[{"content":" Module 1: Course Lessons\nThis course is about learning how mobile applications are built in Codename One without treating the framework as magic. The goal is not just to get an app on screen. It is to understand what mobile development asks of you, how Codename One fits into that world, and how to build habits that will still make sense once the project grows beyond a toy example.\nIf you are starting fresh today, the right place to begin is with the current Maven-based workflow. Create projects with Initializr, open them in the IDE you already use, and rely on the generated project structure instead of the legacy plugin-based setup shown in some of the older course material. That modern setup is simpler, easier to version, and much closer to the way current Codename One projects are maintained.\nThe early lessons in this course focus on the fundamentals that keep coming back throughout real projects: how mobile devices differ from desktop environments, how a Codename One application is structured, how layouts and styling work, why the event dispatch thread matters, and how device builds fit into the development loop. Those are the things that make the rest of the framework easier to understand.\nYou should expect some of the videos in this course to show older tooling. When that happens, use the written lesson as the current source of truth. The important concepts are still worth learning, but the practical workflow has evolved. In particular, modern projects usually start with Maven, use CSS as the primary styling workflow, and use l10n property bundles for localization instead of treating the designer and resource editor as the center of the project.\nThe best way to use this course is to keep a project open while you read. Run the simulator often, change one thing at a time, and make sure you understand why the framework behaves the way it does before moving on. That feedback loop is what turns the lessons into working knowledge.\nFurther Reading Getting Started Initializr Developer Guide Hello World ","permalink":"https://www.codenameone.com/courses/course-01-java-for-mobile-devices/001-introduction/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Course Lessons\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eThis course is about learning how mobile applications are built in Codename One without treating the framework as magic. The goal is not just to get an app on screen. It is to understand what mobile development asks of you, how Codename One fits into that world, and how to build habits that will still make sense once the project grows beyond a toy example.\u003c/p\u003e\n\u003cp\u003eIf you are starting fresh today, the right place to begin is with the current Maven-based workflow. Create projects with \u003ca href=\"/initializr/\"\u003eInitializr\u003c/a\u003e, open them in the IDE you already use, and rely on the generated project structure instead of the legacy plugin-based setup shown in some of the older course material. That modern setup is simpler, easier to version, and much closer to the way current Codename One projects are maintained.\u003c/p\u003e","title":"Introduction"},{"content":" Module 1: Restaurant Server\nThis course starts by bringing the server back into the picture. Earlier material focused heavily on the mobile side, but a real full-stack application only makes sense once the server responsibilities are clear as well.\nThe good news is that most of the server code in this module is deliberately boring, and that is exactly what you want. A good backend is not usually interesting because of flashy implementation tricks. It is useful because it behaves predictably, enforces the rules the client should not be trusted to enforce, and keeps the application state coherent.\nThe lesson uses a Spring Boot backend again, which is still a sensible choice for this kind of Java-based full-stack application. The exact IDE screenshots are older, but the architectural point remains current: the mobile app and the server are two parts of one system, and the server is where pricing, authorization, versioning, and multi-tenant concerns need to be treated seriously.\nOne of the most important examples in the lesson is the pricing discussion around Braintree. If the client submits prices and the server trusts them, the system is already too weak. Even if no one is attacking it actively, stale client data and altered requests can still produce wrong results. The server should recalculate authoritative values from trusted identifiers and server-side state. That single design habit prevents an entire class of problems.\nThe same principle shows up in entity design. IDs, DAO objects, and transport representations may look repetitive, but they serve different purposes. The entity models storage. The DAO or DTO models communication. Keeping those roles distinct gives the backend room to evolve without exposing internal persistence choices directly to the client.\nSo the first server lesson is really about responsibility boundaries. The mobile app owns experience and interaction. The server owns authority, validation, and cross-client consistency. Once that boundary is clear, the rest of the full-stack application becomes much easier to reason about.\nFurther Reading Introduction to Spring Boot Connecting to a Web Service Security Basics and Certificate Pinning ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/001-server/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Restaurant Server\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/exL7bS0StP4?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThis course starts by bringing the server back into the picture. Earlier material focused heavily on the mobile side, but a real full-stack application only makes sense once the server responsibilities are clear as well.\u003c/p\u003e\n\u003cp\u003eThe good news is that most of the server code in this module is deliberately boring, and that is exactly what you want. A good backend is not usually interesting because of flashy implementation tricks. It is useful because it behaves predictably, enforces the rules the client should not be trusted to enforce, and keeps the application state coherent.\u003c/p\u003e","title":"Server"},{"content":" Module 1: Working with CSS\nThis lesson explains how CSS fits into a modern Codename One project and how it should be used in day-to-day styling work.\nFor most new Codename One projects, CSS is the first place to reach when you want to style the UI. It is the most practical way to control colors, borders, fonts, spacing, and component states without pushing visual concerns into Java code. The video introduces CSS as an optional plugin, but that part is out of date now. In current Codename One development, CSS is a normal part of the workflow rather than something experimental.\nThat does not mean CSS replaces the Codename One theme system entirely. It means CSS is now the most practical way to drive that system. UIIDs still matter. Theme values still matter. The difference is that instead of editing everything through the older designer workflow, you usually define and evolve those visual decisions in CSS and let the build process generate the underlying resources as needed.\nThis is also why Codename One CSS feels familiar without being identical to browser CSS. Selectors, colors, borders, and states look recognizable, which is useful, but the framework has its own custom properties and behavior. You are styling Codename One components, not HTML elements. So it is better to think of CSS here as a clean styling language for Codename One rather than expecting arbitrary snippets from the web to drop in unchanged.\nThe easiest way to learn this is to style one simple component first. Take a button, give it a UIID, define its appearance in CSS, and rerun the application. That small loop teaches the core idea quickly: you describe the look once, and Codename One applies it consistently across the relevant states instead of forcing you to rebuild that appearance in Java code.\nA Codename One CSS file works with the theme system rather than bypassing it. That is why theme overlays, UIIDs, and precedence still matter. If a base theme defines one thing and your CSS defines another, the later layer wins. Understanding that relationship makes it much easier to predict why a style is or is not being applied.\nAnother place where the video is dated is the role of the designer and resource editor. They were much more central to styling workflows at the time. That is no longer the best default. CSS should be the main styling layer in a new project, and localization should usually live in l10n property bundles rather than the older designer-driven localization flow.\nIn practice, the healthiest split is simple. Use layouts and component structure to define how the UI behaves. Use CSS to define how it looks. Use resource files only where they still make sense for assets that genuinely belong there. That separation keeps screens easier to evolve and makes style changes far less invasive than they were in older projects.\nOnce you approach the topic that way, the rest falls into place. Layouts define structure. CSS defines appearance. Resource files still have a role for the assets that belong there, but they are no longer where most visual work should begin.\nFurther Reading Themeing Designer Developer Guide Layout Basics Moving To Maven ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/001-working-with-css/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Working with CSS\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eThis lesson explains how CSS fits into a modern Codename One project and how it should be used in day-to-day styling work.\u003c/p\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/UxZ1HeheGwU?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eFor most new Codename One projects, CSS is the first place to reach when you want to style the UI. It is the most practical way to control colors, borders, fonts, spacing, and component states without pushing visual concerns into Java code. The video introduces CSS as an optional plugin, but that part is out of date now. In current Codename One development, CSS is a normal part of the workflow rather than something experimental.\u003c/p\u003e","title":"Working with CSS"},{"content":" Module 1: Course Lessons\nThis lesson shows how to build a small but complete Codename One application: an app that starts cleanly, shows a form, responds to input, and is ready to be sent to a device once the basics are working.\nThe best first project is a very small one. Create a Maven-based Codename One application using the initializr, open it in your IDE, and spend a few minutes understanding the generated app before you start customizing it. The video covers the same first milestone, but this is one place where it is out of date because it starts with the old IDE plugin flow instead of the current Maven-based setup. At this stage you are not trying to design the final architecture of your product. You are trying to learn the basic rhythm of a Codename One app and confirm that your development environment is working.\nOne of the first things worth getting right is the package name. In Codename One it becomes part of the app\u0026rsquo;s identity and eventually touches signing, native packaging, and store submission. Choose a stable reverse-domain package name at the beginning instead of treating it as a temporary placeholder.\nOnce the project is generated, the application class shows you the lifecycle that every Codename One app follows. init() is where one-time application setup belongs. start() is where the first UI is created and shown. stop() is called when the app goes into the background, and destroy() is there for shutdown cleanup when needed. That lifecycle is still the backbone of the framework, and understanding it early saves a lot of confusion later.\nThe actual hello world UI should stay simple. Create a form, add a button, attach an action listener, and show a dialog or some other small response when the user taps it. That single exercise teaches several important things at once. It shows how a form is displayed, how components are added to it, how event listeners are wired, and how the UI responds to interaction. Once that works, you have a real application, even if it is still visually plain.\nRun that first version in the simulator and use it as your main feedback loop. The simulator is still the fastest place to confirm that the lifecycle is behaving correctly and that the UI looks sane across different device skins. Only after that loop feels stable should you send a native build. For most teams Android is the easiest first checkpoint. iOS usually comes later because certificates and provisioning need to be in place before the build becomes useful.\nOnce the app is running, the next step is usually to improve the look and feel. This is one place where the video is out of date. It moves toward the older theme designer and resource-editor workflow. For most current Codename One projects, CSS is the better default for styling and l10n property bundles are the better default for localization. The designer and resource editor still exist, but they are no longer the workflow most new projects should start with.\nBy the time you have a form on screen, a button responding to taps, and a simulator session you can trust, you already have the foundation you need. From there you can style the app with CSS, add localization with property bundles, and start growing the project without having to relearn the basics later.\nFurther Reading Getting Started Hello World Development Environment Build Server Themeing Moving To Maven ","permalink":"https://www.codenameone.com/courses/course-01-java-for-mobile-devices/002-creating-a-hello-world-app/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Course Lessons\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eThis lesson shows how to build a small but complete Codename One application: an app that starts cleanly, shows a form, responds to input, and is ready to be sent to a device once the basics are working.\u003c/p\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/73d65cvyQv4?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe best first project is a very small one. \u003ca href=\"/initializr/\"\u003eCreate a Maven-based Codename One application using the initializr\u003c/a\u003e, open it in your IDE, and spend a few minutes understanding the generated app before you start customizing it. The video covers the same first milestone, but this is one place where it is out of date because it starts with the old IDE plugin flow instead of the current Maven-based setup. At this stage you are not trying to design the final architecture of your product. You are trying to learn the basic rhythm of a Codename One app and confirm that your development environment is working.\u003c/p\u003e","title":"Creating a Hello World App"},{"content":" Module 2: Working with Custom Web Services\nSooner or later most non-trivial mobile apps need a server. That server might store data, authenticate users, send push notifications, validate business rules, or expose an API that several client applications share. In this course module, Spring Boot is used as the server-side counterpart because it is a straightforward way to build a Java backend without drowning in boilerplate.\nSpring Boot works well for this kind of project because it removes a lot of setup friction. Instead of manually assembling an application server, wiring configuration by hand, and spending the first hour fighting infrastructure, you can create a project, add the dependencies you need, and start exposing endpoints quickly. That makes it a good fit for a mobile course where the goal is to understand the client/server relationship, not get lost in container administration.\nThe video introduces Spring Boot through older IDE screenshots, but the important part is not the IDE. The important part is the shape of the backend: a normal Java project, usually built with Maven, with dependencies for web support, data access, and whatever database driver you need. Today you can create that project with Spring Initializr and open it in any mainstream IDE.\nFor the persistence layer, the lesson chooses a relational database and uses JPA-style mapping. That is still a sensible default. Mobile backends often need reliable querying, reporting, and clear data relationships long before they need exotic distributed-database tricks. Starting with a conventional SQL-backed model keeps the application understandable and leaves room to grow later if the problem actually demands something more specialized.\nThat does not mean every Codename One backend must be Spring Boot or even Java. The mobile client can talk to any server that exposes a usable API. But if you already work in Java, Spring Boot remains a practical choice because it keeps the server in the same language ecosystem as the client while still giving you mature tools for HTTP endpoints, data access, and deployment.\nThe key outcome of this lesson is not \u0026ldquo;install Spring Boot.\u0026rdquo; It is understanding that a mobile backend can be treated like a normal application project. It has its own build, its own runtime, its own persistence layer, and its own deployment concerns. Once you see it that way, the client and server stop feeling like two mysterious worlds and start feeling like two parts of the same system.\nFurther Reading Developer Guide How Do I Access Remote Webservices, Perform Operations On The Server Connecting to a Web Service ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/002-introduction-to-spring-boot/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 2: Working with Custom Web Services\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/tugJ_7xMdzs?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eSooner or later most non-trivial mobile apps need a server. That server might store data, authenticate users, send push notifications, validate business rules, or expose an API that several client applications share. In this course module, Spring Boot is used as the server-side counterpart because it is a straightforward way to build a Java backend without drowning in boilerplate.\u003c/p\u003e","title":"Introduction to Spring Boot"},{"content":" Module 2: The App Maker\nThe app maker in this course is a different kind of product from the restaurant app that came before it. The restaurant app had plenty of familiar reference points. The app maker does not. That means the design process has to start from structure and purpose rather than from an existing polished mockup.\nThis lesson handles that correctly by starting with scope. Before trying to make the app beautiful, it asks what information the product must collect, what parts should be editable immediately, and what kind of first impression the user should get. That is the right order. A screen can be refined later. A confused product scope is harder to recover from.\nThe first design attempt in the video is intentionally useful because it fails in an informative way. A tabbed, detail-heavy form may make sense to a developer looking at the data model, but it is not a good first impression for a user who wants to understand the product quickly. That is an important design instinct to build: the right interface is not necessarily the one that mirrors the underlying data most directly.\nThe improved direction shifts the focus to preview and momentum. The user sees something that already resembles a customizable app, not just a pile of settings. That is a stronger product choice because it lets people feel progress before they have finished entering every detail. A preview-first workflow is often the right answer in builder-style products for exactly that reason.\nThis lesson is also a reminder that defaults are part of design. If the app opens in a half-empty, awkward state, it does not matter that the user could eventually make it look good. Good defaults reduce the amount of work required before the product feels alive.\nSo the real takeaway here is not just one UI sketch over another. It is the idea that scope, first impression, and editability should drive the product shape from the beginning, especially when you do not have a designer handing you a finished visual system.\nFurther Reading Fleshing Out the UI Design Adapting a UI Design Themeing ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/002-scope-and-basic-ui-design/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 2: The App Maker\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/tiY5ofnJop8?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe app maker in this course is a different kind of product from the restaurant app that came before it. The restaurant app had plenty of familiar reference points. The app maker does not. That means the design process has to start from structure and purpose rather than from an existing polished mockup.\u003c/p\u003e","title":"Scope and Basic UI Design"},{"content":" Module 2: Working with Custom Web Services\nOnce a backend exists, the mobile app needs a clean way to talk to it. In practice that usually means sending HTTP requests, receiving JSON responses, and converting those responses into application objects that the UI can work with. That process is simple in concept, but it becomes messy fast if networking code leaks everywhere.\nThe first thing worth doing is separating transport code from UI code. A form should not be responsible for knowing how to build URLs, set headers, serialize request bodies, and parse raw JSON. Put that logic in a small service layer instead. Then the rest of the app can ask for higher-level operations such as \u0026ldquo;add item\u0026rdquo;, \u0026ldquo;load items\u0026rdquo;, or \u0026ldquo;log in\u0026rdquo; instead of dealing with low-level request mechanics every time.\nThe video builds requests directly with ConnectionRequest, serializes JSON explicitly, and parses responses back into model objects. That is still a valid way to understand what is happening on the wire, and it is a good lesson because it keeps the protocol visible. Even if you later wrap the code in helper utilities or higher-level abstractions, you still need to understand the basics: HTTP method, URL, headers, body, response status, and JSON parsing.\nOne of the most important design choices here is whether a call should be treated synchronously or asynchronously. Synchronous code can be easier to read because it flows top to bottom, but it must be used carefully and never in a way that freezes the user interface. Asynchronous code is more flexible and generally safer for long-running work, but it pushes you toward callback or continuation-style logic. There is no single correct answer for every case. What matters is knowing which model you are using and keeping UI responsiveness intact.\nFor most applications, the practical structure is this: define a model object that matches the data you exchange with the server, define a client-side service class that knows how to talk to the backend, and keep the UI layer focused on displaying results and collecting user input. That separation pays off quickly once the project grows beyond one or two endpoints.\nThis lesson also highlights a broader truth about mobile networking: the app is always dealing with a hostile environment. Networks fail, servers return unexpected responses, and payloads change over time. Good client code assumes that requests can fail and that parsing may not always go the happy-path way. Even a simple demo service is worth writing as though it were real.\nFurther Reading Developer Guide How Do I Access Remote Webservices, Perform Operations On The Server How Do I Use HTTP, Sockets, Webservices \u0026amp; Websockets Threading and the EDT ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/003-connecting-to-a-web-service/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 2: Working with Custom Web Services\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/3B7C0ZbV8Bc?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce a backend exists, the mobile app needs a clean way to talk to it. In practice that usually means sending HTTP requests, receiving JSON responses, and converting those responses into application objects that the UI can work with. That process is simple in concept, but it becomes messy fast if networking code leaks everywhere.\u003c/p\u003e","title":"Connecting to a Web Service"},{"content":" Module 1: Course Lessons\nMobile development feels different from desktop development because the constraints are different. Screens vary wildly in size and density, memory is tighter, interaction is touch-first, and native platforms impose rules around packaging, signing, and distribution. If those constraints feel annoying at first, that is normal. The key is to design with them instead of fighting them.\nThe first concept to get comfortable with is the difference between resolution and density. Resolution tells you how many pixels are on a screen. Density tells you how tightly packed those pixels are. Two devices can have similar resolutions and still look very different because one has far more pixels per inch. That is why a UI that seems fine on one device can suddenly look too small, blurry, or badly balanced on another. In Codename One, this is one of the reasons layouts matter so much. Hard-coded sizes age badly across real devices.\nImages are where density becomes expensive. If you ship only one low-resolution asset, it will look soft or pixelated on modern devices. If you ship only very large assets, the app pays in download size and memory use. The practical answer is to be selective. Use vector-friendly approaches where you can, especially for icons, and use raster images only where they genuinely add value. Codename One\u0026rsquo;s multi-image support exists to help match assets to device density, but that should not become an excuse to dump huge image libraries into the app.\nFor icons and simple symbolic graphics, built-in material icons and font-based icons are often the better choice. They scale cleanly, work well with theme colors, and avoid the asset explosion that comes from exporting multiple bitmap versions of the same shape. For photos and more detailed artwork, regular image assets still make sense, but you should think carefully about where the sharpest version is really needed.\nAnother mobile concept that surprises people is that shipping an app is not just a matter of compiling code. Native platforms require signing and, in some cases, provisioning. On Android, signing establishes the identity of the app and controls who can publish updates to it. On iOS, certificates and provisioning profiles are part of both development and distribution. That complexity is not specific to Codename One. It is part of mobile development itself, and understanding it early makes later build and release work much less mysterious.\nThe video spends a fair amount of time on signing and provisioning, and that material is still relevant. What has changed is the workflow around the project. Today you will usually create a Maven project first and then send builds through the current Codename One tooling. But the native platform rules have not gone away. If anything, they are the reason Codename One\u0026rsquo;s build tooling is valuable in the first place.\nThe broader lesson is that mobile work rewards adaptability. You do not control the screen, the density, the store requirements, the operating system policies, or the amount of memory on the user\u0026rsquo;s device. A good mobile framework helps you live with those constraints. A good mobile developer learns to expect them.\nFurther Reading Developer Guide Build Server How Do I Fetch An Image From The Resource File, Add A Multiimage How Do I Create A 9 Piece Image Border How Do I Create An iOS Provisioning Profile ","permalink":"https://www.codenameone.com/courses/course-01-java-for-mobile-devices/003-core-concepts-of-mobile-development/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Course Lessons\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/hwsWdhJHl8Q?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eMobile development feels different from desktop development because the constraints are different. Screens vary wildly in size and density, memory is tighter, interaction is touch-first, and native platforms impose rules around packaging, signing, and distribution. If those constraints feel annoying at first, that is normal. The key is to design with them instead of fighting them.\u003c/p\u003e","title":"Core Concepts of Mobile Development"},{"content":" Module 2: The App Maker\nOnce the high-level direction is clear, the next step is to turn that direction into actual screens and decide which ones belong in the first version. This is where many projects start drifting, because every missing form suddenly feels important.\nThe strongest part of this lesson is its willingness to separate essential flows from tempting extras. Billing, details, styling, address entry, and media selection all matter, but they do not all need to be built at once in full generality. The act of choosing what to postpone is part of the design work, not an admission of failure.\nThe lesson\u0026rsquo;s styling and customization ideas are also useful because they think in terms of targeted editing rather than giant monolithic settings screens. If a user can tap an area and customize the relevant background, color, icon, or font in context, the builder becomes much easier to understand. That is generally more approachable than making the user translate abstract configuration names into visual outcomes.\nAt the same time, this lesson keeps the product grounded by acknowledging that some features should stay simpler for now. That restraint is important. A builder product can easily become unusable if every form tries to expose every possible option immediately.\nThe implementation-plan discussion at the end is also worth carrying forward. A depth-first approach makes sense here because it validates the product loop early. Instead of building a thin layer of every feature, it gets one narrow slice working end to end so the design, data model, and code-generation assumptions can be tested against reality.\nSo the broader lesson is this: fleshing out the UI is not only about drawing more screens. It is about deciding which screens matter now, which editing interactions are intuitive, and how to sequence the work so the product can be validated before the whole plan gets too large.\nFurther Reading Scope and Basic UI Design Architecture of Mockup How Do I Use Properties To Speed Development ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/003-fleshing-out-the-ui-design/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 2: The App Maker\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/IxVUX0s2Nms?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the high-level direction is clear, the next step is to turn that direction into actual screens and decide which ones belong in the first version. This is where many projects start drifting, because every missing form suddenly feels important.\u003c/p\u003e","title":"Fleshing Out the UI Design"},{"content":" Module 3: Initial UI Mockup\nOnce the product direction is stable enough, the next question is architectural: what parts of the UI are common, and what parts belong to individual screens? This lesson starts answering that by defining the form hierarchy for the initial app-maker mockup.\nThat hierarchy matters because the app maker already has a recognizable shell: a navigation structure, shared editing affordances, and a preview-oriented top-level experience. If every screen were built independently, that shell would quickly drift. A shared base form is the right tool for keeping navigation and common editing patterns consistent.\nThe lesson also makes a pragmatic point about reuse that is easy to miss. Copying an existing model or structure is often the right first move if it gets you to a working baseline quickly. Generalization should come from repeated need, not from the fear of duplication on day one. That is especially true in builder-style products where the real shape of the domain is still being discovered.\nThe result is a simple but useful structure: one shared navigation-oriented base, a small number of top-level forms that inherit from it, and one-off forms like dish editing that are allowed to stand on their own because their responsibilities are different. That split keeps the code honest about which UI concerns are shared and which are truly local.\nSo the architectural lesson here is not complicated, but it is important. Establish a common shell for the parts of the product that behave alike, and do not force unrelated screens into that same abstraction just to look tidy.\nFurther Reading Base Navigation Form and Shape Effects Developer Guide Layout Basics ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/004-architecture-of-mockup/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 3: Initial UI Mockup\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/vxsUf3gw1zg?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the product direction is stable enough, the next question is architectural: what parts of the UI are common, and what parts belong to individual screens? This lesson starts answering that by defining the form hierarchy for the initial app-maker mockup.\u003c/p\u003e","title":"Architecture of Mockup"},{"content":" Module 3: Extracting a UI Design\nThis module is about the gap between a static design and a real application screen. A mockup can show you the look of the product, but it does not tell you which parts should become live UI, which parts should remain image assets, which elements need to stretch, and which details are safe to simplify.\nThe example in the video starts from a Photoshop design and turns it into a Codename One mockup. The same exercise still matters today, but the tools around it have changed. Many teams now start from Figma or similar design tools rather than PSD files, and the implementation should usually lean on CSS for styling instead of older theme-designer workflows. The core skill, though, has not changed at all: learn to read a design structurally instead of treating it like a screenshot you have to reproduce pixel by pixel.\nWhen you look at a design, start by asking what is truly interactive. Buttons, search fields, lists, toolbars, filters, and cards usually want to be real components. Photos, illustrations, and a few special decorative details may need to stay as assets. Once you separate those two categories, the rest of the implementation becomes far more manageable.\nThe other important idea in this module is that a good adaptation does not have to be a perfect clone. Mobile UIs live on different devices, densities, and font renderers. It is often better to preserve the visual hierarchy, spacing, and behavior of the design than to overfit to one mockup and end up with something brittle. Material icons, reusable borders, and framework-native layout behavior often produce a better result than trying to freeze every pixel exactly as it appeared in the design file.\nIn the lessons that follow, the design gets broken down into manageable parts: assets that need to be extracted, layout decisions, CSS styling, and the component structure that makes the screen behave like a real application. That is the right mindset for design implementation in Codename One. Start with structure, then layer styling and assets on top.\nFurther Reading Developer Guide Themeing Layout Basics How Do I Create A 9 Piece Image Border ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/004-introduction/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 3: Extracting a UI Design\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/BXwh2T7wvfc?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThis module is about the gap between a static design and a real application screen. A mockup can show you the look of the product, but it does not tell you which parts should become live UI, which parts should remain image assets, which elements need to stretch, and which details are safe to simplify.\u003c/p\u003e","title":"Introduction"},{"content":" Module 1: Course Lessons\nThe shortest description of Codename One is that it lets you build cross-platform applications in Java. The longer and more useful answer is that Codename One is a combination of framework APIs, platform ports, build tooling, and a development workflow that turns one codebase into applications that run on multiple targets.\nThat combination matters because Codename One is not just a widget library. It provides a portable UI toolkit, portable device APIs, a simulator, native build infrastructure, and the glue that keeps those parts working together. When you create a project, write Java code, run it in the simulator, and later send a native build, you are using several layers of the system at once even if you do not think about them separately.\nAt the application level, you mostly work with the public Codename One API. That is the part that gives you forms, layouts, networking, storage, media, and the rest of the framework surface. Underneath that is a porting layer that maps the framework behavior onto each platform. That is one of the reasons Codename One can behave consistently across platforms while still producing native builds.\nThe video goes into the history from LWUIT through the early Codename One years, and that background helps explain some design decisions that are still visible in the framework. It also spends time on the old IDE plugin flow and older toolchain assumptions. That part is out of date. Today the practical entry point is a Maven-based project created with Initializr, not a legacy IDE plugin wizard. The underlying idea is the same, though: the tooling exists to assemble the framework, your application code, and the native build pipeline into one working system.\nAnother important part of the Codename One model is that the framework is versioned with the application. That means the app you ship carries the framework code it was built with. In practice this gives shipped apps stability and lets you choose when to adopt framework changes. It also makes versioned builds and controlled upgrades much more practical than they would be if every running app depended on one mutable shared runtime.\nCodename One also makes a deliberate trade-off in its UI architecture. It uses a lightweight component model so the framework can keep behavior more consistent across targets and so the simulator can behave meaningfully. That design choice is a big part of why the same application logic can run across the supported targets without being rewritten for each platform.\nIf you are trying to decide whether Codename One is \u0026ldquo;just Java for mobile\u0026rdquo;, the answer is no. It is a full cross-platform application stack with Java at the center. The more accurate way to think about it is this: Codename One gives you one framework, one language, and one application model, then handles the platform-specific work needed to turn that into real applications.\nFurther Reading Developer Guide Getting Started Build Server Moving To Maven ","permalink":"https://www.codenameone.com/courses/course-01-java-for-mobile-devices/004-what-is-codename-one/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Course Lessons\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/XSztvFzQAr0?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe shortest description of Codename One is that it lets you build cross-platform applications in Java. The longer and more useful answer is that Codename One is a combination of framework APIs, platform ports, build tooling, and a development workflow that turns one codebase into applications that run on multiple targets.\u003c/p\u003e","title":"What is Codename One"},{"content":" Module 1: Course Lessons\nEvery framework has a moment where the generated project stops feeling friendly and starts feeling like a pile of mysterious files. This lesson is about getting past that point. A Codename One project is much easier to work with once you know which files define the application, which files are generated, and which parts are just build output that you can ignore.\nThe video walks through the old IDE-plugin project layout and spends a lot of time on build.xml, lib, and other files that were central to the older Ant-based workflow. That part is out of date for new projects. Today you will usually start from a Maven project, so the file and directory structure looks different. Even so, the important ideas from the lesson still translate well: some files define the app, some define the build, some are caches or artifacts, and some exist only to support a specific toolchain.\nIn a modern Codename One project, the first files worth understanding are the Maven build files and the application source itself. The Java application class still expresses the lifecycle of the app. Resource directories still contain the assets and configuration the app depends on. Build-related files still describe how the project is packaged and how platform-specific work is triggered. The main difference is that Maven now owns the overall build structure instead of the old plugin-generated Ant layout.\nOne file that remains conceptually important is codenameone_settings.properties. It still acts as the central configuration point for many application-specific settings, including identifiers, build hints, and platform-specific options. You do not need to hand-edit it for everything, and in many cases it is better to use the supported tooling, but you do need to know it exists and what role it plays. When something about the application\u0026rsquo;s identity or native configuration changes, this file is often involved.\nBuild output should be treated as disposable. Whether it is a Maven target directory or older build and dist folders from the plugin era, generated artifacts are there to support a build or a simulator run. They are useful for debugging packaging problems, checking what assets ended up in the final jar, or understanding why an application became unexpectedly large, but they are not the place to make source-level changes.\nThat distinction becomes especially important when you start troubleshooting. If the final package is too large, inspect the generated artifact and see what actually got bundled. If a build behaves differently from what you expect, check whether the configuration lives in source files, properties, or generated output. A lot of confusion disappears once you stop treating every file in the project tree as equally important.\nSo the real anatomy of a Codename One application is simpler than it first appears. There is the app code you write, the project configuration that describes how it should be built, the assets it depends on, and the generated output produced along the way. Learn those boundaries early and the rest of the project becomes much easier to reason about.\nFurther Reading Developer Guide Getting Started Build Server Hello World How Do I Get Repeatable Builds, Build Against A Consistent Version Of Codename One \u0026amp; Use The Versioning Feature ","permalink":"https://www.codenameone.com/courses/course-01-java-for-mobile-devices/005-anatomy-of-a-codename-one-application/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Course Lessons\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/8fxZVc1hw6Q?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eEvery framework has a moment where the generated project stops feeling friendly and starts feeling like a pile of mysterious files. This lesson is about getting past that point. A Codename One project is much easier to work with once you know which files define the application, which files are generated, and which parts are just build output that you can ignore.\u003c/p\u003e","title":"Anatomy of a Codename One Application"},{"content":" Module 3: Initial UI Mockup\nThis lesson is where the app-maker mockup starts becoming visually specific. The shared navigation shell is not just a place to hang menus. It is also where the product gets much of its identity: editable title areas, branded imagery, and the small visual treatments that make the preview feel like an actual product instead of a form editor.\nOne of the strongest ideas here is the use of editable text fields styled to feel like normal title elements. That approach matches the product well. The app maker is about live customization, so turning parts of the preview itself into editable elements makes the interface more direct and more understandable.\nThe rounded-logo discussion is also useful because it shows how shape work should be approached in Codename One. The important point is not the specific masking trick alone. It is the broader principle that visual effects need to be implemented in a way that stays portable and predictable across platforms. A trick that looks elegant but behaves differently from target to target is not actually helping the design.\nThis lesson predates the stronger CSS-first emphasis that now makes sense for most styling work, but the underlying visual decisions still hold up. Use CSS and current theming practices for the bulk of the style system, and reserve lower-level image or mask work for the cases where the design truly needs it, such as logo shaping or image treatment that cannot be expressed cleanly through normal styling.\nSo the navigation form in this lesson is important for two reasons. It gives the app maker a consistent structural shell, and it establishes the visual language that later editable screens will build on top of.\nFurther Reading Themeing Working With CSS Architecture of Mockup ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/005-base-navigation-form-and-shape-effects/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 3: Initial UI Mockup\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/xzwq4P9ogoU?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThis lesson is where the app-maker mockup starts becoming visually specific. The shared navigation shell is not just a place to hang menus. It is also where the product gets much of its identity: editable title areas, branded imagery, and the small visual treatments that make the preview feel like an actual product instead of a form editor.\u003c/p\u003e","title":"Base Navigation Form and Shape Effects"},{"content":" Module 3: Extracting a UI Design\nWhen you receive a design file, the goal is not to export everything. The goal is to extract only the assets that should really remain images in the final application. That sounds obvious, but it is one of the easiest mistakes to make when turning a design into code. If you export too much, you end up with a UI that is heavy, rigid, and difficult to adapt.\nThe video demonstrates this using Photoshop, and the basic workflow still holds up: isolate the part you need, remove anything that should remain live UI, and export only the visual element that actually belongs in an asset file. Today you might do the same work in Figma, Sketch, or another design tool, but the decision-making process is the same.\nBackground photos are a good example. If the image is purely decorative and really is a photo, then exporting it as an image makes sense. A JPEG is often appropriate there because file size matters and you do not need transparency. On the other hand, if a visual element needs transparency, sharp edges, or mask-style behavior, a PNG is often the better choice.\nRounded cards, masks, and border fragments should be handled with even more care. Sometimes a cropped image is the right answer. Sometimes a nine-piece border is the right answer. Sometimes the best answer is not an image at all because CSS, borders, padding, and standard components can express the same effect more cleanly. The lesson is useful because it forces you to ask that question for each element instead of exporting blindly.\nThis is also where asset discipline starts paying off. Remove text from exported buttons if the label should remain live and localizable. Keep decorative images separate from content images. Export the smallest useful region instead of the whole screen. Those choices make the final app easier to style, localize, and maintain.\nSo while the tooling in the video is older and Photoshop-specific, the principle is current: treat image extraction as selective engineering work, not as screenshot slicing. Every asset you keep should earn its place.\nFurther Reading Themeing How Do I Create A 9 Piece Image Border How Do I Fetch An Image From The Resource File, Add A Multiimage Adapting a UI Design ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/005-cutting-images-in-photoshop/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 3: Extracting a UI Design\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/exQ8xXAxtoU?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eWhen you receive a design file, the goal is not to export everything. The goal is to extract only the assets that should really remain images in the final application. That sounds obvious, but it is one of the easiest mistakes to make when turning a design into code. If you export too much, you end up with a UI that is heavy, rigid, and difficult to adapt.\u003c/p\u003e","title":"Cutting Images in Photoshop"},{"content":" Module 3: Extracting a UI Design\nOnce the structure of a screen is in place, CSS is usually the fastest way to make it look intentional. That is the modern styling path for most Codename One projects. It lets you work at the right level of abstraction: UIIDs, spacing, colors, borders, backgrounds, and state-specific styling, without turning every visual adjustment into Java code.\nThis lesson is really about taking a mockup and giving each part of the screen a styling identity. A form gets its base background. A title area gets transparency and alignment rules. Cards, buttons, filters, and checkout elements each get their own UIID so they can be styled consistently. Once those UIIDs exist, CSS becomes the place where the visual system lives.\nThe older video mixes CSS with some manual theme-designer work, especially for a few border assets. That was understandable at the time, but the default recommendation today is simpler: stay in CSS unless you have a strong reason to drop lower. The old designer still works, but it is no longer the center of the workflow for new projects.\nGood Codename One CSS starts with a few basic habits. Containers and labels often need their transparency, margin, and padding made explicit so the design behaves consistently across themes. Toolbar-related UIIDs often need cleanup because native themes can contribute defaults you do not want. State-specific styling needs to be defined intentionally so the selected or pressed state feels like part of the same design rather than an afterthought.\nSpacing is one of the biggest reasons CSS matters. Padding defines breathing room inside a component. Margin defines its relationship to neighboring components. If a screen feels cramped or oddly balanced, the fix is often there rather than in color or typography. That is also why a visually simple design can still take real work to reproduce well: the small spacing choices are doing a lot of the design work.\nInheritance is another important part of maintainable styling. If one button style is really a variation of another, define the common look once and override only the differences. The same idea applies to cards, list entries, and reusable decorative treatments. A style system should reduce repetition, not create it.\nSo the practical workflow is straightforward. Build the screen structure in Java, give the important elements stable UIIDs, and then use CSS to express the design. Reserve lower-level theme tooling for the rare cases where CSS is not the right fit. That keeps the application easier to read, easier to evolve, and much closer to the way modern Codename One projects are styled.\nFurther Reading Themeing Developer Guide Working With CSS How Do I Create A Simple Theme ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/006-css/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 3: Extracting a UI Design\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/-f1yue3hDEk?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the structure of a screen is in place, CSS is usually the fastest way to make it look intentional. That is the modern styling path for most Codename One projects. It lets you work at the right level of abstraction: UIIDs, spacing, colors, borders, backgrounds, and state-specific styling, without turning every visual adjustment into Java code.\u003c/p\u003e","title":"CSS"},{"content":" Module 3: Initial UI Mockup\nThe dish list is where the app maker stops feeling like a shell and starts feeling like a real editor. The user is no longer just changing a title or background. They are managing a collection of product content that will define the generated app.\nThe most important decision in this lesson is the editing flow. Instead of presenting a separate “create dish” ceremony and then making the user confirm every step, the app immediately creates an entry and opens it for editing. That is a very mobile-friendly choice. It keeps momentum high and avoids forcing a cumbersome OK/cancel workflow where deletion is often the simpler and clearer form of undo.\nThe grid-based presentation is also a good product choice because dishes are fundamentally visual. People think about menu items through images and headlines, not just through rows of text. The list screen should therefore behave more like a content board than a data table.\nOn the editing side, the lesson continues the preview-first design language established earlier. The title is editable in place, the image remains a dominant part of the form, and the editing controls are arranged to support that rather than overwhelm it. The floating action button placement, background treatment, and bottom-positioned delete action all serve that same goal: keep the main content visible while still making the editing affordances clear.\nThis is also a good example of where layout choices matter more than decorative polish. Wrapping controls correctly, avoiding awkward line breaks in editable title areas, and positioning actions relative to the title region are what make the form feel intentional. Once the structure is right, the styling has something solid to work with.\nSo this lesson is really the first end-to-end content-management interaction in the app maker. It shows how to let users create, inspect, and refine one of the core artifacts of the generated app without turning the editing experience into a wall of forms.\nFurther Reading Base Navigation Form and Shape Effects How Do I Create A List Of Items The Easy Way Layout Basics ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/006-dish-list-and-edit/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 3: Initial UI Mockup\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/yv3WXt8o88k?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe dish list is where the app maker stops feeling like a shell and starts feeling like a real editor. The user is no longer just changing a title or background. They are managing a collection of product content that will define the generated app.\u003c/p\u003e","title":"Dish List and Edit"},{"content":" Module 1: Course Lessons\nInternationalization and localization are broader than translation. Internationalization means structuring the app so it can adapt to different locales. Localization is the work of adapting the app to a specific locale. Language is part of that, but so are dates, numbers, currency, right-to-left behavior, phrasing, and the cultural meaning of visual choices.\nThe first practical rule is to stop hard-coding user-facing text directly into the UI wherever possible. Codename One is designed to work with key/value bundles so that the text shown to the user can change with the current locale. The older video demonstrates this through the resource editor. For new projects, the better default is l10n property bundles, but the core idea remains the same: components should reference localizable keys, not baked-in strings that force you to revisit the code for every translation.\nThis matters because translation is only the first layer. Locale-specific behavior also affects the way you display dates, numbers, and currency. If you use locale-aware formatting utilities, the app can present those values in a way that feels natural to the user instead of forcing one fixed representation on every market. In Codename One, L10NManager and the framework\u0026rsquo;s localization utilities are the right place to start for this kind of formatting.\nTesting localization also needs to be part of the normal development loop. It is much easier to catch problems early if you force the simulator into a different language and inspect the UI there. A localized build should not only show translated strings. It should still fit properly, align correctly, and feel intentional when labels grow longer or date and number formatting changes.\nRight-to-left support is one of the most important areas to get right. Languages such as Hebrew and Arabic do not just translate the text. They change the expected flow of the interface. Text aligns differently, component order often reverses, and icons or directional affordances may need to be mirrored. Codename One helps a lot here because layouts react to RTL mode by flipping positions and alignment where appropriate. A BorderLayout.EAST relationship, for example, is interpreted relative to the active writing direction.\nThat said, RTL is not automatic magic. Mixed-direction content still needs attention. Numbers are still read left-to-right even inside right-to-left languages, so bidirectional text can produce cursor movement and layout behavior that surprises developers who only test in English. Icons such as play arrows, chevrons, and back buttons also need review because a mirrored UI with unmirrored directional icons still feels wrong.\nThe video uses the older designer workflow to define bundles and RTL markers. That part is outdated for new projects, but the localization concepts themselves are still the right ones to learn. In current Codename One development, the better default is property-bundle based localization plus locale-aware formatting in code, with the layout system doing most of the heavy lifting for RTL-aware component ordering.\nFurther Reading Developer Guide Themeing Layout Basics Properties Are Amazing ","permalink":"https://www.codenameone.com/courses/course-01-java-for-mobile-devices/006-internationalization-and-localization/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Course Lessons\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/32mkZymqa6E?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eInternationalization and localization are broader than translation. Internationalization means structuring the app so it can adapt to different locales. Localization is the work of adapting the app to a specific locale. Language is part of that, but so are dates, numbers, currency, right-to-left behavior, phrasing, and the cultural meaning of visual choices.\u003c/p\u003e","title":"Internationalization and Localization"},{"content":" Module 3: Extracting a UI Design\nOnce several screens share the same visual shell, the cleanest approach is usually to build that shell once and let individual forms supply their own content. That is what a BaseForm is doing in this lesson. It is not there to be clever. It is there to stop layout duplication from spreading through the app.\nIn this design, the shared shell includes the top area, toolbar behavior, background treatment, and the general structure that all of the screens inherit. If every form rebuilt those pieces independently, the design would drift and small visual fixes would become repetitive. A base form keeps those common decisions in one place.\nThe video uses a layered toolbar and a filler component to keep content from sliding underneath the title area. That underlying problem is still real even if your exact implementation differs. Any time you have a floating or layered top section, you need to think about how the content below it is offset. The detail may look minor, but it is exactly the sort of thing that makes a polished design feel intentional instead of improvised.\nThis lesson also shows a good example of separating what is common from what is form-specific. The reusable frame belongs in the base class. The actual list of categories, the content body, and any screen-specific widgets belong in the subclasses. That split makes the UI easier to reason about because the shared layout logic stops competing with the details of one particular screen.\nOne subtle but important theme here is that design implementation often depends on small framework behaviors. Empty labels, transparent containers, layered panes, and size calculations all affect the final result. Those details may feel unimportant when reading code, but they are often what turns \u0026ldquo;almost right\u0026rdquo; into \u0026ldquo;actually right.\u0026rdquo;\nSo the practical lesson is simple: if several screens share the same top bar, background treatment, toolbar setup, or framing logic, pull that into a reusable base form. Then let each screen add only the content that is unique to it. Reuse is not just a code quality issue here. It is also a design consistency tool.\nFurther Reading Developer Guide Layout Basics Adapting a UI Design CSS ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/007-baseform/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 3: Extracting a UI Design\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/aNFKBDeky2s?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce several screens share the same visual shell, the cleanest approach is usually to build that shell once and let individual forms supply their own content. That is what a \u003ccode\u003eBaseForm\u003c/code\u003e is doing in this lesson. It is not there to be clever. It is there to stop layout duplication from spreading through the app.\u003c/p\u003e","title":"BaseForm"},{"content":" Module 4: App Maker Server\nUp to this point the app maker has mostly been a client-side mockup and workflow exercise. This module turns it into a real system by deciding how it talks to the server and how the server decides who is allowed to change what.\nThe first architectural choice is pragmatic and sensible: reuse the restaurant server instead of inventing a second independent backend immediately. That may not be the forever architecture, but it is the right depth-first move because it lets the product validate its end-to-end flow before spending time on system separation that may not yet be justified.\nAuthorization is the central problem here. Public restaurant data can be fetched by ordinary identifiers, but editable restaurant state needs a different trust boundary. The lesson solves that by introducing a secret key used only for write operations. That is a strong fit for this kind of product because it avoids the ceremony of a full user-password system while still creating a private capability that the public app should never expose.\nThis is a good example of designing security around the actual product, not around abstract purity. The restaurant app and the app maker do not need identical access models. One is a public consumer-facing app. The other is an editing tool. They should not be using the same credential path just because they operate on the same data.\nThe lesson also hints at an important full-stack pattern: some operations are naturally asynchronous. A build request, for example, may take long enough that the server should queue the work and report the result later rather than pretending it is an ordinary fast request. That is the right instinct, because builder-style products often have a split between quick CRUD operations and longer-running generation tasks.\nSo the broader takeaway is that once the app maker becomes real, the server is no longer just a storage endpoint. It becomes the place where editing authority, asynchronous work, and product boundaries are defined.\nFurther Reading Server REST API Design Security Basics and Certificate Pinning ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/007-introduction-architecture-and-authorization/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 4: App Maker Server\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/FcHVK9ObONg?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eUp to this point the app maker has mostly been a client-side mockup and workflow exercise. This module turns it into a real system by deciding how it talks to the server and how the server decides who is allowed to change what.\u003c/p\u003e","title":"Introduction, Architecture and Authorization"},{"content":" Module 1: Course Lessons\nLayouts are the reason a Codename One UI can survive different screen sizes, orientations, pixel densities, and languages. Components do not live at fixed coordinates. They live inside Container objects, and those containers use layout managers to decide how much space each child gets and where it should appear.\nThe core problem layouts solve is portability. A button position that looks fine on one phone may be wrong on another. A label that fits in English may overflow in German. A design that works in portrait may fall apart in landscape. Layout managers let you describe intent instead of hard-coding coordinates: this component should stay on the left, this field should take the remaining width, this section should stack vertically, these buttons should all be the same size.\nThat is why the classic “label on the left, field on the right” example is still such a useful starting point. In Codename One you usually express that with a BorderLayout, putting the label in BorderLayout.WEST and the field in BorderLayout.CENTER. The layout then handles the resizing rules for you. The label keeps the width it needs, while the center component expands into the remaining space.\nThe standard layouts each have a natural role. FlowLayout is fine for small inline groups of components, but it is easy to outgrow. BorderLayout is one of the most useful outer layouts because it gives you strong structure: top, bottom, left, right, and a center area that consumes the remaining space. BoxLayout.y() is a great default for stacked content because it reads like the screen itself. GridLayout is useful when you genuinely want equal-sized components. TableLayout is especially helpful for forms and data entry. LayeredLayout is the one to reach for when components need to sit on top of each other.\nOne detail that matters early is constraints. Some layouts need them and some do not. BorderLayout depends on explicit positions such as CENTER and WEST, while BoxLayout generally does not need extra constraints at all. A layout manager is not just “where children go”; it also defines what information you need to provide when you add those children.\nThe most effective way to build a real screen is usually to nest a few simple containers rather than hunting for one magical layout that does everything. A form might use BorderLayout at the top level, a BoxLayout.y() in the content area, and then small BorderLayout or GridLayout sections inside it. Good layout code tends to mirror the visual structure of the screen.\nThe modern adjustment is not in the layout system itself so much as in how you split responsibilities. Layout code should mostly define structure and resizing behavior. CSS should do much more of the styling work: spacing, fonts, colors, borders, and visual states. If you find yourself using extra containers only to fake visual styling, that is often a sign that the visual concern belongs in CSS instead.\nFurther Reading Layout Basics Developer Guide Themeing Getting Started ","permalink":"https://www.codenameone.com/courses/course-01-java-for-mobile-devices/007-layout-basics/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Course Lessons\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/4D_KUa2qv2o?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eLayouts are the reason a Codename One UI can survive different screen sizes, orientations, pixel densities, and languages. Components do not live at fixed coordinates. They live inside \u003ccode\u003eContainer\u003c/code\u003e objects, and those containers use layout managers to decide how much space each child gets and where it should appear.\u003c/p\u003e","title":"Layout Basics"},{"content":" Module 3: Extracting a UI Design\nWith the base form in place, the main menu screen becomes the first real test of the design system. This is where the shared shell has to support actual content: category filters, dish cards, images, buttons, and the spacing that makes the screen feel usable rather than crowded.\nThe category strip at the top is a good example of choosing a component for behavior rather than for visual resemblance alone. It may look like tabs in the mockup, but its job is really closer to filtering. That distinction matters because it affects how users understand the control and how the code should model its state.\nThe dish entries themselves are another good example of layered design work. Each card combines structure, styling, and assets. The title and descriptive text stay live so they can respond to layout, truncation, and localization. The image gets the decorative treatment it needs, including rounded shaping or masking where appropriate. The buttons inherit from the same visual language as the rest of the screen instead of being styled in isolation.\nThis is also where reusable component-building code starts to pay off. If every dish entry is assembled in roughly the same way, that assembly should live in one helper method or one reusable component rather than being repeated inline. The design gets more consistent, and later changes become much cheaper.\nThe video spends time on list behavior, selection state, and masked images. Those details are still the right things to care about because they affect how the UI feels in motion, not just how it looks in a static screenshot. A design adaptation is only successful if the interaction model feels as intentional as the visuals.\nBy the end of this lesson, the main screen should no longer feel like a set of disconnected mockup fragments. It should feel like one coherent form built from reusable patterns: a shared shell, a filter control with clear behavior, and content cards that combine live data with carefully chosen visual treatment.\nFurther Reading Layout Basics CSS How Do I Create A List Of Items The Easy Way How Do I Create Gorgeous SideMenu ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/008-mainmenuform/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 3: Extracting a UI Design\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/WYlM2utu4Ps?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eWith the base form in place, the main menu screen becomes the first real test of the design system. This is where the shared shell has to support actual content: category filters, dish cards, images, buttons, and the spacing that makes the screen feel usable rather than crowded.\u003c/p\u003e","title":"MainMenuForm"},{"content":" Module 4: App Maker Server\nAPI design becomes much easier once you stop asking what would be theoretically elegant and start asking what the client actually needs to do. That is the real value of this lesson.\nThe tempting design for an app maker would be one giant “submit everything and build” request. It sounds simple on paper, but it does not fit the product well. The user is editing incrementally, uploading assets separately, previewing changes, and eventually asking for a build. Those are different operations with different reliability and security concerns, so they should not be collapsed into one oversized endpoint.\nThe lesson\u0026rsquo;s incremental API design is stronger because it matches the workflow. Restaurant updates are separate from dish updates. File upload is separate from structured JSON changes. Build triggering is separate from both of those because it starts a distinct asynchronous process. That separation makes the system easier to reason about, easier to retry, and easier to secure.\nThe file-download discussion is especially valuable because it highlights a type of mistake that often sneaks into “internal” APIs. The moment you expose file retrieval, you are no longer just returning an object from a database. You are handling a path into part of the server\u0026rsquo;s filesystem boundary. That demands validation even if the API feels private or product-specific.\nThis lesson also reinforces a broader design rule: REST is not about worshipping nouns or HTTP verbs in the abstract. It is about shaping the server surface so that the client can perform its real tasks safely and cleanly. When the operations are different, the endpoints should reflect that.\nFurther Reading Introduction, Architecture and Authorization Connecting to a Web Service Communicating from the Client ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/008-rest-api-design/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 4: App Maker Server\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/L7ulPCUxIsw?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eAPI design becomes much easier once you stop asking what would be theoretically elegant and start asking what the client actually needs to do. That is the real value of this lesson.\u003c/p\u003e\n\u003cp\u003eThe tempting design for an app maker would be one giant “submit everything and build” request. It sounds simple on paper, but it does not fit the product well. The user is editing incrementally, uploading assets separately, previewing changes, and eventually asking for a build. Those are different operations with different reliability and security concerns, so they should not be collapsed into one oversized endpoint.\u003c/p\u003e","title":"REST API Design"},{"content":" Module 1: Course Lessons\nStyling in Codename One starts with a simple question: are you trying to change how components look, or are you trying to change how the UI behaves structurally? If the answer is visual styling, the modern default is CSS. The video uses the older designer-centered theme workflow, and that still helps explain the underlying concepts, but for a new project you should usually start with CSS and treat the older theme editor as a lower-level tool rather than the main path.\nThe concepts behind theming are still the same. Components get their appearance from a UIID. A UIID is effectively the name of the style a component uses. If you create a button and give it a custom UIID, that UIID becomes the hook for styling the button consistently. This is true whether the style is defined in CSS or in the older theme resource workflow.\nThe simplest useful example is a custom button. Give it a background color, a foreground color, some padding, and a readable font size. The point is not to make it beautiful on the first pass. The point is to understand which properties actually shape the component. Background and foreground colors control the obvious look, but spacing is just as important. Padding affects the space inside the component and therefore the touchable area. Margin affects the space outside the component and therefore the relationship between neighboring components.\nState-specific styling is one of the first places where theming becomes real. A button usually needs at least an unselected appearance and a pressed or selected appearance. If the normal state has one background and the pressed state has no explicit styling, the result can feel inconsistent or broken. The video demonstrates this with borders and selected styles, and the underlying lesson remains important: style all of the states that matter, not just the first one you see in the simulator.\nBorders are another common source of confusion. In the older theme editor, borders often take precedence over background settings, which is why a component can look correct on one platform but unexpectedly wrong on another. The same general rule applies conceptually even when you work in CSS: understand which visual property is actually winning.\nThe other important concept from the lesson is inheritance. A custom style does not need to redefine everything from scratch. It is usually better to start from a base component style and override only what you actually want to change. That keeps your styles smaller and more maintainable.\nTheme constants and other lower-level theme settings still matter, especially when you are controlling broader application behavior or integrating with older theme-based assets. But for a new project, the practical approach is simpler than the older lesson suggests: use layouts to define structure, use CSS to define appearance, and only drop to the older theme tooling when you genuinely need the lower-level control.\nFurther Reading Themeing Developer Guide How Do I Create A Simple Theme Work With Multi Images And Device Densities ","permalink":"https://www.codenameone.com/courses/course-01-java-for-mobile-devices/008-theme-basics/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Course Lessons\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/cxllJwt10VU?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eStyling in Codename One starts with a simple question: are you trying to change how components look, or are you trying to change how the UI behaves structurally? If the answer is visual styling, the modern default is CSS. The video uses the older designer-centered theme workflow, and that still helps explain the underlying concepts, but for a new project you should usually start with CSS and treat the older theme editor as a lower-level tool rather than the main path.\u003c/p\u003e","title":"Theme Basics"},{"content":" Module 1: Course Lessons\nAdapting a UI design is never just a matter of copying pixels from a mockup into code. A design file shows you the visual intention. Your job is to translate that intention into a layout that survives different screen sizes, densities, font rendering differences, and real user interaction.\nThe first step is to break the design into categories instead of trying to build the whole screen at once. Some parts should stay as live UI: text, buttons, lists, search fields, toolbars, and anything the user interacts with. Some parts may need image assets: photographs, illustrations, decorative textures, or highly specific shapes that are not worth recreating in code. Once you make that distinction, the design becomes much easier to implement.\nThe video uses a Photoshop-based workflow and cuts image assets out of a PSD. That basic thinking is still useful, but the tooling has moved on. Today the same exercise might start from Figma, Sketch, or exported design assets rather than Photoshop, and the resulting Codename One implementation should usually be styled with CSS rather than centered around the older designer workflow.\nWhen you translate the design into UI, start with layout before styling. Build the screen structure using forms, containers, and layouts that express the visual hierarchy. Decide which areas belong in the toolbar, which belong in the content pane, and which elements need to float over the content. Once the structure is correct, styling becomes much easier because you are polishing a stable layout instead of trying to patch a brittle one.\nThis is also where you should resist the temptation to chase pixel perfection too early. A design mockup is often drawn for one screen size with one font rasterizer and one set of exact asset dimensions. A real mobile UI has to survive much more than that. It is usually better to match the intent and rhythm of the design than to overfit to one screenshot and end up with something that breaks on the next device.\nAssets still matter, but they should be chosen carefully. If a shape can be expressed with styling, borders, padding, and standard components, that is usually preferable to shipping another image. If an icon can come from a material icon font, that is usually preferable to exporting several bitmap versions. Use raster assets where they provide something unique, not as a substitute for understanding layout and styling.\nFloating action buttons, layered elements, and custom visual accents are good examples of where the implementation needs to understand the framework rather than just the mockup. A floating button is not simply drawn in one static position. It needs to live in the right layer and respond properly as the form size changes. A highlighted row or decorative border may be better represented by a border image, a styled background, or a reusable UIID depending on how the screen behaves.\nThe best way to adapt a design in Codename One today is to treat the mockup as a guide, recreate the structure with layouts, use CSS to style the resulting components, and only then introduce image assets where they genuinely improve the result. That approach scales much better than trying to paint the entire screen out of cut-up images.\nFurther Reading Developer Guide Themeing Layout Basics How Do I Create A 9 Piece Image Border How Do I Create Gorgeous SideMenu ","permalink":"https://www.codenameone.com/courses/course-01-java-for-mobile-devices/009-adapting-a-ui-design/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Course Lessons\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/WT4cFceBWRA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eAdapting a UI design is never just a matter of copying pixels from a mockup into code. A design file shows you the visual intention. Your job is to translate that intention into a layout that survives different screen sizes, densities, font rendering differences, and real user interaction.\u003c/p\u003e","title":"Adapting a UI Design"},{"content":" Module 3: Extracting a UI Design\nOne of the more useful lessons in UI implementation is learning when something that looks like a dialog should really be a form. The checkout screen in this module is a good example. Visually it behaves like an overlay, but structurally it owns more of the screen than a simple dialog and has controls that sit outside the central receipt area. Treating it as a form gives you much more control.\nThat choice affects everything else. Once the checkout UI is a form, transitions, layering, dismissal, and content layout become much easier to manage deliberately. The video creates the visual overlay effect by taking the current screen, rendering it into an image, and using a blurred and tinted version as the backdrop. The exact visual treatment can vary, but the principle is still valuable: separate the visual illusion from the structural implementation.\nThe receipt itself is then just another styled UI region. Its top and bottom decorations, list of items, close affordance, and checkout action all become ordinary layout problems once you stop thinking of the whole screen as a magical special case. That is often the trick with polished mobile UI work. The effect looks fancy, but the implementation becomes straightforward once the right structural choice is made.\nThis lesson also reinforces an important design habit: do not let the mockup choose the component model for you. A screen can look like a popup and still be better implemented as a form. A row can look like a tab and still really be a filter. A decorative border can look custom and still be best represented by a reusable border asset or CSS treatment. The job is to choose the structure that produces reliable behavior.\nSo the checkout form is valuable not only because it looks good, but because it demonstrates that advanced-looking UI often comes from ordinary building blocks combined carefully: one form, one transition, a styled content region, and a background effect that supports the illusion without dictating the architecture.\nFurther Reading Layout Basics CSS Transitions How Do I Create Gorgeous SideMenu ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/009-checkoutform/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 3: Extracting a UI Design\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/ts-Q1zBGXco?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOne of the more useful lessons in UI implementation is learning when something that looks like a dialog should really be a form. The checkout screen in this module is a good example. Visually it behaves like an overlay, but structurally it owns more of the screen than a simple dialog and has controls that sit outside the central receipt area. Treating it as a form gives you much more control.\u003c/p\u003e","title":"CheckoutForm"},{"content":" Module 4: App Maker Server\nOnce the server API exists, the client has to use it without making the product feel like a network admin console. That is the theme of this lesson.\nThe first important client-side job is establishing or retrieving the secret associated with the current editing device or session. That is an infrastructure step, but the user should not experience it as a setup ritual. The app should just do the work and continue.\nThat is why the asynchronous design here matters. The client asks for what it needs, keeps the UI moving, and treats network coordination as background product infrastructure rather than as a constant source of prompts and ceremony. This is especially important in builder-style tools, where too much visible networking friction quickly makes the product feel fragile.\nThe lesson\u0026rsquo;s philosophy is worth keeping: do not overexpose network reliability concerns to the user if the application can reasonably recover, retry, or defer those concerns internally. That does not mean ignoring errors. It means designing the flow so the product behaves like a cohesive tool instead of narrating every transport detail back to the user.\nSo the key takeaway here is not a specific request helper. It is the product stance: client/server coordination should support the editing flow quietly, not dominate it.\nFurther Reading Connecting to a Web Service REST API Design Communicating with the Server ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/009-communicating-from-the-client/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 4: App Maker Server\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/VnYaxvVn6OA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the server API exists, the client has to use it without making the product feel like a network admin console. That is the theme of this lesson.\u003c/p\u003e\n\u003cp\u003eThe first important client-side job is establishing or retrieving the secret associated with the current editing device or session. That is an infrastructure step, but the user should not experience it as a setup ritual. The app should just do the work and continue.\u003c/p\u003e","title":"Communicating from the Client"},{"content":" Module 4: UI Design From Scratch\nWorking from an existing design is one skill. Continuing when the design is incomplete is another. This module starts from that second situation: some screens already exist, but the application still needs additional forms, navigation paths, and visual decisions that were never specified in the original mockup.\nThat is a very normal place to be in real projects. Designers may deliver only the primary flow. Product requirements may grow after the original handoff. Some screens, like about pages, contact screens, settings, or edge-case flows, may never have been designed in detail at all. At that point the developer has to extend the design language without turning the app into a patchwork.\nThe important mindset here is that this is still not about becoming a graphic designer overnight. It is about learning to recognize the intention behind the existing design and then making new screens that feel like they belong to the same product. Consistency matters more than novelty. Reuse matters more than decoration. A good new screen often comes from carrying forward the spacing, hierarchy, motion, and interaction patterns that are already present.\nThe video makes a good point about avoiding flashy effects with no purpose. That advice is still worth following. Animation and transitions should communicate meaning, not just show off. A transition can indicate entering a deeper detail screen, revealing an overlay, or moving laterally between related views. When motion has no semantic role, it usually ends up making the UI feel dated rather than polished.\nSo this module is really about design judgment in a programmer\u0026rsquo;s context. You already have some patterns from the previous mockup-driven work. Now the task is to extend them. Build the missing forms, keep the visual language consistent, and make choices that support usability first. That is how a design system starts to become an application instead of a one-screen demo.\nFurther Reading Developer Guide Adapting a UI Design How Do I Create Gorgeous SideMenu Themeing ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/010-introduction/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 4: UI Design From Scratch\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/aZ2Y74xPj_0?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eWorking from an existing design is one skill. Continuing when the design is incomplete is another. This module starts from that second situation: some screens already exist, but the application still needs additional forms, navigation paths, and visual decisions that were never specified in the original mockup.\u003c/p\u003e","title":"Introduction"},{"content":" Module 5: SQLite and ORM Binding\nAs soon as the app maker starts feeling real, local persistence becomes valuable. The point is not that SQLite is always the perfect storage choice. The point is that instant startup, local continuity, and reduced server dependency make the editing experience much better.\nThe lesson handles this well by refusing to let SQL details leak through the whole application. Instead of scattering persistence code across forms, it introduces an application-specific storage abstraction. That is the right move regardless of the underlying technology because it keeps the rest of the app working in domain terms rather than persistence terms.\nThe ORM-style mapping used here is also pragmatic. It reduces boilerplate enough that local persistence becomes approachable instead of feeling like a second product hidden inside the first. The exact API details have evolved since the original lesson, but the architectural point remains sound: let a higher-level mapping layer handle repetitive SQLite concerns where it genuinely reduces friction.\nThe lesson is also refreshingly honest about why this local database exists. It is not there because local state is the ultimate source of truth. It is there because performance and responsiveness matter. That is a healthy way to reason about client-side persistence in a full-stack app. If the server is authoritative but the UI needs to feel fast and resilient, some duplication is often worth it.\nSo the main lesson here is to persist locally on purpose, behind a small abstraction, and for a reason the product can justify.\nFurther Reading Communicating with the Server Integrating SQLite into the Code How Do I Use Storage, File System, SQL ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/010-sqlite-abstraction-with-object-relational-mapping/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 5: SQLite and ORM Binding\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/Qw7moLv-dE4?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eAs soon as the app maker starts feeling real, local persistence becomes valuable. The point is not that SQLite is always the perfect storage choice. The point is that instant startup, local continuity, and reduced server dependency make the editing experience much better.\u003c/p\u003e","title":"SQLite Abstraction with Object Relational Mapping"},{"content":" Module 1: Course Lessons\nPersistent data in Codename One usually starts with a choice between three levels of storage: Preferences for very small settings, Storage for simple app-private persisted objects or blobs, and SQL for data that needs real querying, sorting, or filtering. The file system sits beside those as a lower-level tool rather than the default answer to every persistence question.\nStorage is the place to start for many apps because it is portable and application-oriented. It is not a general shared file hierarchy. It is a higher-level persistence API tied to the app itself. That makes it a much better default than reaching immediately for raw files just because you are used to desktop development.\nThe file system becomes useful when you actually need file paths, larger assets, or interoperability with APIs that naturally work in terms of files. But mobile app isolation still matters. Devices do not expose the same shared-file assumptions developers are used to on the desktop. Even when some platforms allow more shared file access than others, that behavior is not the best foundation for portable application design.\nSQL is the right tool when your data is large enough or dynamic enough that you need real query capability. If you need filtering, sorting, lookups, or structured updates over a meaningful amount of data, SQLite is usually a better fit than trying to serialize everything into a single stored object. If you just need to save app state or a few structured objects, SQL is often unnecessary complexity.\nThe lesson also makes an important operational point about cleanup. Database cursors and related resources should be closed explicitly. You should not rely on the garbage collector to clean up database resources whenever it happens to run. That becomes especially important when portability differences between platforms affect database behavior and thread safety.\nShipping an initial database is another valid pattern. If the app needs seed data, you can package a database resource and copy it into the correct writable location on first run. That is often easier than trying to generate the full initial data set programmatically every time.\nThe modern recommendation is mostly about choosing the simplest layer that fits the problem. Use Preferences for settings, Storage for straightforward app-private persistence, SQL when you genuinely need query power, and filesystem APIs when the problem is really file-oriented. Starting at the highest appropriate level tends to produce the most portable and maintainable code.\nFurther Reading Developer Guide How Do I Use Properties To Speed Development How Do I Improve Application Performance Or Track Down Performance Issues ","permalink":"https://www.codenameone.com/courses/course-01-java-for-mobile-devices/010-storage-filesystem-and-sql/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Course Lessons\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/_EXEN52wQvs?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003ePersistent data in Codename One usually starts with a choice between three levels of storage: \u003ccode\u003ePreferences\u003c/code\u003e for very small settings, \u003ccode\u003eStorage\u003c/code\u003e for simple app-private persisted objects or blobs, and SQL for data that needs real querying, sorting, or filtering. The file system sits beside those as a lower-level tool rather than the default answer to every persistence question.\u003c/p\u003e","title":"Storage Filesystem and SQL"},{"content":" Module 5: SQLite and ORM Binding\nAdding local persistence is only half the job. The bigger question is how the rest of the application reacts to that persistence without turning every screen into a tightly coupled database client.\nThis lesson moves in the right direction by letting the model and the storage abstraction drive updates while the UI stays focused on presentation. Property listeners and deletion events are doing the real work here. They allow the forms to respond to meaningful changes in the data model instead of polling or manually synchronizing every visible element.\nThe delete flow is also a good product lesson. Mobile interfaces often work better when the app performs the obvious action and offers undo than when it stops to ask for permission on every destructive step. That pattern only works, though, if the underlying model and UI are structured well enough to make undo or re-addition straightforward. This lesson gets that balance right.\nThe broader idea is that persistence should not make the app feel heavier. Users should not experience \u0026ldquo;now we are saving to SQLite\u0026rdquo; as a separate phase. The storage integration should simply make edits survive, lists update, and property-driven UI stay in sync.\nSo the integration lesson is really about coupling and user experience at the same time: connect local persistence deeply enough that the app benefits from it, but not so deeply that every screen becomes persistence-aware in all the wrong ways.\nFurther Reading SQLite Abstraction with Object Relational Mapping How Do I Use Properties To Speed Development How Do I Use Storage, File System, SQL ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/011-integrating-sqlite-into-the-code/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 5: SQLite and ORM Binding\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/vAiTW4Y8QuA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eAdding local persistence is only half the job. The bigger question is how the rest of the application reacts to that persistence without turning every screen into a tightly coupled database client.\u003c/p\u003e\n\u003cp\u003eThis lesson moves in the right direction by letting the model and the storage abstraction drive updates while the UI stays focused on presentation. Property listeners and deletion events are doing the real work here. They allow the forms to respond to meaningful changes in the data model instead of polling or manually synchronizing every visible element.\u003c/p\u003e","title":"Integrating SQLite into the Code"},{"content":" Module 4: UI Design From Scratch\nThe real test of a design system begins when you need screens that were never designed for you. A product rarely stops at the original mockup. It needs detail screens, about pages, contact forms, side menus, and supporting flows that still have to feel like they belong to the same app.\nThis lesson is about designing those missing forms without pretending you are starting from nothing. You already have a visual language: spacing, colors, image treatment, buttons, overlays, and a certain rhythm to the UI. The job is to extend that language rather than invent a different one for every new screen.\nThe dish detail screen is a good example. The content is different from the menu screen, but the priorities are not mysterious. The dish itself is still the hero. The supporting text, price, and action affordances need to stay visible without competing with the image. Once you recognize that hierarchy, the new screen can grow naturally out of the original design instead of feeling pasted on.\nThe same principle applies to the about and contact screens. These pages often exist outside the main product flow, but they should not look like they came from another app. If the contact form highlights the location, let the map become the dominant element. If the about page is content-heavy, use the platform\u0026rsquo;s strengths to present that content cleanly. The visual language can relax a little to suit the new purpose, but it should still be recognizably part of the same product.\nThe side menu is another case where familiarity matters. Users already understand the basic conventions of side navigation, so the most important job is not to reinvent the pattern. It is to make the menu feel visually consistent with the rest of the app while preserving the usability people expect.\nThis lesson also reinforces something developers often underweight: taste is partly a matter of noticing why an existing design works. If you study how other apps solve similar problems, not to copy them literally but to understand their decisions, your own additions become much more grounded. That is especially useful when the original design is incomplete and you need to make judgment calls quickly.\nFurther Reading Developer Guide Themeing Adapting a UI Design How Do I Create Gorgeous SideMenu ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/011-the-new-forms/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 4: UI Design From Scratch\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/bH7cS5ENNlw?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe real test of a design system begins when you need screens that were never designed for you. A product rarely stops at the original mockup. It needs detail screens, about pages, contact forms, side menus, and supporting flows that still have to feel like they belong to the same app.\u003c/p\u003e","title":"The New Forms"},{"content":" Module 1: Course Lessons\nThreading becomes much less mysterious once you separate two different concerns: doing work, and updating the user interface. In Codename One, those two things should not be mixed casually. The UI is driven by the event dispatch thread, usually shortened to EDT, and that thread needs to stay responsive if the application is going to feel smooth.\nThe simplest mental model is that the EDT is the thread that owns UI work. Painting, handling most user interaction, and changing component state should happen there. If you block it with long calculations, network waits, database work, or file processing, the app stops feeling alive. Buttons appear unresponsive, animations freeze, and the whole interface looks broken even if the code is technically still running.\nThat is why background work matters. Expensive or slow operations should run off the EDT, then hand control back to the EDT when it is time to update the UI. This is one of the core habits of mobile development in general, not just Codename One. The framework gives you utilities to help with that handoff, but the underlying rule is simple: keep slow work away from the UI thread.\nThe video also points out something that is still worth taking seriously: portability is one reason to keep threading simple. Codename One targets multiple platforms and runtime environments, so code that depends on subtle threading behavior or low-level JVM memory-model tricks is much more likely to become fragile. The framework is happiest when your concurrency model is boring and explicit.\nIn practice, that means you should treat the EDT as a place for fast UI logic, not a place for long-running business logic. Build the screen there. React to taps there. Start background work from there when needed. Then return to the EDT to update labels, show dialogs, replace forms, or refresh components once the work is done.\nIt also means you should be careful about \u0026ldquo;almost fast\u0026rdquo; work. A single blocking call may not feel dangerous while testing on a desktop simulator, but mobile hardware, slow storage, and real networks make those delays much more obvious. If an operation might pause for a noticeable amount of time, it probably does not belong on the EDT.\nOnce you adopt that model, threading stops being an abstract theory lesson and becomes a practical discipline: keep the interface responsive, move slow work to the background, and bring results back to the UI thread in a controlled way. Most Codename One applications do not need elaborate concurrency. They need that one rule applied consistently.\nFurther Reading Developer Guide How Do I Access Remote Webservices, Perform Operations On The Server How Do I Improve Application Performance Or Track Down Performance Issues How Do I Find Problems In My Application Using The Codename One Tools And The Standard IDE Tools ","permalink":"https://www.codenameone.com/courses/course-01-java-for-mobile-devices/011-threading-and-the-edt/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Course Lessons\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/p6UFNw0nGik?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThreading becomes much less mysterious once you separate two different concerns: doing work, and updating the user interface. In Codename One, those two things should not be mixed casually. The UI is driven by the event dispatch thread, usually shortened to EDT, and that thread needs to stay responsive if the application is going to feel smooth.\u003c/p\u003e","title":"Threading and the EDT"},{"content":" Module 6: Miscellaneous Features\nMany products reach a point where the remaining work is not one dramatic feature but a collection of missing pieces that quietly determine whether the app feels complete. This lesson is about that stage.\nThe category flow is a strong example of solving a product problem by reducing UI rather than adding more of it. Instead of introducing a whole separate category-management experience, the app lets categories emerge through dish editing with autocomplete support and cleanup logic behind the scenes. That is a simpler model for both the code and the user.\nValidation is the other major theme here. Category presence, numeric pricing, and basic detail integrity are not glamorous features, but they are part of making the builder trustworthy. The lesson is right to put validation near the editing experience instead of treating it as a distant backend-only concern.\nThe details form also shows a good instinct about complexity management. Whenever a setting leads into a more focused editing experience, navigating to a dedicated screen is often clearer than cramming everything into a single overloaded form. That is especially true in a builder product where users can easily get lost in a wall of unrelated controls.\nSo the common thread in this lesson is simplification through structure. Remove unnecessary management screens where the workflow can be inferred, validate where the user is already working, and split details into focused editors instead of building one giant control panel.\nFurther Reading Fleshing Out the UI Design Billing and Global Server How Do I Use Properties To Speed Development ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/012-details-categories-and-validation/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 6: Miscellaneous Features\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/VCNFKMeud-w?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eMany products reach a point where the remaining work is not one dramatic feature but a collection of missing pieces that quietly determine whether the app feels complete. This lesson is about that stage.\u003c/p\u003e\n\u003cp\u003eThe category flow is a strong example of solving a product problem by reducing UI rather than adding more of it. Instead of introducing a whole separate category-management experience, the app lets categories emerge through dish editing with autocomplete support and cleanup logic behind the scenes. That is a simpler model for both the code and the user.\u003c/p\u003e","title":"Details, Categories and Validation"},{"content":" Module 4: UI Design From Scratch\nA checkout screen is not finished just because it looks good. If users cannot understand what they ordered, change quantities easily, or remove mistakes without friction, the design has failed at the point where clarity matters most.\nThat is the problem this lesson addresses. The earlier checkout design was visually appealing, but it did not give the user a practical way to change the order. That kind of gap is common in mockups. A screen is designed for presentation, then later you discover that a real product still needs editing, correction, and confirmation behaviors that the design never accounted for.\nThere are several possible fixes. Swipe gestures can keep the surface clean, but they are easy to miss. An edit mode can work, but it adds state and often makes the flow feel heavier than necessary. Always-visible controls take more space, but they are honest about what the user can do.\nThe solution in the lesson is a good practical compromise: make the quantity directly editable through a compact control that fits the existing visual language, and use a picker-based interaction to avoid keyboard friction. That is an especially sensible choice on mobile because it reduces validation problems, keeps the interaction predictable, and makes deletion just another quantity change to zero rather than a separate destructive action.\nWhat matters most here is not the exact widget choice. It is the principle that checkout should support correction without making the user search for hidden functionality. At this stage of the flow, discoverability and confidence matter more than keeping the layout pristine.\nSo if a checkout UI feels elegant but does not let the user edit the order naturally, fix the behavior first and let the visual solution follow that need. Real product quality comes from that willingness to adjust the design once real interaction requirements become obvious.\nFurther Reading Developer Guide How Do I Create A List Of Items The Easy Way Threading and the EDT ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/012-fixing-the-checkout-experience/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 4: UI Design From Scratch\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/CvbcWC4hLYk?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eA checkout screen is not finished just because it looks good. If users cannot understand what they ordered, change quantities easily, or remove mistakes without friction, the design has failed at the point where clarity matters most.\u003c/p\u003e\n\u003cp\u003eThat is the problem this lesson addresses. The earlier checkout design was visually appealing, but it did not give the user a practical way to change the order. That kind of gap is common in mockups. A screen is designed for presentation, then later you discover that a real product still needs editing, correction, and confirmation behaviors that the design never accounted for.\u003c/p\u003e","title":"Fixing the Checkout Experience"},{"content":" Module 1: Course Lessons\nCodename One properties are useful when you want one model class to do more than simply hold data. A plain old Java object can represent state just fine, but it does not automatically know how to bind to UI, serialize itself, parse structured input, or describe its own fields at runtime. The properties API exists to make those jobs easier.\nThe core idea is that a property-backed object carries metadata about its fields through the property index. That means the framework can introspect the object safely even after obfuscation. Once that metadata exists, a lot of repetitive plumbing becomes easier: JSON and XML mapping, serialization, SQL helpers, UI binding, and generated forms.\nThis is what makes properties more than just a different syntax for getters and setters. You still keep a clear data model, but you also gain a structured description of that model that the framework can reuse. That is why the lesson moves quickly from basic property access into parsing, storage, CRUD helpers, and binding. Those features all depend on the same underlying introspection capability.\nTwo uses are especially practical. The first is data mapping. If your app receives structured data from a service and you want a cleaner route from raw JSON or XML into an object model, properties can reduce a lot of manual parsing code. The second is UI binding. If a field in the model changes and a component should reflect that change, or vice versa, the properties API gives you a much cleaner starting point than manually wiring every update yourself.\nThe lesson also highlights Instant UI, which can generate forms from property objects. That is still conceptually useful, but it should be applied with judgment. Generated UI can be a strong accelerator for internal tools, simple data-entry screens, or prototypes. It is not automatically the best fit for polished product UI where custom layout and styling matter more. In modern projects, CSS and hand-authored layout code still remain the better choice for most high-touch product screens.\nSo the best way to think about properties is as a productivity tool for model-driven parts of an application. If the same object needs to be bound to UI, serialized, parsed, and perhaps stored, properties can eliminate a lot of repetitive glue code. If the object is simple and none of those benefits matter, a normal POJO may still be the simpler choice.\nFurther Reading Developer Guide Properties Are Amazing How Do I Use Storage, File System And SQL ","permalink":"https://www.codenameone.com/courses/course-01-java-for-mobile-devices/012-understanding-properties/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Course Lessons\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/77N2t2n8rbQ?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eCodename One properties are useful when you want one model class to do more than simply hold data. A plain old Java object can represent state just fine, but it does not automatically know how to bind to UI, serialize itself, parse structured input, or describe its own fields at runtime. The properties API exists to make those jobs easier.\u003c/p\u003e","title":"Understanding Properties"},{"content":" Module 6: Miscellaneous Features\nBilling screens are often deceptively simple. The form may look like a set of ordinary fields, but the layout, data mapping, and server contract beneath it are doing more work than the visuals suggest.\nThis lesson handles that well by separating the visible editing experience from the way the data is ultimately packaged and sent. The billing form itself is mostly straightforward UI. The more interesting design choice is how the builder\u0026rsquo;s local application state is combined into the server-facing representation.\nThat merging step is a useful reminder that client-side models and server-side payloads do not need to map one-to-one. Sometimes the client organizes data for editing convenience, while the server expects a flatter or differently structured contract. That is normal. The important thing is to keep the translation explicit instead of letting it happen accidentally in random places.\nThe lesson also points to a broader truth about rapidly evolving builder products: persistence strategies may start pragmatically. Preferences, lightweight local state, and partial mappings can all be acceptable as long as they serve the workflow and are honest about their limits. Perfection in local storage architecture is not the first milestone. A working end-to-end billing and settings flow is.\nSo this section is less about billing forms in isolation and more about how builder-state becomes server-state cleanly enough that the product can keep moving.\nFurther Reading Introduction, Architecture and Authorization REST API Design How Do I Use Properties To Speed Development ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/013-billing-and-global-server/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 6: Miscellaneous Features\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/Q0fkApAGMZA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eBilling screens are often deceptively simple. The form may look like a set of ordinary fields, but the layout, data mapping, and server contract beneath it are doing more work than the visuals suggest.\u003c/p\u003e\n\u003cp\u003eThis lesson handles that well by separating the visible editing experience from the way the data is ultimately packaged and sent. The billing form itself is mostly straightforward UI. The more interesting design choice is how the builder\u0026rsquo;s local application state is combined into the server-facing representation.\u003c/p\u003e","title":"Billing and Global Server"},{"content":" Module 4: UI Design From Scratch\nWhenever new screens are added, the styling layer has to catch up. Otherwise the application ends up with correct layouts but mismatched visual language. This lesson is about extending the CSS so the new forms, overlays, and side menu feel like the same product rather than late additions.\nThat work is usually less about dramatic restyling and more about tightening the small things that carry consistency: gradients, padding, transparency, text treatment, separators, and inherited button styles. These are the pieces that make a screen feel related to the rest of the app even when its structure is different.\nThe newer forms in this module need that kind of refinement. The dish view, the contact screen, and the side menu all reuse ideas from earlier screens, but they each need their own UIIDs and spacing rules. Without those explicit rules, native defaults and inherited behavior start leaking in, and the app begins to look inconsistent even if the layouts are technically correct.\nThe side menu is a particularly good example. Side commands often receive strong native-theme defaults, so if you want them to look intentional you usually need to override more than you first expect. Background, spacing, text decoration, and separator behavior all need deliberate choices. Otherwise the menu keeps the behavior of the framework but not the visual identity of your application.\nThis lesson also reinforces a maintainability rule: if two components are visually related, their styles should be related too. Reuse through inheritance or shared style concepts is not just a convenience. It is how you keep the UI from drifting as the project grows. Modern Codename One projects should keep that work in CSS whenever possible rather than bouncing between multiple styling systems.\nSo the right way to think about these CSS changes is not \u0026ldquo;decorate the new screens.\u0026rdquo; It is \u0026ldquo;extend the design system so the new screens belong.\u0026rdquo; That mindset produces more durable styling decisions.\nFurther Reading Themeing Working With CSS CSS How Do I Create A Simple Theme ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/013-css-changes/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 4: UI Design From Scratch\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/MLbOdCt67Rw?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eWhenever new screens are added, the styling layer has to catch up. Otherwise the application ends up with correct layouts but mismatched visual language. This lesson is about extending the CSS so the new forms, overlays, and side menu feel like the same product rather than late additions.\u003c/p\u003e","title":"CSS Changes"},{"content":" Module 1: Course Lessons\nPush notification is best understood as a user-notification channel, not as a general-purpose networking layer. It is good for telling a device that something happened and, depending on platform and app state, optionally carrying some payload with that message. It is not something you should design your core application protocol around.\nThat distinction matters because push is inherently unreliable as a transport. Users can disable it. Some devices or services may not support it the same way. Different platforms treat background delivery differently. Build your app so that push signals something important, but do not assume it is always available or always delivered in the same way everywhere.\nCodename One smooths over a lot of the platform differences by providing a unified push API and server-side push entry point. You still need platform credentials for the vendor services, but you do not have to design a completely separate push implementation for every target OS. The high-level workflow is: configure the provider credentials, register the app for push, collect the push token on the device, send that token to your server, and then use your server to send push messages through the Codename One push infrastructure.\nOn the client side, one of the most important details is that push callbacks belong in the main application class. The PushCallback implementation must live in the class that represents the app lifecycle. That is where Codename One wires push delivery into the application. The key callbacks are the message callback itself, the registration callback, and the registration error callback.\nThe registration callback is especially important because that is where you usually obtain the push key and send it to your own backend. A common mistake is to treat the device identifier argument as if it were the push token. It is not. The push key is what your server needs in order to target that device later.\nServer-side push is just as important as the client setup. Sending the request is not enough; you also need to parse the response and log the outcome. A lot of push debugging time is wasted by code that fires off a request and never looks closely at the response body. If delivery fails because of a credential mismatch, certificate problem, provider rejection, or malformed request, that response is often your only useful clue.\nPush types also need to be chosen deliberately. Visible notification types are usually the safest default because they match what users and platforms expect. Hidden push and payload-heavy push are more nuanced and behave differently across operating systems, especially on iOS. The lesson is out of date in its references to older Google push naming and setup steps, but the design lesson is still current: treat push as signaling, not as the backbone of app synchronization.\nFurther Reading Developer Guide Build Hints Build Server How Do I Use Crash Protection? Get Device Logs? ","permalink":"https://www.codenameone.com/courses/course-01-java-for-mobile-devices/013-push-notification/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Course Lessons\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/8wzBpEp81Kc?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003ePush notification is best understood as a user-notification channel, not as a general-purpose networking layer. It is good for telling a device that something happened and, depending on platform and app state, optionally carrying some payload with that message. It is not something you should design your core application protocol around.\u003c/p\u003e","title":"Push Notification"},{"content":" Module 4: UI Design From Scratch\nOnce the new screens have been designed, the application still needs the code structure to support them cleanly. This lesson is where the design work turns back into application engineering: model objects, reusable form logic, quantity editing, map integration, HTML content, and the small animation details that make the whole flow feel deliberate.\nOne of the key ideas here is that richer UI usually demands a clearer model. A dish is no longer just something painted on screen. It now has identity, descriptive data, pricing, image variants, and behaviors associated with ordering. That is why the lesson starts pulling the underlying data representation into a more explicit form.\nThe rest of the code changes follow naturally from the design decisions made earlier. The about form needs a structured way to host HTML content. The contact screen needs map integration and action buttons that connect to native capabilities. The checkout flow needs quantity editing and removal behavior that feels smooth instead of abrupt. None of these are isolated gimmicks. They are consequences of choosing to build a fuller application rather than a static mockup.\nThe animation and overlay details are especially useful because they show how polish often comes from sequencing rather than from fancy APIs. Remove an element, let the layout animate, then update totals and related UI once the movement is complete. That order matters. It prevents visual interference and makes the app feel more intentional.\nThe same is true of layered components, overlays, and special visual treatments. They are easiest to reason about once you understand which parts are structural and which parts are just visual support. A glass pane, a layered layout, or a positioned overlay can solve a very specific problem cleanly if the rest of the form architecture is already sound.\nSo the summary of this lesson is that extending a UI from mockup to working app requires both taste and structure. The design choices create new requirements, and the code has to respond by becoming more explicit, more reusable, and a little more architectural than the early demo version.\nFurther Reading Developer Guide How Do I Access Native Device Functionality, Invoke Native Interfaces How Do I Use Properties To Speed Development How Do I Take A Picture With The Camera ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/014-code-changes-and-summary/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 4: UI Design From Scratch\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/a6q1M_wqEYY?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the new screens have been designed, the application still needs the code structure to support them cleanly. This lesson is where the design work turns back into application engineering: model objects, reusable form logic, quantity editing, map integration, HTML content, and the small animation details that make the whole flow feel deliberate.\u003c/p\u003e","title":"Code Changes and Summary"},{"content":" Module 1: Course Lessons\nNative interfaces are how you call platform-specific code from a Codename One application without giving up the portability of the rest of the project. When Codename One says \u0026ldquo;native\u0026rdquo; in this context, it does not mean Java\u0026rsquo;s ordinary native keyword. It means \u0026ldquo;use the platform\u0026rsquo;s own language and APIs\u0026rdquo; when you need something that the portable Codename One layer does not expose directly.\nThat means the implementation changes by platform. On Android, a native interface implementation can use the Android SDK and third-party Android libraries. On iOS, the implementation uses the native iOS language and APIs. On JavaScript builds, you can call into JavaScript. On the desktop port, you can use ordinary JavaSE APIs. The Java code in your main app remains the same; the native interface is the bridge that dispatches to the right implementation on each platform.\nThe core idea is simple: define an interface that extends NativeInterface, then provide platform-specific implementations of that interface. The interface becomes the contract between your portable Java code and the native side. isSupported() is especially important because not every platform will necessarily have an implementation. Your Java code should check whether the native feature is available before relying on it.\nThis is useful both inside an application and inside a cn1lib. In fact, cn1libs are one of the best uses of native interfaces because they let you wrap messy platform-specific integration behind a clean Java API. The caller sees a normal library. The native details stay hidden inside the implementation.\nThe most important habit here is to keep the native surface area small. Expose the narrowest interface that solves the problem. It is tempting to mirror a large native API directly, but that usually leads to code that is harder to maintain, harder to test, and harder to port. A small interface with a few focused methods is much easier to reason about and much easier to support across platforms.\nNative interfaces also restrict the kinds of types you can pass. That is intentional. Simple values such as primitives, strings, byte arrays, and peers are much easier to move between languages and runtimes. Once you try to pass complex Java objects directly into Objective-C, JavaScript, or other native code, translation becomes far more complicated and performance becomes harder to predict.\nPeerComponent is one of the most important special cases. It allows native code to return a native visual component that can be placed into a Codename One layout like an ordinary component. The classic example is a native map view. That pattern is powerful because it gives you real native UI where it matters while still letting the surrounding screen remain portable.\nThe hard part of native interfaces is often not the code itself but the configuration around it. Native libraries frequently come with Gradle dependencies on Android, CocoaPods or frameworks on iOS, manifest changes, plist changes, and packaging rules for extra files. In Codename One these are usually handled through build hints and native source packaging.\nFurther Reading Developer Guide Build Hints Build Server How Do I Access Native Device Functionality? Invoke Native Interfaces? ","permalink":"https://www.codenameone.com/courses/course-01-java-for-mobile-devices/014-native-interfaces-access-native-device-features/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 1: Course Lessons\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/2xKvvv7XoVQ?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eNative interfaces are how you call platform-specific code from a Codename One application without giving up the portability of the rest of the project. When Codename One says \u0026ldquo;native\u0026rdquo; in this context, it does not mean Java\u0026rsquo;s ordinary \u003ccode\u003enative\u003c/code\u003e keyword. It means \u0026ldquo;use the platform\u0026rsquo;s own language and APIs\u0026rdquo; when you need something that the portable Codename One layer does not expose directly.\u003c/p\u003e","title":"Native Interfaces - Access Native Device Features"},{"content":" Module 6: Miscellaneous Features\nPreview is one of the most important features in a builder product because it turns editing from abstract configuration into immediate feedback. This lesson finally gives that idea the implementation attention it deserves.\nThe side menu matters here because it helps the builder feel like a complete tool rather than a pile of forms. Small visual decisions such as padding, selection styling, and header content do more than improve aesthetics. They make the product feel stable and intentional while users move between editing contexts.\nThe preview path is even more important. The clever part is not that a preview exists. It is that the system reuses the actual restaurant app code instead of inventing a fake representation of what the generated app might look like. That is a strong product choice because the preview is more trustworthy when it is built from the same implementation path as the real result.\nThe lesson openly takes the pragmatic route by copying the restaurant app sources instead of prematurely generalizing everything into a shared framework. That is consistent with the rest of the course and still the right instinct here. If the preview proves valuable and the duplication becomes painful, that is the right moment to refactor. Not before.\nSo the key lesson is that preview should be treated as a product feature, not as a nice extra. The more directly it reflects the actual generated app, the more useful it becomes to the user and to the developer.\nFurther Reading Scope and Basic UI Design Themeing How Do I Create Gorgeous SideMenu ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/014-sidemenu-and-preview/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 6: Miscellaneous Features\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/jhPep9vHv_U?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003ePreview is one of the most important features in a builder product because it turns editing from abstract configuration into immediate feedback. This lesson finally gives that idea the implementation attention it deserves.\u003c/p\u003e\n\u003cp\u003eThe side menu matters here because it helps the builder feel like a complete tool rather than a pile of forms. Small visual decisions such as padding, selection styling, and header content do more than improve aesthetics. They make the product feel stable and intentional while users move between editing contexts.\u003c/p\u003e","title":"Sidemenu and Preview"},{"content":" Module 6: Miscellaneous Features\nAbout pages are easy to underestimate because they are rarely the headline feature of an app. In practice they matter a lot. They give the product a place for identity, contact information, explanatory content, and other material that should exist without cluttering the main workflow.\nThis lesson is dealing with two related but different problems. The builder itself needs an about experience, and the generated restaurant app needs a configurable about destination of its own. Those are not the same concern, and treating them separately is the right design move.\nFor the builder\u0026rsquo;s own about page, HTML is a reasonable tool because the content is mostly informational and static. That is one of the few areas where a browser-based presentation can be more convenient than building everything out of native-looking components. The older lesson says this directly, and that judgment still makes sense.\nFor the generated app, the choice to rely on a URL instead of embedding arbitrary HTML is also pragmatic. It keeps the app-maker workflow simpler and assumes something that is usually true in the real world: a restaurant likely already has a site or a page that can serve as the deeper “about” destination. That is often better than turning the builder into a full CMS just to support one screen.\nThe validation portion of the lesson is also important. If the builder is going to save and preview an about destination, it should not accept obviously broken values and hope the user notices later. Lightweight validation at the point of edit is part of making the builder feel trustworthy.\nSo the real lesson here is not “how to show HTML.” It is how to give both the editor and the generated app an about experience that fits their purpose without dragging the product into unnecessary complexity.\nFurther Reading Sidemenu and Preview Details, Categories and Validation Developer Guide ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/015-about-forms/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 6: Miscellaneous Features\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/a7MF3oSCASE?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eAbout pages are easy to underestimate because they are rarely the headline feature of an app. In practice they matter a lot. They give the product a place for identity, contact information, explanatory content, and other material that should exist without cluttering the main workflow.\u003c/p\u003e","title":"About Forms"},{"content":" Module 5: Architecture\nAt some point a project can no longer live as a collection of forms and helper methods. Once the UI starts to stabilize, the next step is to make the data model explicit and decide where application state should live. That shift is what this lesson is about.\nThe important thing here is not to overreact and invent a giant architecture too early. The lesson takes a more useful approach: start from the things the UI already proved are necessary. If the app clearly revolves around dishes, categories, orders, and restaurant-level information, then those are the right places to start shaping the model.\nThat is a healthier way to design architecture than beginning with abstract diagrams and hoping the product eventually fits them. A menu screen implies a menu model. A checkout flow implies an order model. Restaurant branding, address, contact details, and currency imply some application-level object that represents the current restaurant state. The UI has already told you what the model needs to be.\nThe singleton-style restaurant object used in the lesson is a pragmatic choice for a demo-sized application. It centralizes the state the rest of the UI depends on and keeps the app easy to reason about while the architecture is still evolving. In a larger system you might eventually split responsibilities further, but this is a reasonable starting point because it matches the actual scope of the app.\nThis lesson also hints at a broader modeling principle: not everything needs the same identity rules. Some objects naturally need stable identifiers because they represent persistent records or externally referenced entities. Others exist more as configuration or supporting data. It is fine for the model to reflect that difference instead of forcing uniformity where it is not useful.\nThe result of this first architecture pass is not a grand framework. It is a cleaner separation between the UI and the data it presents. That alone makes the next set of changes easier, because once the model is explicit, the forms stop having to carry hidden application state in ad hoc ways.\nFurther Reading Developer Guide How Do I Use Properties To Speed Development Connecting to a Web Service ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/015-overview-and-basic-model/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 5: Architecture\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/mFFjxs9EDW8?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eAt some point a project can no longer live as a collection of forms and helper methods. Once the UI starts to stabilize, the next step is to make the data model explicit and decide where application state should live. That shift is what this lesson is about.\u003c/p\u003e","title":"Overview and Basic Model"},{"content":" Module 5: Architecture\nOnce the model exists, the next question is whether the UI is truly using it or just sitting beside it. This lesson is the point where the restaurant, menu, order, and dish data start driving what the application shows instead of merely backing it in theory.\nThat integration is where architecture starts paying off. A category list no longer needs to be hard-coded because the menu model can supply it. Totals no longer need to be manually synchronized in several places because the order model can become the source of truth. Contact screens no longer need literal strings embedded in the UI because restaurant-level data can fill them in.\nThe listener-based update pattern in the lesson is especially important. When one part of the application changes shared state, the rest of the UI should respond through a clear mechanism instead of requiring scattered manual refresh logic. That keeps the application from turning into a patchwork of \u0026ldquo;remember to update this label too\u0026rdquo; style code.\nThis is also the point where formatting decisions become part of the model rather than accidental view logic. Currency is a good example. If the restaurant defines the currency, then the UI should present values through that lens rather than applying a generic formatting assumption in random places. Small decisions like that are a sign that the app is beginning to think in domain terms instead of just widget terms.\nThe wider lesson here is that good architecture does not need to arrive all at once. It can emerge from repeated cleanup as the UI becomes real. Start with the screens, identify the shared data they imply, move that data into an explicit model, then let the forms depend on that model instead of inventing their own local truths. That is often a much more productive path than trying to design the whole system upfront.\nFurther Reading Developer Guide Overview and Basic Model How Do I Use Properties To Speed Development How Do I Localize/Translate My Application, Apply i18n/l10n to My App ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/016-integration-and-summary/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 5: Architecture\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/Ke8bjFdD1bc?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the model exists, the next question is whether the UI is truly using it or just sitting beside it. This lesson is the point where the restaurant, menu, order, and dish data start driving what the application shows instead of merely backing it in theory.\u003c/p\u003e","title":"Integration and Summary"},{"content":" Module 7: Style Form\nStyle customization is where the app maker stops being a form editor and starts behaving like a product-design tool. That shift is important, because once users can see and alter the look of the generated app directly, the builder becomes much more compelling.\nThe first thing this lesson gets right is restraint. Full visual freedom sounds attractive, but in practice it can produce a confusing editor and a generated app that looks broken. The builder deliberately limits what can be customized, where it can be customized, and how deep the options go. That is a strength, not a weakness.\nThe core interaction is simple and still strong: show the actual app UI, let the user tap meaningful parts of it, and make those parts customizable in context. That beats a detached theme-control panel because users do not need to translate abstract style names into visible outcomes.\nThe lesson also makes an important architectural distinction between temporary editing state and committed styling changes. Users need to be able to explore, preview, and cancel without immediately persisting every choice. That is fundamental for builder UX. A customization workflow that commits too early feels risky and brittle.\nFrom a modern Codename One perspective, the main idea still holds even though newer projects generally center styling around CSS rather than older theme workflows. In a builder product, you still need an application-level representation of style choices and a consistent way to layer those choices onto the generated app. The mechanics may evolve, but that product need does not.\nSo the purpose of the style form is not just to expose colors and fonts. It is to define a safe, understandable boundary around customization so users feel they are shaping the app, not breaking it.\nFurther Reading Themeing Working With CSS Style Customization 2 - The Customization Popup ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/016-style-customization-1-introduction-and-basics/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 7: Style Form\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/p05yMCleSLo?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eStyle customization is where the app maker stops being a form editor and starts behaving like a product-design tool. That shift is important, because once users can see and alter the look of the generated app directly, the builder becomes much more compelling.\u003c/p\u003e","title":"Style Customization 1 - Introduction and Basics"},{"content":" Module 7: Style Form\nOnce the style form exists, the next design problem is deciding how customization should be presented. The popup approach in this lesson is a good answer because it keeps the editing UI close to the thing being edited and limits the choices to what actually makes sense for that element.\nThat contextual behavior matters. A builder should not offer font controls for elements that have no meaningful text. It should not pretend background customization is useful where borders or other constraints make it irrelevant. Good customization tools are as much about saying “not here” as they are about exposing more controls.\nThe lesson’s focus on pointer release instead of pointer press is also a subtle but good reminder that editing tools still need to respect normal UI behavior. A customization feature that feels glitchy or race-prone because it fires too early undermines the trust users need in the editor.\nThe popup itself is a strong interaction pattern because it keeps the mental model local: tap a thing, get the relevant choices for that thing, apply a change, and see the result right there. That is far easier to understand than jumping out to a distant control panel and hoping the user remembers what they were editing.\nSo this lesson is really about matching the editing surface to the structure of the UI. Contextual style editing works well when the options are filtered intelligently and the feedback is immediate.\nFurther Reading Style Customization 1 - Introduction and Basics Style Customization 3 - Font and Color Pickers Developer Guide ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/017-style-customization-2-the-customization-popup/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 7: Style Form\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/uYCCbE70kE0?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the style form exists, the next design problem is deciding how customization should be presented. The popup approach in this lesson is a good answer because it keeps the editing UI close to the thing being edited and limits the choices to what actually makes sense for that element.\u003c/p\u003e","title":"Style Customization 2 - The Customization Popup"},{"content":" Module 6: Native Interfaces - Billing\nNative interfaces are most useful when the Java side stays small, deliberate, and easy to reason about. The mistake developers often make is trying to expose every detail of a native SDK directly into the portable layer. That usually creates a fragile API that mirrors platform quirks instead of hiding them.\nThis lesson starts from a payment use case and shows a better approach. Look at the native SDK first, identify the smallest set of information the Java layer truly needs, and then define a narrow native interface around that. In the billing example, most of the heavy lifting is already handled by the native SDK and by the server. The portable layer mainly needs a token and a way to receive the outcome.\nThe callback part is where the design gets interesting. Native SDKs often return results asynchronously, but Codename One native interfaces cannot simply accept arbitrary Java callback objects in every situation. That constraint means you need a bridging strategy. In the older lesson that strategy uses static callback methods. The exact implementation detail can vary, but the underlying lesson is still right: the Java-facing API should absorb the awkward platform boundary so the rest of the application does not have to care about it.\nThat is also why the native interface itself should almost never be used directly from the UI or business layer. Wrap it in a plain Java abstraction. That wrapper can normalize differences between platforms, centralize fallback behavior, and keep the rest of the codebase isolated from native-specific edge cases.\nThe video uses Braintree as the concrete example, but there is an important modern note here: when an official or maintained Codename One library already exists for an integration, prefer that over re-creating the binding yourself. Native interface work is still valuable to understand, and sometimes you do need it for unsupported features, but it should not be the first choice when a stable library already covers the problem.\nSo the real takeaway from this lesson is not \u0026ldquo;copy this payment bridge.\u0026rdquo; It is \u0026ldquo;design the narrowest native boundary you can, then wrap it so the application talks to a clean Java API instead of a pile of platform details.\u0026rdquo;\nFurther Reading Developer Guide How Do I Access Native Device Functionality, Invoke Native Interfaces How Do I Use The Include Sources Feature To Debug The Native Code On iOS/Android ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/017-the-native-interface-callback/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 6: Native Interfaces - Billing\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/jVuNrLw4e-A?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eNative interfaces are most useful when the Java side stays small, deliberate, and easy to reason about. The mistake developers often make is trying to expose every detail of a native SDK directly into the portable layer. That usually creates a fragile API that mirrors platform quirks instead of hiding them.\u003c/p\u003e","title":"The Native Interface Callback"},{"content":" Module 6: Native Interfaces - Billing\nMost native integrations fail before the first line of native code ever runs. The usual problem is dependency setup: the Java wrapper may be correct, but the native platform build is missing the SDK, targeting the wrong platform level, or pulling in conflicting configuration.\nThat is why dependency handling deserves its own lesson. On Android, third-party native SDKs usually arrive through Gradle coordinates. On iOS, they often arrive through CocoaPods. Codename One sits above those build systems, so the practical question becomes how to express those native dependencies in a way the platform builds can consume.\nThe older lesson focuses heavily on Braintree-specific build hints and version mismatches. The specific versions in that video are no longer the important part. What still matters is the troubleshooting pattern. When a native dependency fails to build, look for the first meaningful error, not the giant wall of build-tool stack trace below it. Most of the time the real issue is a platform-level mismatch such as minimum SDK version, deployment target, or an incompatible transitive dependency.\nThis is also one of the places where modern Codename One development is easier if you stay disciplined. Keep build hints explicit, document why they are needed, and prefer maintained integrations when available. If an old lesson suggests unpacking and editing a library artifact by hand, treat that as a temporary workaround from another era, not as a normal workflow. Today the better approach is usually to fix the library, update the dependency declaration, or isolate the workaround in a clearly documented build step.\nNative dependency management is not glamorous, but it is part of the cost of crossing the platform boundary. If you understand that Gradle and CocoaPods are simply the native package managers on the other side of your Codename One build, the problem becomes much easier to reason about.\nFurther Reading Developer Guide How Do I Access Native Device Functionality, Invoke Native Interfaces How Do I Get Repeatable Builds, Build Against A Consistent Version Of Codename One \u0026amp; Use The Versioning Feature ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/018-dependencies-gradle-and-cocoapods/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 6: Native Interfaces - Billing\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/d1T25sbFUKE?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eMost native integrations fail before the first line of native code ever runs. The usual problem is dependency setup: the Java wrapper may be correct, but the native platform build is missing the SDK, targeting the wrong platform level, or pulling in conflicting configuration.\u003c/p\u003e","title":"Dependencies - Gradle and CocoaPods"},{"content":" Module 7: Style Form\nColor and font controls are where a style editor can become either empowering or exhausting. This lesson stays on the right side of that line by keeping the tools practical rather than pretending to be a full professional design suite.\nThe color picker works because it balances directness with precision. Sliders give users a tactile way to explore, while the hex value keeps the result grounded in something explicit and reusable. That combination is usually enough for a product builder. Most users do not need a huge color science interface. They need a reliable way to land on a good color and see it applied immediately.\nThe font picker is harder because typography is harder. Fonts carry meaning, hierarchy, tone, and readability concerns all at once, and they are not equally well supported across every target environment. The lesson’s constrained approach is therefore the right one. Offer a smaller, portable subset of choices and make sure the preview reflects the real result as closely as possible.\nOne of the most useful implementation ideas in this lesson is the care taken to avoid accidental feedback loops between controls. Any time you have multiple inputs representing the same value, the UI needs to update cohesively without endlessly retriggering itself. That sounds mechanical, but it is part of making customizer tools feel solid.\nSo the real product lesson here is that builder controls should be expressive enough to be useful and narrow enough to stay trustworthy. A constrained but dependable color or font picker is better than a theoretically unlimited one that behaves inconsistently across the generated apps.\nFurther Reading Style Customization 2 - The Customization Popup Themeing Working With CSS ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/018-style-customization-3-font-and-color-pickers/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 7: Style Form\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/ZzSCPcnFkxs?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eColor and font controls are where a style editor can become either empowering or exhausting. This lesson stays on the right side of that line by keeping the tools practical rather than pretending to be a full professional design suite.\u003c/p\u003e\n\u003cp\u003eThe color picker works because it balances directness with precision. Sliders give users a tactile way to explore, while the hex value keeps the result grounded in something explicit and reusable. That combination is usually enough for a product builder. Most users do not need a huge color science interface. They need a reliable way to land on a good color and see it applied immediately.\u003c/p\u003e","title":"Style Customization 3 - Font and Color Pickers"},{"content":" Module 7: Style Form\nCustomization is only useful if it survives. Once users start shaping the look of a generated app, those choices need to exist as real data, not just as temporary UI state.\nThat is what this lesson is about. Style settings become first-class business data: something that can be stored locally, synchronized with the server, and reapplied later. That is the right abstraction for a builder product because appearance is part of the product definition, not just a visual side effect of the current screen.\nThe important architectural move here is turning style changes into structured objects rather than scattered theme tweaks. Once styles are represented as data, the rest of the system can reason about them the same way it reasons about titles, dishes, prices, or other editable entities.\nThis also connects back to the earlier product decisions about temporary versus committed edits. A user can experiment locally, but once they confirm the changes, those changes need to be durable. That durability is what makes the builder trustworthy across sessions and eventually across devices or server sync.\nSo the final lesson in this style-customization block is straightforward but important: styling in a builder is not just presentation logic. It is part of the editable domain model.\nFurther Reading Style Customization 1 - Introduction and Basics SQLite Abstraction with Object Relational Mapping Billing and Global Server ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/019-style-customization-4-saving-style-settings/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 7: Style Form\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/Wiy2goFwfQA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eCustomization is only useful if it survives. Once users start shaping the look of a generated app, those choices need to exist as real data, not just as temporary UI state.\u003c/p\u003e\n\u003cp\u003eThat is what this lesson is about. Style settings become first-class business data: something that can be stored locally, synchronized with the server, and reapplied later. That is the right abstraction for a builder product because appearance is part of the product definition, not just a visual side effect of the current screen.\u003c/p\u003e","title":"Style Customization 4 - Saving Style Settings"},{"content":" Module 6: Native Interfaces - Billing\nOnce the interface shape is settled and the native dependencies are in place, the remaining job is to implement the platform code without letting threading, lifecycle, and callback mechanics turn the integration into a black box.\nThe most practical advice in the lesson is still the best advice today: if the integration is non-trivial, generate native sources and inspect the result in the platform IDE. That gives you real build feedback, better navigation, and a much easier debugging path than trying to reason about everything from the portable project alone. The include sources workflow is still the right tool for that job.\nThe Android and iOS implementations shown here look different, but the conceptual structure is the same. Marshal arguments from the Java side into the native SDK, run on the thread the native platform expects, receive the native callback, and then bridge the result back into the portable layer in a controlled way. Once you view native integration through that lens, the platform syntax becomes less intimidating.\nThreading deserves special attention. The Codename One EDT is not the same thing as the native platform UI thread. That difference matters because many native SDKs assume they are being called from the platform\u0026rsquo;s own event thread. If you ignore that boundary, integrations can fail in ways that look random but are really just threading mistakes.\nThis lesson also helps demystify the uglier parts of native stubs, especially on iOS where generated method names and VM bridge calls can look hostile at first glance. The important point is that most of the ugliness lives at the boundary. Your application code should not have to see it. That is another reason the wrapper layer matters.\nSo the modern version of this advice is: prototype in the native IDE when needed, keep the native code narrow, respect thread boundaries, and translate results back into a clean Java-facing API. That is how native integrations stay maintainable instead of becoming permanent fear zones in the project.\nFurther Reading Developer Guide How Do I Access Native Device Functionality, Invoke Native Interfaces How Do I Use The Include Sources Feature To Debug The Native Code On iOS/Android Threading and the EDT ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/019-the-native-code/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 6: Native Interfaces - Billing\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/swgT_aDsv3U?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the interface shape is settled and the native dependencies are in place, the remaining job is to implement the platform code without letting threading, lifecycle, and callback mechanics turn the integration into a black box.\u003c/p\u003e\n\u003cp\u003eThe most practical advice in the lesson is still the best advice today: if the integration is non-trivial, generate native sources and inspect the result in the platform IDE. That gives you real build feedback, better navigation, and a much easier debugging path than trying to reason about everything from the portable project alone. The \u003ca href=\"/how-do-i/how-do-i-use-the-include-sources-feature-to-debug-the-native-code-on-iosandroid-etc/\"\u003einclude sources\u003c/a\u003e workflow is still the right tool for that job.\u003c/p\u003e","title":"The Native Code"},{"content":" Module 7: Native Interfaces - Camera\nCamera integrations are a good example of why native interfaces need design, not just implementation. If you begin by copying every method from a platform SDK into your portable API, you usually end up with an awkward abstraction that is too platform-specific to be pleasant and too incomplete to be reliable.\nThis lesson takes the more useful route: study the native APIs, decide what the portable layer actually needs, and then shape a Codename One-facing API around that. In the original material, the portable surface is influenced heavily by an Android camera library. That is a reasonable way to get traction, but the deeper lesson is that the portable API should be owned by your application or library, not by whichever native SDK you happened to read first.\nThe wrapper class is crucial here. The raw native interface should remain a thin bridge, while the public Java API becomes the place where you handle defaults, constants, event listener management, simulator behavior, and build-hint concerns. That separation gives you the freedom to improve the native implementation later without breaking the rest of the app.\nThis is also where you can see why native interfaces are not a good place to expose callback-heavy behavior directly. Some platform APIs are naturally event-driven, but the portable layer still needs to present those events in a way that fits Codename One. Listener registration, singleton behavior, and platform capability checks all belong in the wrapper, not scattered around the app.\nOne modern point worth stating explicitly: if there is already a maintained Codename One camera library that covers the use case you need, prefer that first. This lesson is still valuable because it teaches how to think about a difficult native integration, but hand-rolling a bridge should usually be reserved for unsupported features, experiments, or library work.\nFurther Reading Developer Guide How Do I Access Native Device Functionality, Invoke Native Interfaces How Do I Take A Picture With The Camera ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/020-introduction-and-generic-code/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 7: Native Interfaces - Camera\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/Mcw8z_uP3BA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eCamera integrations are a good example of why native interfaces need design, not just implementation. If you begin by copying every method from a platform SDK into your portable API, you usually end up with an awkward abstraction that is too platform-specific to be pleasant and too incomplete to be reliable.\u003c/p\u003e","title":"Introduction and Generic Code"},{"content":" Module 8: Push and In-App Purchase\nPush usually feels harder than it really is because the setup is split across several systems. You need Android-side configuration, iOS-side configuration, and project settings that tell Codename One how those pieces fit together. Once that groundwork is done, the rest of the push flow is much easier to understand.\nOn Android, the core job is to register the app with Google\u0026rsquo;s push infrastructure and copy the sender information back into the project. The video uses the old Google Cloud Messaging terminology. Today the equivalent work is done through Firebase Cloud Messaging, but the role of the value is the same: Android needs to know which sender the application belongs to so it can receive notifications correctly.\nIn Codename One, that sender information ends up in the project configuration as a build hint. The video shows the legacy settings and plugin-based workflow, which is now out of date. In a modern Maven-based project you still provide the same information, but you manage the project through Maven and the current Codename One configuration flow instead of relying on the old IDE plugin setup.\nThe Android step is the easier half. iOS is where push becomes certificate-driven. Push on iOS does not just reuse your normal signing setup. It requires push-enabled certificates and provisioning profiles that match the app. That is why the original lesson spends so much time on the certificate wizard.\nOne warning from the video is still very important: if you already have working certificates, do not revoke them casually just because a wizard offers that option. Replacing or revoking an existing certificate can break other apps that depend on it. If this is your first push-enabled setup, generate what you need. If you already have a valid certificate chain, reference and reuse the existing material instead of resetting it blindly.\niOS also separates development and production push environments. A debug build installed directly on a device is not the same thing as a production build distributed through the App Store, and the push credentials need to match that distinction. If push works in one environment but not the other, this mismatch is one of the first things to check.\nOnce the iOS setup is complete, Codename One gives you the cloud certificate URLs and related values that the server side will later need when it sends notifications. Keep those values somewhere safe. They are not part of client registration, but they are essential later when the app server needs to deliver a push to a device.\nAt this stage, the goal is not to send a notification yet. The goal is to leave the project correctly identified on Android, correctly provisioned on iOS, and ready for the client and server code in the next lessons.\nFurther Reading Push 2 - Client Side Code Push 3 - The Server Side and Build Logic Push Notifications Build Hints ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/020-push-1-initial-registration-process/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 8: Push and In-App Purchase\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/SBqYZSdIdec?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003ePush usually feels harder than it really is because the setup is split across several systems. You need Android-side configuration, iOS-side configuration, and project settings that tell Codename One how those pieces fit together. Once that groundwork is done, the rest of the push flow is much easier to understand.\u003c/p\u003e","title":"Push 1 - Initial Registration Process"},{"content":" Module 7: Native Interfaces - Camera\nOnce the portable camera API exists, the Android side becomes a matter of mapping that API onto the native implementation without letting threading, lifecycle, and dependency details escape into the rest of the app.\nThe lesson\u0026rsquo;s most practical recommendation is still correct: if you are new to native integration, generate native sources and work in Android Studio while developing the Android side. That gives you real tooling support, native compilation feedback, and a much faster path to understanding what the platform expects.\nThe Android implementation itself is conceptually straightforward. Hold onto the preview view, forward configuration calls to the native camera component, and make sure the operations that need the Android UI thread are dispatched there. The syntax may be verbose, but the pattern is simple: Codename One asks for behavior, the bridge translates that into the Android library\u0026rsquo;s calls, and results are pushed back into the portable layer.\nThe threading boundary matters here just as much as it did in the billing example. Some getter-like operations are harmless, but start, stop, capture, and view-related behavior often need to run on the native Android UI thread. If that distinction is blurred, camera code tends to fail in ways that are difficult to diagnose.\nThe other part of this lesson is build configuration. Native Android integrations frequently depend on Gradle artifacts, ProGuard or R8 rules, SDK levels, and other platform-specific settings. The exact versions in the older video are historical now, but the lesson remains current: camera integrations are often as much about satisfying native build expectations as they are about writing bridge code.\nSo the Android side is not just \u0026ldquo;translate methods one by one.\u0026rdquo; It is \u0026ldquo;translate the API, honor the Android lifecycle and thread model, and make the build aware of the native library\u0026rsquo;s requirements.\u0026rdquo;\nFurther Reading Developer Guide How Do I Access Native Device Functionality, Invoke Native Interfaces How Do I Use The Include Sources Feature To Debug The Native Code On iOS/Android ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/021-implementing-the-native-camera-on-android/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 7: Native Interfaces - Camera\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/16-Vkgcx2kg?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the portable camera API exists, the Android side becomes a matter of mapping that API onto the native implementation without letting threading, lifecycle, and dependency details escape into the rest of the app.\u003c/p\u003e\n\u003cp\u003eThe lesson\u0026rsquo;s most practical recommendation is still correct: if you are new to native integration, generate native sources and work in Android Studio while developing the Android side. That gives you real tooling support, native compilation feedback, and a much faster path to understanding what the platform expects.\u003c/p\u003e","title":"Implementing the Native Camera on Android"},{"content":" Module 8: Push and In-App Purchase\nOnce the platform setup is done, the client side of push becomes a lifecycle problem. The app needs to register when it starts, store the push key when registration succeeds, and react sensibly when a message arrives.\nThe first thing to get right is where the callback lives. In Codename One, push callbacks belong in the main application class, the one that owns init() and start(). That is not just convention. Push is tied to the application lifecycle, so the framework expects the callback implementation to live in the object that represents that lifecycle.\nRegistration should happen every time the app runs. The video mentions that registerPush() had changed and no longer needed the old extra arguments, and that is still the modern direction. The registration call itself is simple. The useful information arrives later through the callback flow.\nWhen registration succeeds, the app can obtain the actual push key and send it to the server. That is the value the server needs if it wants to target this device later. One of the easiest mistakes here is confusing the native device identifier with the push token. They are not interchangeable. If the server is going to send a push notification, it needs the push key.\nReceiving a push is a little subtler than many developers expect. Push is not a guaranteed background RPC channel. If the app is running, the callback can handle the message directly. If the app is not running, behavior depends on the platform and on the push type. That is why this lesson routes the incoming notification into a shared onBuildResult() path instead of putting all the business logic inside the push callback itself.\nThat is still the right design. Push should act as a signal that new work is available. The actual business logic, such as downloading a built artifact or refreshing state, should live in ordinary application code that can also be triggered by fallback transports.\nThe different push types matter mostly because they influence how much information reaches the app and when. A visible push is useful when the user needs to see a notification. An invisible push can sometimes be used as a signal, but it is not a good foundation for general networking logic. The mixed approach shown in the lesson is the pragmatic one: send a human-readable notification and include a machine-readable payload the app can act on.\nIn the original code that payload is a URL. That is perfectly reasonable. It could just as well be JSON or another structured message format. What matters is that the app can distinguish between text that is just meant for the user and data that should trigger behavior.\nThe lesson also touches on registration failures, and that part is worth updating. A failed registration should usually be logged and reflected in app state, not shown as an alarming early-launch toast. Some environments will never produce a perfectly clean failure signal, which is exactly why the rest of the module introduces HTTP and WebSocket fallbacks. A production app should keep working even when push is unavailable.\nFurther Reading Push 1 - Initial Registration Process Push 3 - The Server Side and Build Logic Push WebSockets Fallback Push Notifications ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/021-push-2-client-side-code/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 8: Push and In-App Purchase\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/BwWhFcHc6LM?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the platform setup is done, the client side of push becomes a lifecycle problem. The app needs to register when it starts, store the push key when registration succeeds, and react sensibly when a message arrives.\u003c/p\u003e\n\u003cp\u003eThe first thing to get right is where the callback lives. In Codename One, push callbacks belong in the main application class, the one that owns \u003ccode\u003einit()\u003c/code\u003e and \u003ccode\u003estart()\u003c/code\u003e. That is not just convention. Push is tied to the application lifecycle, so the framework expects the callback implementation to live in the object that represents that lifecycle.\u003c/p\u003e","title":"Push 2 - Client Side Code"},{"content":" Module 7: Native Interfaces - Camera\nThe iOS side of a camera integration tends to look more intimidating than the Android side because the API surface is different and the generated bridge code is less familiar to most Java developers. The right way to handle that is not to memorize every Objective-C detail. It is to understand the moving parts well enough to see where the bridge is actually doing work.\nAt a high level, the iOS port needs to manage three things: permission, session lifecycle, and preview presentation. If those three are under control, the rest of the integration becomes a matter of mapping options and forwarding events.\nPermission comes first. Camera access on iOS is tightly controlled, so the bridge must request it correctly and the app must declare the right usage description. Without that, nothing else matters. This is one of the places where the wrapper layer again proves its value, because it can ensure required build hints and usage strings are present instead of expecting every application author to remember them manually.\nAfter permission, the capture session becomes the center of the native implementation. The port needs to initialize the right camera device, create or resume the session, attach the preview layer to a view, and handle stop/start cycles cleanly. These details may feel low-level, but they are the heart of what the user experiences as \u0026ldquo;the camera preview just works.\u0026rdquo;\nThe preview itself is another good reminder that peer components and native views need careful treatment. The portable side wants something that can be embedded in a Codename One form. The native side wants to manage a real UIKit view and camera layer. The bridge exists to reconcile those expectations cleanly.\nSo the lesson here is not about becoming an iOS media expert overnight. It is about recognizing the responsibilities of the native bridge: request permission, initialize the native camera system, expose a preview surface that the portable layer can host, and keep the lifecycle predictable. Once that model is clear, the Objective-C syntax stops being the scary part.\nFurther Reading Developer Guide How Do I Access Native Device Functionality, Invoke Native Interfaces How Do I Use The Include Sources Feature To Debug The Native Code On iOS/Android ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/022-camera-ios-port-basics/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 7: Native Interfaces - Camera\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/17ISIksjcPM?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe iOS side of a camera integration tends to look more intimidating than the Android side because the API surface is different and the generated bridge code is less familiar to most Java developers. The right way to handle that is not to memorize every Objective-C detail. It is to understand the moving parts well enough to see where the bridge is actually doing work.\u003c/p\u003e","title":"Camera iOS Port Basics"},{"content":" Module 8: Push and In-App Purchase\nOn the server side, push is part of the result-delivery pipeline. The build finishes, the server decides what happened, and then it sends a short notification to the device so the app can react.\nThat framing matters because this lesson is not really about building a generic push utility. It is about closing the loop in a product where the server builds an app on behalf of the user and needs a clean way to report the result back to the device.\nThe first practical concern is credential management. The server needs Codename One push credentials, Android server-side credentials, and iOS push certificate information. The original lesson stores these values in a local properties file instead of hard-coding them into source. That is still the right approach. Secrets and environment-specific configuration should live outside application code so they can be rotated and deployed safely.\nThe second concern is the build mode itself. The lesson uses a synchronous automated build flow so the server can wait for the result, inspect the generated artifacts, and decide what message to send. That works well for this kind of product because a build request is not fire-and-forget. The user expects a concrete answer: success, failure, and where the result can be downloaded.\nOnce the build is complete, the push itself is conceptually simple. The server posts to the Codename One push service with the device key and the credentials needed for the target platforms. In this app the message includes both a visible notification for the user and a machine-readable payload for the client code. That makes the notification useful immediately while still giving the app enough information to continue the flow automatically.\nThat mixed-message approach is one of the better ideas in this module. Push is used for what it is good at: signaling a state change and drawing attention to something that is ready. The real work, such as downloading or opening the generated result, still happens in normal application logic where it can be validated and retried.\nThe iOS warning from the video also deserves to survive in updated form. Development and production push environments are different, and they do not share credentials. A debug build installed directly on a device is not the same thing as a production build distributed through the App Store. If push works in one environment and fails in the other, mismatched certificates or environment configuration are a likely cause.\nFinally, log the push response on the server. Even in a small project, delivery failures are much easier to diagnose when the server records what it attempted to send, which credentials were used, and what response came back from the push service.\nFurther Reading Push 1 - Initial Registration Process Push 2 - Client Side Code Push Notifications In-App Purchase ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/022-push-3-the-server-side-and-build-logic/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 8: Push and In-App Purchase\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/qaYExTzcCVY?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOn the server side, push is part of the result-delivery pipeline. The build finishes, the server decides what happened, and then it sends a short notification to the device so the app can react.\u003c/p\u003e\n\u003cp\u003eThat framing matters because this lesson is not really about building a generic push utility. It is about closing the loop in a product where the server builds an app on behalf of the user and needs a clean way to report the result back to the device.\u003c/p\u003e","title":"Push 3 - The Server Side and Build Logic"},{"content":" Module 7: Native Interfaces - Camera\nOnce the basic iOS camera bridge exists, the next challenge is not a new feature so much as learning how the native view and native memory model affect the implementation. This is where the integration stops being a thin method mapping and starts feeling like real platform work.\nThe first important piece is the preview view itself. Codename One needs a peer component it can host inside a form, while iOS needs a real UIView whose internal preview layer stays aligned with that view\u0026rsquo;s bounds. That sounds simple, but it is exactly the kind of detail that makes or breaks a native camera preview. If the view moves and the preview layer does not track it correctly, the bridge may compile fine and still behave badly on screen.\nThe second important piece is object lifetime. The older lesson spends time on ARC and reference counting because iOS memory management cannot simply be ignored when bridging a Java runtime to native objects. You do not need to become an expert in every detail of Objective-C memory semantics, but you do need to understand the practical implication: when the bridge recreates or replaces native camera objects, their lifecycle has to be handled intentionally.\nThat is also why operations such as changing the active camera, updating zoom, or reconfiguring focus can feel more invasive on iOS than they do at first glance. Some updates are cheap. Others effectively require tearing down and rebuilding parts of the camera session. The bridge has to hide that complexity from the portable layer without pretending it does not exist.\nThe focus and zoom examples in the lesson are still useful because they show the real pattern of native camera integration: acquire the right native state, translate a portable intent into a platform-specific action, and update the native session safely. The bridge is not just a pipe. It is a compatibility layer that owns those translations.\nSo the point of this lesson is not really ARC trivia for its own sake. It is understanding that on iOS, view embedding, session reconfiguration, and object lifetime are part of the contract of a usable camera bridge. Once you accept that, the implementation becomes much easier to reason about.\nFurther Reading Developer Guide How Do I Access Native Device Functionality, Invoke Native Interfaces Camera iOS Port Basics ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/023-arc-and-view-on-ios/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 7: Native Interfaces - Camera\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/7G4OkjgTWIQ?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the basic iOS camera bridge exists, the next challenge is not a new feature so much as learning how the native view and native memory model affect the implementation. This is where the integration stops being a thin method mapping and starts feeling like real platform work.\u003c/p\u003e","title":"ARC and View on iOS"},{"content":" Module 8: Push and In-App Purchase\nPush is useful, but it should never be the only transport a feature depends on. Users can disable it, devices can fail to register, and platform delivery is not reliable enough to be the single mechanism that keeps an app functional.\nThat is why this lesson adds an HTTP fallback. It is not elegant, but it is dependable and easy to understand. The server stores the latest build result somewhere the client can fetch it later, and the client polls only when push is unavailable.\nIn this app the existing restaurant entity is used as a convenient place to store the most recent build result. That is a pragmatic choice. The app already has a server-side record for the current builder state, so attaching the latest build status to that record avoids introducing extra infrastructure just to support a fallback notification path.\nOn the client side, the logic is simple and that simplicity is a strength. If push registration succeeded and the app has a usable push key, push remains the preferred notification mechanism. If not, the client periodically sends a normal HTTP request until the server reports a changed result.\nThat is the right priority order. Push gives a better user experience, but HTTP polling is easier to reason about and easier to debug. The important thing is that both paths eventually call into the same result-handling code. The transport changes, but the meaning of the result does not.\nThis is also a good example of a broader rule in mobile development: if an event-driven channel is optional, always keep a plain request-response path available. It may be slower and less efficient, but it prevents an entire feature from failing just because one delivery mechanism is missing.\nThe video correctly presents polling as a fallback rather than the ideal design. Polling creates unnecessary traffic and introduces delay because the client only learns about changes on the next timer tick. It is acceptable as a safety net, but not as the best long-term solution. The next lesson shows how WebSockets provide a cleaner event-driven fallback when you want real-time updates without relying on push.\nFurther Reading Push 2 - Client Side Code Push WebSockets Fallback Connecting to a Web Service How Do I Use HTTP, Sockets, Webservices \u0026amp; WebSockets ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/023-push-http-fallback/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 8: Push and In-App Purchase\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/VDyltmk_Hu8?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003ePush is useful, but it should never be the only transport a feature depends on. Users can disable it, devices can fail to register, and platform delivery is not reliable enough to be the single mechanism that keeps an app functional.\u003c/p\u003e","title":"Push Http Fallback"},{"content":" Module 7: Native Interfaces - Camera\nThe last part of the iOS camera work is where the bridge becomes truly useful: still capture, video capture, and the callback path back into the portable layer. Once those are in place, the camera integration stops being a preview widget and becomes a working feature.\nThe main challenge here is not just calling the native capture APIs. It is doing so on the right thread, with the right delegate or callback setup, and then translating the result into something the Java side can consume. That is the part developers often find intimidating, but the underlying pattern is consistent: start native work, let the native API complete asynchronously, then convert the result into the portable representation you want.\nStill image capture is often more complicated than expected because platform APIs evolve over time and older iOS versions may require a different path from newer ones. The specifics in the video are tied to that era of iOS, but the general lesson is still current: camera integrations often need version-aware code paths, and a bridge must isolate that complexity so the portable API remains stable.\nVideo capture tends to be easier conceptually because the lifecycle is clearer: start recording, receive the completion callback, stop recording, then hand the resulting path or media object back to the Java side. Even there, though, the important part is not the one method call. It is the callback contract between native completion and portable code.\nThis lesson also reinforces why patience matters more than heroics in native work. Most of the code is not brilliant. It is procedural, repetitive, and specific. The value comes from keeping the bridge narrow enough that all of that platform-specific detail remains confined to one place instead of leaking into the application.\nFurther Reading Developer Guide How Do I Access Native Device Functionality, Invoke Native Interfaces How Do I Use The Include Sources Feature To Debug The Native Code On iOS/Android ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/024-capture-and-callbacks-in-ios/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 7: Native Interfaces - Camera\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/MbTEz-K8iwY?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe last part of the iOS camera work is where the bridge becomes truly useful: still capture, video capture, and the callback path back into the portable layer. Once those are in place, the camera integration stops being a preview widget and becomes a working feature.\u003c/p\u003e","title":"Capture and Callbacks in iOS"},{"content":" Module 8: Push and In-App Purchase\nIf HTTP polling is the safety net, WebSockets are the more polished fallback. They preserve the event-driven feel of push without depending on the mobile push infrastructure, which makes them a good fit for workflows like build completion, job status changes, and other lightweight live updates.\nThe reason WebSockets work well here is simple. After the connection is established, the server can push short messages back to the client immediately. That avoids the repeated request loop of polling and gives the app a much more direct way to learn that something changed.\nThe comparison in the video between HTTP, raw sockets, and WebSockets is still useful. HTTP is excellent for normal request-response operations and large payloads, but it is wasteful when the client keeps asking whether anything has changed. Raw sockets are powerful but awkward to operate through common web infrastructure. WebSockets sit in the middle: they begin as ordinary web traffic, then remain open so client and server can exchange small messages efficiently.\nOn the client side, the structure is straightforward. Open the WebSocket connection, wait until the connection is actually open, send whatever identifying information the server needs, and then react to incoming messages. In this app that identifying information is the restaurant secret, which allows the server to bind the socket to the correct builder session.\nThat sequencing matters. One easy mistake with asynchronous communication is assuming the socket is ready immediately after construction. It is not. The handshake has to complete first, which is why the first outgoing message belongs in the onOpen callback instead of immediately after creating the object.\nIncoming messages can then be routed into the same result-processing code used by push and HTTP fallback. That reuse is the strongest part of the design. WebSockets change how the notification arrives, but they do not change what the notification means.\nThe server side is where WebSockets become architectural rather than just mechanical. The app needs a handler for the WebSocket endpoint, a way to associate each open connection with the right logical user or restaurant, and a way for the rest of the server code to find that connection when an asynchronous event finishes. The lesson uses a shared map keyed by the restaurant secret to do exactly that.\nThe implementation shown in the video is intentionally pragmatic and not especially scalable. That is fine for understanding the pattern. The idea to keep is not the exact static-field implementation. The important part is the binding step: when the client opens the socket, the server records which logical entity that connection belongs to so later server-side work can publish a message to the right place.\nThe video also shows WebSocket support being installed through the old settings UI as a CN1Lib. That workflow is outdated now. In a modern Maven-based Codename One project, dependency management should live in Maven rather than in the legacy extension flow.\nFurther Reading Push Http Fallback How Do I Use HTTP, Sockets, Webservices \u0026amp; WebSockets Connecting to a Web Service Push Notifications ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/024-push-websockets-fallback/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 8: Push and In-App Purchase\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/FSek5IOQ0IE?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eIf HTTP polling is the safety net, WebSockets are the more polished fallback. They preserve the event-driven feel of push without depending on the mobile push infrastructure, which makes them a good fit for workflows like build completion, job status changes, and other lightweight live updates.\u003c/p\u003e","title":"Push WebSockets Fallback"},{"content":" Module 8: Putting it All Together\nFinishing an application is usually less about adding one big feature than about making a lot of practical decisions that keep the product moving. This lesson starts that final assembly process by focusing on the network layer and on one of the most important development skills in product work: defining a finish line and refusing to keep expanding it.\nOn the technical side, the service layer in this lesson is built around a useful principle for mobile apps: load from local state first when you can, then refresh from the server. That makes the application feel responsive, reduces the cost of repeated launches, and gives the user something to look at immediately instead of forcing every cold start to wait on the network.\nThe caching approach in the older lesson is intentionally simple. The app stores the server\u0026rsquo;s JSON payload locally, reloads it into the model on startup, and then asks the server whether the data has changed. That is not a full offline-sync system, but it is a strong practical baseline for many applications because it keeps startup fast without hiding the fact that the server remains the source of truth.\nThe other important design choice is where UI updates occur. The code uses the network layer for transport, the model layer for decoded data, and the EDT for visible updates. That separation matters. Once network completion and UI refresh logic start blurring together, responsiveness and maintainability both suffer.\nThis lesson also makes a valuable product point: finishing requires discipline. There is always another improvement to make. There is always one more feature that would be nice. If you never constrain the scope, the app never reaches the stage where real users can react to it. A modest but working feature set is often far more valuable than an endlessly expanding plan.\nSo the practical outcome here is a network layer with sane caching, timestamp-based refresh logic, and a UI that reacts when data arrives. Just as importantly, it is a reminder that \u0026ldquo;good enough to ship\u0026rdquo; is often a more important milestone than \u0026ldquo;still theoretically improvable.\u0026rdquo;\nFurther Reading Connecting to a Web Service Threading and the EDT How Do I Access Remote Webservices, Perform Operations On The Server ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/025-communicating-with-the-server/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 8: Putting it All Together\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/LUHb5fuWzJE?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eFinishing an application is usually less about adding one big feature than about making a lot of practical decisions that keep the product moving. This lesson starts that final assembly process by focusing on the network layer and on one of the most important development skills in product work: defining a finish line and refusing to keep expanding it.\u003c/p\u003e","title":"Communicating with the Server"},{"content":" Module 8: Push and In-App Purchase\nIn-app purchase is one of those features where the code is usually easier than the store setup. Apple and Google own the payment flow, product definitions, pricing, refunds, and approval rules. Your app mostly needs to define what is being sold and decide what to unlock when a purchase succeeds.\nThat store ownership is not just convenient. For digital goods and in-app features, it is often a platform requirement. If the user is buying something that exists inside the app experience, the stores generally expect that transaction to go through their billing system rather than through a custom payment form.\nIn this project, the purchase flow is tied directly to the build workflow. The user chooses a build target, buys that build if necessary, and then the normal build process continues. That is a sensible product design because the purchase does not create a separate mini-application inside the app. It simply unlocks the next step the user was already trying to perform.\nLike push, purchase callbacks belong in the main application class. The app starts a purchase, waits for the store result, and then handles success, failure, cancellation, or refund through the appropriate callback methods. The most important callback is the successful purchase event, which includes the SKU of the item that was bought.\nThe SKU is the bridge between store configuration and application logic. You define it in App Store Connect or Google Play Console, and the app uses it to decide what the purchase means. Once you have more than one purchasable item, that mapping becomes the heart of your purchase logic.\nThe lesson keeps the client-side code intentionally small: present a purchase choice, start the purchase, and continue into the pending build flow once the store confirms success. That is the right scope. Most of the complexity in in-app purchase is not in the callback methods. It is in product configuration, testing, and making sure the entitlement model is correct.\nThe warnings about store policy from the video are still worth taking seriously. Apple in particular is strict about in-app purchase rules, and review feedback can be broader than many developers expect. If a reviewer believes something inside the app experience should be sold through store billing, you should assume they may challenge any alternative payment path.\nThe exact screens shown in the video are dated now, but the overall store workflow has not really changed. You create the product, assign its SKU, give it display text and pricing, and make sure the application uses the same SKU constants when purchase callbacks arrive.\nFurther Reading Push 3 - The Server Side and Build Logic Billing and Global Server In-App Purchase What Is Codename One ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/025-in-app-purchase/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 8: Push and In-App Purchase\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/uvQKs_PdB64?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eIn-app purchase is one of those features where the code is usually easier than the store setup. Apple and Google own the payment flow, product definitions, pricing, refunds, and approval rules. Your app mostly needs to define what is being sold and decide what to unlock when a purchase succeeds.\u003c/p\u003e","title":"In-App Purchase"},{"content":" Module 8: Putting it All Together\nOrder flows are where attractive demos become real products. As soon as delivery is involved, the app needs to collect an address, remember it sensibly, and enforce the business rules that determine whether an order can actually be placed.\nThis lesson adds that missing layer. The address form itself is intentionally modest, which is fine. The important thing is not to over-design the input screen. It is to make the data collection predictable and easy to validate.\nThe older implementation uses explicit property binding code, and the video notes that newer APIs such as Instant UI would now be a more natural fit for some of this work. That is still the right modern guidance. If you are building a similar form today, use the current property-binding and form-generation tools where they simplify the code instead of re-implementing boilerplate by hand.\nThe validation logic is where this lesson becomes more than form wiring. Delivery range, minimum order value, and delivery fee are business rules, not presentation details. That means the UI should surface them clearly, but the application model should own them. Once those rules live in the right place, the rest of the checkout experience becomes more trustworthy because the app is enforcing real constraints instead of merely collecting text fields.\nLocation-aware validation is especially useful here. If the restaurant only serves users within a certain radius, the app should check that early enough to save frustration. The exact implementation can vary, but the principle is clear: validate the order against the real-world service boundary before the user gets all the way to submission.\nSo the key lesson is that checkout forms are not just a place to gather input. They are the point where UI, stored user data, and domain rules finally meet. That is why they deserve more care than a bare list of fields.\nFurther Reading Developer Guide How Do I Use Properties To Speed Development How Do I Access Native Device Functionality, Invoke Native Interfaces ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/026-address-and-validation/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 8: Putting it All Together\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/vOcKbbW9HBM?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOrder flows are where attractive demos become real products. As soon as delivery is involved, the app needs to collect an address, remember it sensibly, and enforce the business rules that determine whether an order can actually be placed.\u003c/p\u003e","title":"Address and Validation"},{"content":" Module 9: Setting Up a Cloud Server\nAt some point the app has to leave the laptop and run somewhere public. This module takes the deliberately pragmatic route: rent a small VPS, install what the backend needs, and get to a working deployment without pretending that this is a full course on cloud architecture.\nThat framing is still useful. A small VPS is often the right starting point for a real project because it keeps cost under control and forces you to understand the basic moving parts of your deployment. The lesson is not trying to design a globally distributed platform. It is trying to get a Java backend onto the internet in a way you can operate and afford.\nThe Spring Boot detail at the start is one of the best parts of the original lesson. Packaging the application so it behaves like an executable service on Linux makes the rest of the deployment story much simpler. Instead of treating the server as a special one-off machine where you run java -jar manually forever, you can integrate the app into the operating system like a real service.\nThe provider shown in the video is just an example. The important decision is the class of machine, not the brand. A modest Linux VPS is enough for many early deployments, and it avoids the trap of overbuilding infrastructure before the product has earned it.\nThe old lesson uses CentOS and walks through a root-first setup with a dedicated non-root builder user for normal work. The exact Linux distribution you choose today may differ, because the hosting and Linux ecosystem has moved on since the video was recorded, but the operational advice is still right. Use root sparingly, create a regular deployment user, and keep day-to-day work under that account so mistakes are less dangerous.\nThe JDK download discussion in the video is mostly historical now. The specific Oracle download friction it describes is not the interesting part anymore. The enduring lesson is that the server needs a predictable Java runtime and that you should install it in a way that is maintainable for your distribution and deployment process.\nThis setup step is intentionally unglamorous, but it matters. A backend deployment is not just code. It is an operating system, a runtime, an account model, a filesystem layout, and a plan for how the application will actually be started and updated.\nFurther Reading Yum, MariaDB, Security and iptables Starting the Server on Boot Introduction to Spring Boot Corporate Server ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/026-setting-up-the-vps-server/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 9: Setting Up a Cloud Server\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/PRk7EhXQRqs?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eAt some point the app has to leave the laptop and run somewhere public. This module takes the deliberately pragmatic route: rent a small VPS, install what the backend needs, and get to a working deployment without pretending that this is a full course on cloud architecture.\u003c/p\u003e","title":"Setting up the VPS Server"},{"content":" Module 8: Putting it All Together\nAs the menu grows, navigation becomes as important as presentation. A visually nice screen is not enough if users cannot narrow the list to what they want quickly. That is where category filtering and search start to matter.\nThe search approach in the older lesson is implemented manually even though Codename One has higher-level search toolbar support. That remains a useful teaching example because it exposes the moving parts: toggling the toolbar state, swapping in a text field, listening for changes, and filtering the visible content based on the underlying model.\nIn a modern application, the decision between a custom search interaction and a built-in search helper should be pragmatic. If the built-in mechanism now covers the behavior you want, use it. If you need custom behavior or a design-specific interaction, implement it intentionally rather than by accident. The lesson still helps because it shows what that custom implementation really requires.\nThe category filter and text search are also a good reminder that UI filtering works best when the model underneath is clean. If each dish entry carries the data the filter needs, the visible UI can be rebuilt or hidden based on that data without making the search code itself complicated.\nThe important product lesson here is that finishing the app does not mean ignoring discoverability. Small features like search and category selection often do more for everyday usability than another round of visual polish.\nFurther Reading How Do I Create A List Of Items The Easy Way Developer Guide Communicating with the Server ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/027-categories-and-search/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 8: Putting it All Together\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/GEG_S-dyxaM?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eAs the menu grows, navigation becomes as important as presentation. A visually nice screen is not enough if users cannot narrow the list to what they want quickly. That is where category filtering and search start to matter.\u003c/p\u003e\n\u003cp\u003eThe search approach in the older lesson is implemented manually even though Codename One has higher-level search toolbar support. That remains a useful teaching example because it exposes the moving parts: toggling the toolbar state, swapping in a text field, listening for changes, and filtering the visible content based on the underlying model.\u003c/p\u003e","title":"Categories and Search"},{"content":" Module 9: Setting Up a Cloud Server\nOnce the server exists, the next job is to make it useful. That means installing the packages the backend depends on, getting the database into a safe enough state for internet exposure, and making sure the application can be reached through the usual HTTP and HTTPS ports.\nThe video uses the package tools and service layout of its Linux distribution, and those exact commands are now more dated than the underlying ideas. What still matters is the sequence: install only what the app genuinely needs, understand why each dependency is there, and enable the pieces that must survive a reboot.\nOne of the more interesting details in this lesson is the use of a virtual framebuffer. That solves a real deployment problem for Java applications that occasionally need graphical capabilities on a headless server. If part of your build or asset pipeline relies on Java2D or other GUI-linked code, a headless Linux box can fail in surprising ways unless you provide an off-screen display environment.\nThe database step is less subtle but more important. Installing MariaDB or another compatible database engine is only the beginning. The real work is hardening it: removing unsafe defaults, setting credentials intentionally, and deciding whether remote database access should exist at all. In many small deployments, the safest default is to keep the database private to the server and administer it through SSH rather than by opening it broadly to the internet.\nThe lesson also uses port redirection so the backend can listen on higher application ports while the machine still exposes standard web ports such as 80 and 443. The exact firewall or proxy mechanism may differ in a modern deployment, but the reason for it is unchanged. Users and clients expect web services on standard ports, while the application process itself often runs more safely on a non-privileged internal port.\nThat combination of service hardening and port mapping is the difference between “the backend runs on the machine” and “the backend is actually deployable.” Getting it right early keeps the rest of the deployment process much simpler.\nFurther Reading Setting up the VPS Server Starting the Server on Boot Introduction to Spring Boot Security Basics and Certificate Pinning ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/027-yum-mariadb-security-and-iptables/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 9: Setting Up a Cloud Server\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/4jIqplr19HA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the server exists, the next job is to make it useful. That means installing the packages the backend depends on, getting the database into a safe enough state for internet exposure, and making sure the application can be reached through the usual HTTP and HTTPS ports.\u003c/p\u003e","title":"Yum, MariaDB, Security and iptables"},{"content":" Module 9: Security\nSecurity is one of the easiest areas to discuss in slogans and one of the hardest to handle well in real software. The first thing worth saying clearly is that security is always a trade-off problem. Stronger protections often add cost, complexity, or friction. That does not make them optional. It means they have to be applied thoughtfully.\nThis lesson starts with the right framing: vulnerability, exploit, and security layers are not abstract buzzwords. They describe how real systems fail. A vulnerability is a weakness. An exploit is a concrete way to use one or more weaknesses. Most applications are not defending against movie-style attackers with full device compromise. They are trying to protect user data, application logic, and trust boundaries in realistic scenarios.\nCodename One does provide some helpful defaults, and the older lesson explains one of them well: obfuscation and the framework\u0026rsquo;s structure can make reverse engineering less straightforward than in some native setups. That is useful, but it should be treated as friction for attackers, not as a complete security strategy.\nCertificate pinning is a good example of a stronger but more delicate protection. It can reduce the risk of man-in-the-middle attacks by requiring the app to trust only a specific certificate or certificate set rather than any certificate the device would otherwise accept through the normal chain of trust. That is powerful, but it also increases operational risk because certificate rotation and deployment mistakes can break legitimate traffic if you are not prepared for them.\nSo the right question is not \u0026ldquo;should I pin because security is good?\u0026rdquo; It is \u0026ldquo;does this threat model justify the added operational burden, and do we have a plan for maintaining it safely?\u0026rdquo; For high-value traffic, the answer may be yes. For other applications, normal TLS validation plus good server-side hygiene may be the more responsible choice.\nThe practical takeaway is that mobile security should be layered. Protect transport. Protect stored data where appropriate. Limit exposure in the UI. Avoid leaking sensitive behavior into easily modified client code. And when you adopt stronger measures like pinning, do it because the threat model is clear, not because the feature sounds impressive.\nFurther Reading Developer Guide Storage Encryption and Misc Security Features How Do I Access Remote Webservices, Perform Operations On The Server ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/028-security-basics-and-certificate-pinning/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 9: Security\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/kjUFJro0yUQ?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eSecurity is one of the easiest areas to discuss in slogans and one of the hardest to handle well in real software. The first thing worth saying clearly is that security is always a trade-off problem. Stronger protections often add cost, complexity, or friction. That does not make them optional. It means they have to be applied thoughtfully.\u003c/p\u003e","title":"Security Basics and Certificate Pinning"},{"content":" Module 9: Setting Up a Cloud Server\nManual deployment is tolerable exactly once. After that, you want a repeatable way to copy the backend onto the server, keep configuration files in the right place, and make sure the application comes back automatically after a reboot.\nThe lesson starts with secure copy, and that is still a perfectly reasonable first deployment tool. You copy the configuration file, copy the built artifact, and keep the transfer explicit enough that you can see what changed. It is not fancy, but it is understandable, and that matters when you are still assembling the deployment story.\nThe next step is the one that turns the backend from a jar file into a service. The original lesson leans on a Spring Boot feature that allows the packaged artifact to behave like an executable Linux service. That is a strong fit for a small VPS because it lets the operating system manage startup and logs instead of forcing you to keep the app alive manually in a shell.\nThe video uses symbolic links and classic init-style service integration. The exact boot integration mechanism you would choose today may differ depending on distribution and tooling, but the principle is the same: the server should know how to start the backend on boot, where its logs live, and which configuration belongs to that deployed instance.\nThe lesson also includes supporting pieces such as copying environment-specific properties, creating the database, and placing build tools where the backend expects them. Those details are not glamorous, but they are what make deployment dependable. A server is not really deployed until the configuration, runtime, filesystem layout, and startup behavior all line up.\nFurther Reading Setting up the VPS Server Let’s Encrypt, HTTPS Certificate Support Introduction to Spring Boot Connecting to a Web Service ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/028-starting-the-server-on-boot/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 9: Setting Up a Cloud Server\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/mqNtfN2C3fM?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eManual deployment is tolerable exactly once. After that, you want a repeatable way to copy the backend onto the server, keep configuration files in the right place, and make sure the application comes back automatically after a reboot.\u003c/p\u003e","title":"Starting the Server on Boot"},{"content":" Module 9: Setting Up a Cloud Server\nOnce the backend is public, HTTPS stops being optional. Modern mobile platforms expect secure traffic, and production apps should assume that all client-server communication needs transport security from the start.\nThe lesson begins with the application-side change: configure the server to listen on an HTTPS port and tell the Java runtime where to find the keystore, alias, and password it should use. That is still the correct mental model. HTTPS in Java is not just a hosting concern. The application itself needs access to the certificate material it will present to clients.\nBefore any certificate can work, the server also needs a real domain name. The video is right to pause on this. Certificates are tied to names, not to bare IP addresses, so DNS is part of the HTTPS setup whether you like it or not. The domain has to resolve to the server before certificate issuance makes sense.\nThe Let\u0026rsquo;s Encrypt workflow shown in the video is from an earlier moment in the ecosystem, and some of the pain it describes is very specific to that period and stack. The durable lesson is that certificate issuance, renewal, and Java keystore handling need to be understood as one pipeline. Getting a certificate from a certificate authority is only half the job. The Java application also needs the certificate material in a format it can actually use.\nThat conversion step is why this lesson spends time on PEM files, keystores, and ownership changes. Even if the exact commands evolve, the deployment concern remains the same: obtain the certificate, convert or package it into the format your runtime expects, and place it somewhere the application can read without turning the whole server into a permissions mess.\nThe warning about Java trust stores is also still relevant in spirit. When certificate authority support changes over time, older runtimes can fail in surprising ways. Secure deployment is easier when your Java runtime is current enough to understand the certificate ecosystem you are using.\nFurther Reading Automating Lets Encrypt Renewal Process Security Basics and Certificate Pinning Introduction to Spring Boot Communicating from the Client ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/029-let-s-encrypt-https-certificate-support/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 9: Setting Up a Cloud Server\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/sH5GY816sRc?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the backend is public, HTTPS stops being optional. Modern mobile platforms expect secure traffic, and production apps should assume that all client-server communication needs transport security from the start.\u003c/p\u003e\n\u003cp\u003eThe lesson begins with the application-side change: configure the server to listen on an HTTPS port and tell the Java runtime where to find the keystore, alias, and password it should use. That is still the correct mental model. HTTPS in Java is not just a hosting concern. The application itself needs access to the certificate material it will present to clients.\u003c/p\u003e","title":"Let’s Encrypt, HTTPS Certificate Support"},{"content":" Module 9: Security\nOnce transport security is in place, the next questions are usually local ones: what happens if the device is compromised, if a screenshot leaks sensitive information, or if another app can inspect copied data? These are the kinds of risks the second security lesson is trying to address.\nStorage encryption is the clearest example. If the app stores sensitive information locally, encrypting that storage can add a useful defensive layer. But encryption is never just \u0026ldquo;turn it on and forget it.\u0026rdquo; Key management becomes the real issue immediately. If the decryption key is easy for an attacker to recover from the app itself, then the protection is weaker than it first appears. That is why the lesson discusses trade-offs like server-provided keys versus offline usability.\nThere is also an important distinction between storage mechanisms. The older lesson is right to separate Codename One Storage from lower-level filesystem access and SQL persistence. The abstraction level matters because it determines where transparent protections can realistically be applied and where you need a more explicit design.\nThe other features discussed here are more situational, but still useful when the threat model justifies them. Screenshot blocking can reduce accidental disclosure on some platforms. Copy/paste restrictions can help for highly sensitive fields. Jailbreak or root detection may serve as one signal among several, though it should never be treated as a perfect truth oracle because compromised devices are designed to hide that fact.\nSo the practical rule for these features is simple: use them when they protect something concrete, and do not confuse them with complete security. They are layers, not guarantees. Applied carefully, they raise the cost of attack and reduce common mistakes. Applied blindly, they mostly add friction.\nFurther Reading Developer Guide Security Basics and Certificate Pinning How Do I Use Crash Protection, Get Device Logs ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/029-storage-encryption-and-misc-security-features/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 9: Security\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/GMnWMB_JfaQ?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce transport security is in place, the next questions are usually local ones: what happens if the device is compromised, if a screenshot leaks sensitive information, or if another app can inspect copied data? These are the kinds of risks the second security lesson is trying to address.\u003c/p\u003e","title":"Storage Encryption and Misc Security Features"},{"content":" Module 9: Setting Up a Cloud Server\nGetting HTTPS working once is not enough. Let\u0026rsquo;s Encrypt certificates expire quickly by design, so the real deployment milestone is automated renewal, not manual issuance.\nThat short lifetime is not a flaw. It is the reason the ecosystem can lean so heavily on automation. Instead of treating certificate replacement as an infrequent ceremony people dread, the system pushes you toward a scriptable renewal path that keeps the server current with minimal manual work.\nThe lesson takes the direct Linux approach: write a renewal script, make it executable, and schedule it with cron. The details in the video are old-school, but the operational idea is still good. Renewal should be repeatable, unattended, and explicit enough that you can audit what it is doing.\nThe awkward part in the original setup is downtime. Because the certificate tooling and the server stack do not integrate perfectly, the backend may have to stop briefly while the renewal process runs. That is not ideal, but it is better than letting the certificate expire. In a more mature deployment you would try to reduce or eliminate that interruption, yet the basic rule remains: an imperfect automated renewal process is still far better than a perfect manual process nobody remembers to run.\nThe main thing to preserve from this lesson is the deployment mindset. Security-related operational steps should not live only in your memory. They should live in scripts, scheduled tasks, and configuration that the server can execute predictably.\nFurther Reading Let’s Encrypt, HTTPS Certificate Support Setting up the VPS Server Security Basics and Certificate Pinning Corporate Server ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/030-automating-lets-encrypt-renewal-process/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 9: Setting Up a Cloud Server\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/0l4R049tSOY?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eGetting HTTPS working once is not enough. Let\u0026rsquo;s Encrypt certificates expire quickly by design, so the real deployment milestone is automated renewal, not manual issuance.\u003c/p\u003e\n\u003cp\u003eThat short lifetime is not a flaw. It is the reason the ecosystem can lean so heavily on automation. Instead of treating certificate replacement as an infrequent ceremony people dread, the system pushes you toward a scriptable renewal path that keeps the server current with minimal manual work.\u003c/p\u003e","title":"Automating Lets Encrypt Renewal Process"},{"content":" Module 10: Maps\nMaps are one of those features that look simple in a product brief and become surprisingly nuanced once implementation begins. The first decision is not how to place a marker. It is which kind of map integration you actually want and how close that integration needs to be to the native experience on each platform.\nThe older lesson does a useful job of separating the available map approaches. Some are native, some are browser-backed fallbacks, and some represent older technology that is no longer the preferred path. That distinction still matters. For most current projects, the native map implementation plus a reasonable fallback is the right mental model. Older tiled-map approaches belong to legacy compatibility, not to the default recommendation for new work.\nThis lesson also highlights a practical truth about map integrations: they are not self-contained. You usually need provider keys, platform-specific configuration, and some awareness of quota or billing implications. That means map support is partly a UI feature and partly an operational setup task.\nOne place where the older material is still directionally right is key handling. Hard-coding keys into a demo may be acceptable for a tutorial, but production applications should treat provider keys as operational assets and protect them appropriately. The exact best practice depends on the provider and the architecture, but the principle is the same: keep the production path more careful than the tutorial path.\nSo the right starting point for maps in Codename One is not \u0026ldquo;drop in a map widget.\u0026rdquo; It is \u0026ldquo;pick the right implementation strategy, understand the native and fallback story, and configure the provider side correctly before building map-heavy features on top.\u0026rdquo;\nFurther Reading Developer Guide How Do I Access Native Device Functionality, Invoke Native Interfaces Communicating with the Server ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/030-introduction-and-installation/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 10: Maps\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/HRTLnLecoMA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eMaps are one of those features that look simple in a product brief and become surprisingly nuanced once implementation begins. The first decision is not how to place a marker. It is which kind of map integration you actually want and how close that integration needs to be to the native experience on each platform.\u003c/p\u003e","title":"Introduction and Installation"},{"content":" Module 10: Adapting to Tablets and Desktops\nRunning a phone UI on a tablet is easy. Making it feel like it belongs there is not. That is the problem this module solves.\nThe lesson begins with the right observation: a phone-oriented app often looks merely enlarged on a tablet. Images feel oversized, empty space is wasted, navigation patterns become awkward, and the whole application looks like it was stretched rather than designed.\nThe fix is not a pile of tablet-specific special cases. The fix is to step back and change the abstraction. On a phone, it is natural for each major screen to be its own form. On a tablet or desktop, that often becomes clumsy. A better pattern is to keep one stable outer shell and replace the content inside it as the user moves through the app.\nThat architectural decision is the heart of the module. Instead of deriving everything directly from Form, the lesson introduces a higher-level UI abstraction that can behave like a normal form on phones while participating in a single-shell layout on larger displays. That lets the same application logic support very different presentation patterns without duplicating the whole app.\nThe OK/cancel discussion in the video is a good example of why this matters. On a phone, toolbar commands may make sense. On a tablet, large action buttons placed naturally in the layout can feel much better. Once that choice is expressed in the abstraction layer, individual screens stop caring about which form factor they are on and can focus on their own job.\nThis is the real benefit of the module. It is not just about making one screen wider. It is about moving form-factor differences into an architectural seam where they can be controlled deliberately.\nFurther Reading The UIAbstraction Class The TabletUI Class Putting it all Together Adapting a UI Design ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/031-abstraction-and-architecture/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 10: Adapting to Tablets and Desktops\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/Dh1bYqiKBQo?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eRunning a phone UI on a tablet is easy. Making it feel like it belongs there is not. That is the problem this module solves.\u003c/p\u003e\n\u003cp\u003eThe lesson begins with the right observation: a phone-oriented app often looks merely enlarged on a tablet. Images feel oversized, empty space is wasted, navigation patterns become awkward, and the whole application looks like it was stretched rather than designed.\u003c/p\u003e","title":"Abstraction and Architecture"},{"content":" Module 10: Maps\nThe first useful map example is not complicated. Create a map, make it render on the supported targets, and verify that the fallback behavior is acceptable where native maps are not available. That sounds simple, but it teaches an important lesson: a map feature is only as good as its weakest platform path.\nThe older lesson compares several rendering outcomes and shows why some map implementations feel much more modern than others. That is still the right instinct. If one path gives you an outdated or visually inconsistent experience while another produces a much better fallback, choose the path that keeps the feature coherent across devices.\nThis lesson also exposes a subtle but practical issue: not every runtime environment behaves like a real user device. Build-time screenshot generation, simulators, and special platform modes may not support every embedded component. When a feature depends on browser-backed or heavyweight behavior, the application should have a graceful fallback instead of assuming the full environment is always available.\nThat is why even a \u0026ldquo;hello world\u0026rdquo; maps lesson matters. It is where you verify native keys, fallback configuration, and platform-specific behavior before you build markers, overlays, routing, or location-driven flows on top. If the base map setup is fragile, every map feature after that becomes harder to debug.\nSo the real goal here is not just to get a map on screen. It is to make sure the basic map experience is acceptable on the targets you care about and that your application degrades cleanly where full support is not present.\nFurther Reading Introduction and Installation Developer Guide Markers, Lightweight Overlays and Map Layout ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/031-hello-world-and-devices/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 10: Maps\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/m43A68sNcvg?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe first useful map example is not complicated. Create a map, make it render on the supported targets, and verify that the fallback behavior is acceptable where native maps are not available. That sounds simple, but it teaches an important lesson: a map feature is only as good as its weakest platform path.\u003c/p\u003e","title":"Hello World and Devices"},{"content":" Module 10: Maps\nMarkers are the first useful map feature because they let the user connect geographic coordinates to something meaningful. But the default marker API is only the beginning. As soon as you want richer visuals or interactions, you start wanting more control than a simple pin can provide.\nThat is where overlays become interesting. Instead of treating the map as a sealed native surface that can only show provider-defined markers, this lesson shows how to place lightweight components above the map and position them according to latitude and longitude. That opens up much richer UI possibilities: custom buttons, status badges, composite visuals, or other interactive elements that feel like part of the app instead of part of the map provider.\nThe layout-manager approach used here is especially instructive because it keeps the problem honest. A map overlay is still a layout problem. You need to convert coordinates into screen points, place components using their preferred size, and update their positions when the map moves or zooms. Once you describe it that way, the solution becomes much less magical.\nThis is also a good example of how Codename One\u0026rsquo;s lightweight UI model enables features that would once have been awkward or impossible. If heavyweight native components always won the z-order battle, this pattern would be much harder to support. The ability to mix map content with lightweight overlays is a real design advantage.\nSo the lesson here is that built-in markers are fine when they are enough, but do not stop there if your map UI needs richer interaction. A carefully designed overlay layer can turn the map from a passive display into a real part of the application interface.\nFurther Reading Developer Guide Introduction and Installation Hello World and Devices ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/032-markers-lightweight-overlays-and-map-layout/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 10: Maps\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/sed5OPQSfe0?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eMarkers are the first useful map feature because they let the user connect geographic coordinates to something meaningful. But the default marker API is only the beginning. As soon as you want richer visuals or interactions, you start wanting more control than a simple pin can provide.\u003c/p\u003e","title":"Markers, Lightweight Overlays and Map Layout"},{"content":" Module 10: Adapting to Tablets and Desktops\nOnce the architectural decision is made, the next question is how to encode it in code without making every screen harder to write. The answer in this course is UIAbstraction, a layer that hides whether the current screen is really a form or just content living inside a larger tablet shell.\nThat is a strong design choice because most screens do not actually care. They want to add components, bind actions, show the next screen, validate an OK button, and go back when needed. They should not have to know whether they are running inside a phone-style navigation stack or a tablet-style container swap.\nThe class therefore acts as a small compatibility layer. In phone mode it delegates to a real form. In tablet mode it works with a container that can be embedded into the persistent tablet shell. The application code above it gets a stable API either way.\nThe OK/cancel handling is a good example. Instead of forcing every screen to decide how its action buttons should be rendered on each form factor, the abstraction turns that into a capability. If a screen says it needs OK/cancel behavior, the abstraction can implement that in the form-appropriate way for the current device.\nThe same idea appears in navigation, validation, and floating action button handling. The app code asks for behavior, and the abstraction adapts that behavior to the current presentation model. That keeps the screen classes readable while still allowing the larger-device UI to diverge meaningfully from the phone layout.\nThe video goes fairly deep into wrapper containers and decorated containers, and that is worth understanding at a conceptual level even if the exact implementation later changes. Once a screen can live in more than one kind of outer structure, it becomes useful to distinguish between the core content and the final wrapped container that includes shared controls or extra layout layers.\nThis kind of abstraction can become overengineered very quickly, so the best thing about the version in the course is that it stays tightly tied to a concrete product need. It is not trying to become a universal UI framework. It is solving one application\u0026rsquo;s phone/tablet split in a way that keeps the rest of the code mostly unchanged.\nFurther Reading Abstraction and Architecture The TabletUI Class Putting it all Together Base Navigation Form and Shape Effects ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/032-the-uiabstraction-class/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 10: Adapting to Tablets and Desktops\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/bU6pZPs3uto?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the architectural decision is made, the next question is how to encode it in code without making every screen harder to write. The answer in this course is \u003ccode\u003eUIAbstraction\u003c/code\u003e, a layer that hides whether the current screen is really a form or just content living inside a larger tablet shell.\u003c/p\u003e","title":"The UIAbstraction Class"},{"content":" Module 11: Building from the Open Source Project Offline Without Build Servers or Plugin\nWorking directly from the Codename One source tree is not the normal path for most application developers. That is worth saying upfront because this module makes more sense when treated as advanced infrastructure knowledge rather than as the default workflow.\nIf your real goal is just to build and ship apps, the hosted build flow and modern project tooling are usually the right choice. Even the older lesson says as much. Building everything locally from source is valuable for a different set of reasons: understanding how the platform is assembled, being able to debug the lower layers more confidently, or contributing to the framework itself.\nThe conceptual model in the lesson is still the useful part. Codename One is not one monolith. It is a combination of APIs, ports, runtimes or VMs on some targets, tooling, and supporting binaries or stubs that make compilation practical across platforms. Once you understand those pieces, the source layout stops feeling arbitrary.\nThe exact version guidance in the video is obviously dated now, and the recommended setup for ordinary application development has moved on. But the deeper lesson is still current: if you build from source, you are taking responsibility for more of the platform stack. That means understanding what each repository or module contributes and which parts exist as implementation support rather than public API.\nSo this lesson is best read as an anatomy-of-the-platform walkthrough for advanced users. It is not the new default way to start a project. It is the way to get closer to the internals when you deliberately need that level of control.\nFurther Reading Developer Guide How Do I Get Repeatable Builds, Build Against A Consistent Version Of Codename One \u0026amp; Use The Versioning Feature How Do I Use Offline Build ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/033-introduction-and-setup/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 11: Building from the Open Source Project Offline Without Build Servers or Plugin\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/wqcM8pSOGTY?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eWorking directly from the Codename One source tree is not the normal path for most application developers. That is worth saying upfront because this module makes more sense when treated as advanced infrastructure knowledge rather than as the default workflow.\u003c/p\u003e","title":"Introduction and Setup"},{"content":" Module 10: Adapting to Tablets and Desktops\nIf UIAbstraction is the contract, TabletUI is the concrete shell that makes the larger-screen experience real.\nThe key idea is that a tablet version of the app does not need to recreate the entire screen on every navigation step. Instead, it can keep one stable outer form, leave navigation permanently available, and replace only the main content area. That makes the product feel much more natural on tablets and desktops because the app stops behaving like a sequence of full-screen phone cards.\nThis lesson takes that pattern seriously. The tablet shell owns the outer layout, the persistent side menu, the title treatment, and the central content area. Navigation then becomes a matter of replacing the content in that center region instead of constructing and showing a brand-new form for every move.\nThat is why the side menu design changes so much here. On a larger screen the menu does not need to hide behind a command. It can stay present and act like a real part of the application structure. The code also uses grouped selectable components so the current section remains visually obvious, which is exactly the kind of small polish that makes a desktop or tablet UI feel intentional.\nThe showContainer() behavior is the heart of the lesson. The first screen is added into the shell. Later screens replace the current content in the center. That is a small implementation detail with a large user-experience effect because it changes the mental model from “move to another form” to “work within one application frame.”\nThe video also shows some duplication between phone-specific and tablet-specific navigation code. That is acceptable here. Once the tablet experience diverges enough from the phone experience, a little explicit duplication can be cleaner than forcing both models through one overcomplicated generic API.\nFurther Reading Abstraction and Architecture The UIAbstraction Class Putting it all Together How Do I Create Gorgeous SideMenu ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/033-the-tabletui-class/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 10: Adapting to Tablets and Desktops\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/DyzEgAGyRcA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eIf \u003ccode\u003eUIAbstraction\u003c/code\u003e is the contract, \u003ccode\u003eTabletUI\u003c/code\u003e is the concrete shell that makes the larger-screen experience real.\u003c/p\u003e\n\u003cp\u003eThe key idea is that a tablet version of the app does not need to recreate the entire screen on every navigation step. Instead, it can keep one stable outer form, leave navigation permanently available, and replace only the main content area. That makes the product feel much more natural on tablets and desktops because the app stops behaving like a sequence of full-screen phone cards.\u003c/p\u003e","title":"The TabletUI Class"},{"content":" Module 10: Adapting to Tablets and Desktops\nThe value of an abstraction is not that it looks clever in isolation. It is that real screens become easier to adapt. This final lesson in the module is where that claim gets tested.\nThe encouraging thing in the original walkthrough is how little many screens actually need to change once the abstraction layer exists. Base navigation screens can move from Form to UIAbstraction with relatively small edits, and more specialized screens can opt into the specific behaviors they need such as OK/cancel handling or form-specific theming.\nThat is exactly what good application architecture should do. It should move the difficult decision to one place and reduce the amount of code that needs to know about it everywhere else.\nThe address form example in the video shows this clearly. Validation still happens. The submission flow still happens. Back and OK actions still happen. What changes is where those controls come from and how they are rendered on different form factors. The business logic is not rewritten just because the app now has a larger-screen presentation.\nThe lesson also makes a fair point about framework design. It would be tempting to say that this whole abstraction should just be part of Codename One itself. The reason not to rush that is that framework APIs are expensive to commit to. A product-specific abstraction can be tuned aggressively for one app. A general-purpose framework abstraction has to survive many different apps and many years of backwards compatibility.\nSo the right takeaway here is not that every app needs exactly this abstraction layer. It is that tablet and desktop adaptation becomes much more manageable when you first identify which parts of your UI are truly form-factor-specific and then isolate them behind a stable application-level API.\nFurther Reading Abstraction and Architecture The UIAbstraction Class The TabletUI Class Adapting a UI Design ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/034-putting-it-all-together/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 10: Adapting to Tablets and Desktops\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/AMlnslUn1bA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe value of an abstraction is not that it looks clever in isolation. It is that real screens become easier to adapt. This final lesson in the module is where that claim gets tested.\u003c/p\u003e\n\u003cp\u003eThe encouraging thing in the original walkthrough is how little many screens actually need to change once the abstraction layer exists. Base navigation screens can move from \u003ccode\u003eForm\u003c/code\u003e to \u003ccode\u003eUIAbstraction\u003c/code\u003e with relatively small edits, and more specialized screens can opt into the specific behaviors they need such as OK/cancel handling or form-specific theming.\u003c/p\u003e","title":"Putting it all Together"},{"content":" Module 11: Building from the Open Source Project Offline Without Build Servers or Plugin\nIf you are building Codename One directly from source, the simulator is the first place to prove that your environment is actually coherent. Before you worry about native packaging, you want one unambiguous success signal: the framework builds, the demo project links against it correctly, and the application runs in the Java SE simulator path.\nThat is why the Kitchen Sink demo is a good target. It exercises a wide range of framework behavior, so if it launches successfully you have more confidence than you would from a toy example. It is not a guarantee that every platform path is correct, but it is the right first checkpoint.\nThe older lesson necessarily spends time on the mechanics of assembling jars, copying the right pieces into place, and working around the absence of the usual build client tooling. The exact commands are historical, but the practical lesson remains: once you operate outside the normal project-generation path, you have to understand which artifacts the simulator actually expects and which pieces of the usual workflow you are now responsible for yourself.\nThis is another reason direct-source work should be treated as an advanced mode. The simulator run is no longer \u0026ldquo;click run.\u0026rdquo; It becomes \u0026ldquo;verify that the platform pieces, demo project, and launch path all line up.\u0026rdquo; That can be valuable knowledge, but it is different from normal application development.\nFurther Reading Introduction and Setup Developer Guide Hello World ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/034-running-the-kitchen-sink-in-the-simulator/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 11: Building from the Open Source Project Offline Without Build Servers or Plugin\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/l1TPKuHYr9c?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eIf you are building Codename One directly from source, the simulator is the first place to prove that your environment is actually coherent. Before you worry about native packaging, you want one unambiguous success signal: the framework builds, the demo project links against it correctly, and the application runs in the Java SE simulator path.\u003c/p\u003e","title":"Running the Kitchen Sink in the Simulator"},{"content":" Module 11: Building from the Open Source Project Offline Without Build Servers or Plugin\nRunning a Codename One app as a desktop application is a useful way to understand what the simulator and Java SE port are really doing for you. The central idea is straightforward: Codename One still needs a bootstrap environment, and on desktop that environment is responsible for creating the host window, initializing the port, and handing lifecycle control to the application.\nThat is why the lesson introduces a small desktop stub. The stub is not application logic in the normal sense. It is the code that embeds the Codename One runtime into a standard Java desktop container and gives the app somewhere to live.\nThe specific Swing-based bootstrap in the older lesson is less important than the pattern. Desktop support in this context means: create a native host window, initialize the Codename One environment against it, forward lifecycle events properly, and package the runtime pieces the app needs. Once you see it that way, the \u0026ldquo;desktop app\u0026rdquo; stops looking like a mystery and starts looking like an ordinary host-shell problem.\nThis lesson is also useful because it shows how different the concerns are from normal portable application code. The portable app should not care about Swing setup, storage path heuristics, or simulator-only flags. Those belong in the desktop-specific bootstrap layer, and keeping them there preserves the clean separation between the app and the host platform.\nSo the main value here is architectural. A desktop wrapper is just one more example of Codename One\u0026rsquo;s layering: portable app logic inside, host-specific bootstrap outside.\nFurther Reading Developer Guide Running the Kitchen Sink in the Simulator How Do I Use Desktop Javascript Ports ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/035-building-a-desktop-version-of-the-kitchen-sink/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 11: Building from the Open Source Project Offline Without Build Servers or Plugin\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/PbRbzCGQCQE?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eRunning a Codename One app as a desktop application is a useful way to understand what the simulator and Java SE port are really doing for you. The central idea is straightforward: Codename One still needs a bootstrap environment, and on desktop that environment is responsible for creating the host window, initializing the port, and handing lifecycle control to the application.\u003c/p\u003e","title":"Building a Desktop Version of the Kitchen Sink"},{"content":" Module 11: Animations\nAnimation helps when it explains something. It hurts when it becomes decoration for its own sake. That warning at the start of the video is still the right way to approach transitions in Codename One.\nThe two most useful jobs for transitions are emphasis and confirmation. Sometimes you want to draw the user\u0026rsquo;s eye to something important. More often, you want motion to confirm what just happened: a new screen was opened, a dialog came from outside the normal navigation stack, or a piece of content expanded into a detail view.\nThat is why the lesson spends more time on meaning than on visual variety. Codename One has many transition types, but the important decision is not which effect looks coolest. It is which effect best matches the user’s mental model of the action that just occurred.\nThe examples in the app are good ones. A cover-style transition makes sense when opening something that behaves like a layer over the current flow. A morph transition makes sense when a thumbnail turns into a full-size detail view because the user can visually track the relationship between the two states. Even the reverse direction matters. If the return motion tells a different story, a different transition may be the better choice.\nThe video also explains one detail that often confuses people: forms and dialogs each have transition-in and transition-out behavior, but in practice form navigation often focuses on the outgoing transition. That is less about API trivia than about keeping navigation consistent. What the user perceives is the movement between states, and consistency matters more than theoretical symmetry.\nAnother good pattern from the lesson is restoring the previous transition after a special-case navigation. That prevents one locally chosen effect from leaking into unrelated parts of the app. Transitions should describe the current interaction, not accidentally redefine the whole application.\nFurther Reading Layout Animations Animation Manager, Style Animations and Low Level Animations Morph Transition: Animating Elements Between Forms Bubble Border ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/035-transitions/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 11: Animations\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/aVkeOIx-Is8?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eAnimation helps when it explains something. It hurts when it becomes decoration for its own sake. That warning at the start of the video is still the right way to approach transitions in Codename One.\u003c/p\u003e\n\u003cp\u003eThe two most useful jobs for transitions are emphasis and confirmation. Sometimes you want to draw the user\u0026rsquo;s eye to something important. More often, you want motion to confirm what just happened: a new screen was opened, a dialog came from outside the normal navigation stack, or a piece of content expanded into a detail view.\u003c/p\u003e","title":"Transitions"},{"content":" Module 11: Building from the Open Source Project Offline Without Build Servers or Plugin\nBuilding a native Android application directly from the Codename One sources is a useful exercise in understanding how the Android port is assembled, but it is not a lightweight workflow. The amount of setup in the older lesson makes that point on its own.\nThe conceptual structure is still worth learning. You need the portable sources, the Android-specific implementation sources, the right resources and bootstrap files in the places Android expects, and an activity layer that maps Android lifecycle behavior onto the Codename One application model. Once all of those are aligned, the app can run as a normal Android application.\nThe old lesson also spends time on Java 8 support, Gradle configuration, copied implementation files, and Android activity wiring. The specific historical version details are not the important thing now. The important thing is understanding why these steps exist at all: Android needs an actual native project structure, and Codename One\u0026rsquo;s Android port includes implementation classes that intentionally override or extend the portable layer.\nThis is one more reason the normal hosted or standard build flow remains the right default for most application work. When you bypass that flow, you take on the responsibility of reproducing all the Android-specific packaging and lifecycle glue yourself. That can be educational and sometimes necessary for framework-level work, but it is not a simpler way to build apps.\nFurther Reading Developer Guide Introduction and Setup How Do I Use Offline Build ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/036-building-an-android-native-version-of-the-kitchen-sink/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 11: Building from the Open Source Project Offline Without Build Servers or Plugin\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/5eMvwRcDcug?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eBuilding a native Android application directly from the Codename One sources is a useful exercise in understanding how the Android port is assembled, but it is not a lightweight workflow. The amount of setup in the older lesson makes that point on its own.\u003c/p\u003e","title":"Building an Android Native Version of the Kitchen Sink"},{"content":" Module 11: Animations\nLayout animation is one of the most useful animation tools in Codename One because it works with the framework instead of fighting it. The layout manager already decides where components belong. Layout animation simply turns that change of layout into motion the user can understand.\nThe underlying concept is explicit reflow. When you add, remove, or rearrange components after a form is already visible, the UI does not magically update itself in a meaningful animated way. You need to trigger layout so the new positions are calculated. Once you do that, Codename One can animate the move from the old layout state to the new one.\nThat is why these APIs feel so practical. They are not asking you to compute every pixel of an animation by hand. They let you describe the structural change and then animate the framework’s reflow process.\nThe lesson distinguishes between layout and unlayout, and that distinction is worth understanding. One direction animates components into their valid final positions. The other direction is useful when you want to visually move something out before it is removed. In the dish-delete example, that creates a two-step effect: the item slides away, and then the rest of the layout closes the gap.\nThat pattern works well because it mirrors the user’s understanding of what happened. First the chosen item leaves. Then the remaining list reorganizes itself. Motion is carrying meaning here, not just adding polish.\nThe fade variants and blocking variants of the APIs are useful for the same reason. They let you compose changes in a controlled sequence instead of firing several visual updates at once and hoping the result feels natural.\nThe lesson is also right to be cautious about the more recursive hierarchy-wide variants. The deeper the framework has to infer for you, the more edge cases appear. Layout animation is most powerful when it is used intentionally around a specific visible change.\nFurther Reading Transitions Animation Manager, Style Animations and Low Level Animations Dish List and Edit Base Navigation Form and Shape Effects ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/036-layout-animations/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 11: Animations\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/anfVMvBXXX0?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eLayout animation is one of the most useful animation tools in Codename One because it works with the framework instead of fighting it. The layout manager already decides where components belong. Layout animation simply turns that change of layout into motion the user can understand.\u003c/p\u003e","title":"Layout Animations"},{"content":" Module 11: Animations\nBy the time you reach this lesson, the easy animation APIs are no longer enough. You start needing orchestration: style changes that happen in sequence, animations that should not collide with each other, and low-level control for custom graphical effects.\nThat is where the animation manager becomes useful. Style animation does not fit as neatly into the older one-method convenience APIs because it has to coordinate state changes on components that may already be participating in other updates. The animation manager gives the form one place to serialize and supervise those operations.\nThis is more important than it sounds. Without coordination, the UI can become fragile when users trigger structural changes while an animation is still running. The manager exists partly to make these interactions safe by postponing conflicting operations until the current animation finishes.\nThe style animation example in the video is a good one because it shows both the power and the limit of this approach. Some style properties animate beautifully, especially values such as colors. Others are too discrete to produce satisfying motion. The point is not to animate every style attribute you can find. It is to choose the ones that meaningfully communicate change.\nThe lesson then moves all the way down to the low-level animation hooks, and that material is worth keeping because it explains how Codename One animation really works. The EDT advances in ticks, animated components opt into receiving animation callbacks, and repainting happens only when the framework is told something visual actually changed.\nThat design is powerful, but it comes with responsibility. A component that stays registered for animation unnecessarily can waste battery and CPU. An animate() method that does too much work or returns true too often can quietly become a performance problem. This is one of those APIs where understanding the cost model matters as much as understanding the signatures.\nSo the real lesson here is not “here is one more animation trick.” It is that Codename One gives you both high-level convenience APIs and low-level rendering hooks, and the farther down you go, the more disciplined you need to be about performance, registration, and repaint frequency.\nFurther Reading Transitions Layout Animations Threading and the EDT What Is Performance? Breaking Down the Problem ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/037-animation-manager-style-animations-and-low-level-animations/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 11: Animations\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/qUJ4FwZMEQY?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eBy the time you reach this lesson, the easy animation APIs are no longer enough. You start needing orchestration: style changes that happen in sequence, animations that should not collide with each other, and low-level control for custom graphical effects.\u003c/p\u003e\n\u003cp\u003eThat is where the animation manager becomes useful. Style animation does not fit as neatly into the older one-method convenience APIs because it has to coordinate state changes on components that may already be participating in other updates. The animation manager gives the form one place to serialize and supervise those operations.\u003c/p\u003e","title":"Animation Manager, Style Animations and Low Level Animations"},{"content":" Module 11: Building from the Open Source Project Offline Without Build Servers or Plugin\nThe source-built iOS path makes the underlying Codename One architecture especially visible because it forces you to confront the translation step directly. Unlike the simulator or Java SE path, this is not just \u0026ldquo;compile the app.\u0026rdquo; It is \u0026ldquo;prepare the classes, translate them into the form the iOS runtime expects, and then wrap the result in an Xcode project that can actually run on Apple tooling.\u0026rdquo;\nThat is why the older lesson spends so much time on translation, stubs, generated output, and Xcode setup. The value is not in memorizing those exact commands. The value is in understanding that the iOS path depends on an explicit bootstrap process and a generated native project, not on some hidden magic.\nThe font-registration and project-setting details in the older video are historical, but the broader message is still current: once you are operating at this layer, you are responsible for the native platform\u0026rsquo;s packaging requirements. iOS expects declared resources, native project metadata, and the right build settings. The standard Codename One build flow handles that for ordinary projects. A source-built path makes you do it yourself.\nSo the lesson here is the same as the Android one, but even more visible. Working from source is useful when you want to understand or modify the lower layers of the platform. It is not the recommended day-to-day workflow for building applications. Its value is educational and infrastructural, not ergonomic.\nFurther Reading Developer Guide Introduction and Setup How Do I Use The Include Sources Feature To Debug The Native Code On iOS/Android ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/037-build-an-ios-native-version-of-the-kitchen-sink/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 11: Building from the Open Source Project Offline Without Build Servers or Plugin\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/RsVOanGYjqo?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe source-built iOS path makes the underlying Codename One architecture especially visible because it forces you to confront the translation step directly. Unlike the simulator or Java SE path, this is not just \u0026ldquo;compile the app.\u0026rdquo; It is \u0026ldquo;prepare the classes, translate them into the form the iOS runtime expects, and then wrap the result in an Xcode project that can actually run on Apple tooling.\u0026rdquo;\u003c/p\u003e","title":"Build an iOS Native Version of the Kitchen Sink"},{"content":" Module 12: Creating an Uber Clone\nTranscript Uber is a big influence on the mobile market and a lot of us try to replicate their functionality and Design in this module I\u0026rsquo;ll try to create an Uber application clone but let\u0026rsquo;s discuss a bit what that means let\u0026rsquo;s start by setting expectations in place I\u0026rsquo;m not going to build everything in the app as there are so many nuances and details within the final app that it would be impossible to go through everything however I will build most of the big ticket UI elements and I\u0026rsquo;ll actually try and focus on the hard stuff rather than doing things that are mostly simple I chose to clone the existing app rather than building my own since I want to show a professional grade application and Uber is pretty much that the goal of this module is to teach the theory of building a professional app it\u0026rsquo;s not there for the purpose of rebuilding Uber are you string boot as usual for the server but I\u0026rsquo;ll try to keep it bare it\u0026rsquo;s actually better to do stuff in the server in real world scenarios but in this case I want to focus on client development I\u0026rsquo;m trying to create a close clone but not an identical clone during that last bit between identical and pretty close is a huge amount of effort that doesn\u0026rsquo;t provide a benefit in fact it makes things worse because it forces the code and designed to be more convoluted I will spend a lot of time in the map UI and try to explain how to build a decent GIS application this isn\u0026rsquo;t a GIS tutorial though as I\u0026rsquo;m not an expert in that field I took some shortcuts in building this app so hopefully they don\u0026rsquo;t show much before we start we need to essentially understand the functionality of uber even if you use the app in the past a lot of the functionality is pretty subtle and you might have run through it without noticing we need to grab screenshots of uber features that we can review and compare to what we are trying to implement once we have those images we can use them to create a mock-up of the Uber UI once the mock-up is in place we can create a server and then connect the whole thing together and fill in the details as we move along this is pretty similar to the process I used to build all the apps and the course as you will notice I prefer building the UI first and think it\u0026rsquo;s always the best approach when we finish the app it should be fully working at but you will probably need some work in order to bring it to production grade I\u0026rsquo;ll try to highlight the bits that are necessary as we move through the UI there are some great transition animations in the Uber app which you can see here I\u0026rsquo;ll go into some details of how we can achieve some of them near the end of the module we\u0026rsquo;ll start by focusing on the basic skeleton UI notice that these animations differ between Android and iOS now let\u0026rsquo;s go into the screenshots I captured of the Uber application this shows that even a major native app can have ux blunders we have the Uber logo splash screen followed by a permission prompt for location but let\u0026rsquo;s move on this is the basic login flow to Uber one of the first things I checked is the look and landscape mode turns out that Uber doesn\u0026rsquo;t support that the app is fixed to Portrait on mobile phones it doesn\u0026rsquo;t seem to have much support for tablets either which makes some sense as you would probably not hail a cab with a tablet this allows them to simplify some of their user experience logic and we can probably use a similar approach there are two options for login the first uses social again through Google Facebook and that falls to the native login option the second one uses SMS style activation by collecting the phone number we have support for that in our SMS activation cn1 lib the UI is shown here are all very simple clean and minimalistic which should make them very easy to replicate in codename one on the right you can see a simple form that allows us to select a country if the one we detected isn\u0026rsquo;t correct it\u0026rsquo;s pretty simple list with flags and search notice that when you scroll down in the form the title collapses in the material design style to provide a more compact View the SMS activation process works with four digits it doesn\u0026rsquo;t seem to automatically offer to grab the SMS which is pretty lame we can do better than this I don\u0026rsquo;t understand why Uber wouldn\u0026rsquo;t do something better on Android where it\u0026rsquo;s possible one important thing to notice is the way the digit input looks these are four separate digits but they have one error message below when a number is already active in the server you can use your password and get a password reset form which I didn\u0026rsquo;t include in the screenshots I\u0026rsquo;m not sure I\u0026rsquo;ll go into that level of detail with the implementation one thing that is missing from the screenshots is the next button progress effect which is pretty cool when you press the arrow button the screen tints and the arrow is surrounded by a circular blue progress bar that should be pretty easy to accomplish in codename one so it\u0026rsquo;s something I\u0026rsquo;ll try to do as well the UI itself is mostly the map which is great there are the cause and landmarks highlighted in the map the where to text field isn\u0026rsquo;t really a text field it\u0026rsquo;s a button when you click on it you see the search form to find directions to order an Uber that you can see in the screenshot next to the map notice notices can be swiped from the bottom this is a doable element but it\u0026rsquo;s non-trivial so I won\u0026rsquo;t go into it with this app and ignore that specific element we can see two floating buttons of recent searches trips that you can repeat that should be pretty easy to replicate as well notice that the side menu icon that just floats with no title to disturb the UI of the application one of the small details is the fact that the menu back button is black surrounded by a white outline that means it will be reasonably visible both on a dark and light map that\u0026rsquo;s a great attention to detail once we pick a location we can get a UI prompt with an order option it also shows the direction on the map highlighting my location and destination if we open the sign menu we can see the design is very simple I\u0026rsquo;ll skip the Uber for business stuff in the app we make but I\u0026rsquo;ll try to reproduce this exact UI design notice how the minimalistic design that even skims on colors is able to broadcast Elegance payment is a relatively simple you user experience I won\u0026rsquo;t go into it at all because we can just integrate brain free for billing and Skip on some of these complexities credit card billing is problematic not just due to technical difficulties but due to liability I wouldn\u0026rsquo;t go into that unless I had to I won\u0026rsquo;t go into the details of each of these forms notice I blocked out in red some private information about my trip that isn\u0026rsquo;t really important one thing you should notice is how simple these uis are I won\u0026rsquo;t really get into them but they should be pretty trivial the iOS version is remarkably similar to the Android version both in design and transitions notice that the login form has some pretty cool background rotation animation but other than that only the transitions differ in the app everything else looks identical even the text input and The Floating Action button this will make our lives much easier\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/038-1-introduction/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/xCEOuV43Uqw?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003eUber is a big influence on the mobile\nmarket\nand a lot of us try to replicate their\nfunctionality and Design\nin this module I\u0026rsquo;ll try to create an\nUber application clone\nbut let\u0026rsquo;s discuss a bit what that means\nlet\u0026rsquo;s start by setting expectations in\nplace\nI\u0026rsquo;m not going to build everything in the\napp as there are so many nuances and\ndetails within the final app that it\nwould be impossible to go through\neverything\nhowever\nI will build most of the big ticket UI\nelements and I\u0026rsquo;ll actually try and focus\non the hard stuff rather than doing\nthings that are mostly simple\nI chose to clone the existing app rather\nthan building my own since I want to\nshow a professional grade application\nand Uber is pretty much that\nthe goal of this module is to teach the\ntheory of building a professional app\nit\u0026rsquo;s not there for the purpose of\nrebuilding Uber\nare you string boot as usual for the\nserver but I\u0026rsquo;ll try to keep it bare\nit\u0026rsquo;s actually better to do stuff in the\nserver in real world scenarios but in\nthis case I want to focus on client\ndevelopment\nI\u0026rsquo;m trying to create a close clone but\nnot an identical clone\nduring that last bit between identical\nand pretty close is a huge amount of\neffort that doesn\u0026rsquo;t provide a benefit\nin fact it makes things worse because it\nforces the code and designed to be more\nconvoluted\nI will spend a lot of time in the map UI\nand try to explain how to build a decent\nGIS application\nthis isn\u0026rsquo;t a GIS tutorial though as I\u0026rsquo;m\nnot an expert in that field\nI took some shortcuts in building this\napp so hopefully they don\u0026rsquo;t show much\nbefore we start we need to essentially\nunderstand the functionality of uber\neven if you use the app in the past a\nlot of the functionality is pretty\nsubtle and you might have run through it\nwithout noticing\nwe need to grab screenshots of uber\nfeatures that we can review and compare\nto what we are trying to implement\nonce we have those images we can use\nthem to create a mock-up of the Uber UI\nonce the mock-up is in place we can\ncreate a server and then connect the\nwhole thing together\nand fill in the details as we move along\nthis is pretty similar to the process I\nused to build all the apps and the\ncourse as you will notice I prefer\nbuilding the UI first and think it\u0026rsquo;s\nalways the best approach\nwhen we finish the app it should be\nfully working at but you will probably\nneed some work in order to bring it to\nproduction grade I\u0026rsquo;ll try to highlight\nthe bits that are necessary as we move\nthrough the UI\nthere are some great transition\nanimations in the Uber app which you can\nsee here\nI\u0026rsquo;ll go into some details of how we can\nachieve some of them near the end of the\nmodule\nwe\u0026rsquo;ll start by focusing on the basic\nskeleton UI\nnotice that these animations differ\nbetween Android and iOS\nnow let\u0026rsquo;s go into the screenshots I\ncaptured of the Uber application\nthis shows that even a major native app\ncan have ux blunders\nwe have the Uber logo splash screen\nfollowed by a permission prompt for\nlocation\nbut let\u0026rsquo;s move on\nthis is the basic login flow to Uber\none of the first things I checked is the\nlook and landscape mode turns out that\nUber doesn\u0026rsquo;t support that\nthe app is fixed to Portrait on mobile\nphones it doesn\u0026rsquo;t seem to have much\nsupport for tablets either which makes\nsome sense as you would probably not\nhail a cab with a tablet\nthis allows them to simplify some of\ntheir user experience logic and we can\nprobably use a similar approach\nthere are two options for login the\nfirst uses social again through Google\nFacebook\nand that falls to the native login\noption\nthe second one uses SMS style activation\nby collecting the phone number\nwe have support for that in our SMS\nactivation cn1 lib\nthe UI is shown here are all very simple\nclean and minimalistic which should make\nthem very easy to replicate in codename\none\non the right you can see a simple form\nthat allows us to select a country\nif the one we detected isn\u0026rsquo;t correct\nit\u0026rsquo;s pretty simple list with flags and\nsearch\nnotice that when you scroll down in the\nform the title collapses in the material\ndesign style to provide a more compact\nView\nthe SMS activation process works with\nfour digits it doesn\u0026rsquo;t seem to\nautomatically offer to grab the SMS\nwhich is pretty lame\nwe can do better than this I don\u0026rsquo;t\nunderstand why Uber wouldn\u0026rsquo;t do\nsomething better on Android where it\u0026rsquo;s\npossible\none important thing to notice is the way\nthe digit input looks\nthese are four separate digits but they\nhave one error message below\nwhen a number is already active in the\nserver\nyou can use your password and get a\npassword reset form which I didn\u0026rsquo;t\ninclude in the screenshots\nI\u0026rsquo;m not sure I\u0026rsquo;ll go into that level of\ndetail with the implementation\none thing that is missing from the\nscreenshots is the next button progress\neffect which is pretty cool when you\npress the arrow button the screen tints\nand the arrow is surrounded by a\ncircular blue progress bar that should\nbe pretty easy to accomplish in codename\none so it\u0026rsquo;s something I\u0026rsquo;ll try to do as\nwell\nthe UI itself is mostly the map which is\ngreat\nthere are the cause and landmarks\nhighlighted in the map the where to text\nfield isn\u0026rsquo;t really a text field it\u0026rsquo;s a\nbutton\nwhen you click on it you see the search\nform to find directions to order an Uber\nthat you can see in the screenshot next\nto the map\nnotice notices can be swiped from the\nbottom\nthis is a doable element but it\u0026rsquo;s\nnon-trivial so I won\u0026rsquo;t go into it with\nthis app and ignore that specific\nelement\nwe can see two floating buttons of\nrecent searches trips that you can\nrepeat\nthat should be pretty easy to replicate\nas well\nnotice that the side menu icon that just\nfloats with no title to disturb the UI\nof the application\none of the small details is the fact\nthat the menu back button is black\nsurrounded by a white outline\nthat means it will be reasonably visible\nboth on a dark and light map that\u0026rsquo;s a\ngreat attention to detail\nonce we pick a location we can get a UI\nprompt with an order option it also\nshows the direction on the map\nhighlighting my location and destination\nif we open the sign menu we can see the\ndesign is very simple\nI\u0026rsquo;ll skip the Uber for business stuff in\nthe app we make but I\u0026rsquo;ll try to\nreproduce this exact UI design\nnotice how the minimalistic design that\neven skims on colors is able to\nbroadcast Elegance\npayment is a relatively simple you user\nexperience\nI won\u0026rsquo;t go into it at all because we can\njust integrate brain free for billing\nand Skip on some of these complexities\ncredit card billing is problematic not\njust due to technical difficulties but\ndue to liability I wouldn\u0026rsquo;t go into that\nunless I had to\nI won\u0026rsquo;t go into the details of each of\nthese forms notice I blocked out in red\nsome private information about my trip\nthat isn\u0026rsquo;t really important\none thing you should notice is how\nsimple these uis are I won\u0026rsquo;t really get\ninto them but they should be pretty\ntrivial\nthe iOS version is remarkably similar to\nthe Android version both in design and\ntransitions notice that the login form\nhas some pretty cool background rotation\nanimation\nbut other than that only the transitions\ndiffer in the app everything else looks\nidentical\neven the text input and The Floating\nAction button this will make our lives\nmuch easier\u003c/p\u003e","title":"1. Introduction"},{"content":" Module 12: Performance and Memory Tuning\nPerformance problems become much easier to solve once you stop treating them as one category. \u0026ldquo;The app feels slow\u0026rdquo; can mean several very different things, and each one points to a different fix.\nThis lesson makes that distinction well. Rendering problems are not the same as business-logic delays. Memory pressure is not the same as a blocking network call. A UI bug caused by nested scrollables or conflicting focus behavior is not really a performance issue at all, even if the user experiences it as sluggishness.\nThat separation matters because performance work is one of the places where developers burn time most easily. If you start optimizing without identifying which kind of problem you actually have, you usually end up making the code harder to maintain without meaningfully improving the user experience.\nThe lesson also makes an important point about perception. Users do not experience performance as a profiler chart. They experience it as feedback, responsiveness, and confidence that the app is doing something sensible. Cached content, progressive loading, and visible movement toward a result often matter as much as raw timing numbers.\nAnother idea here that deserves repeating is the warning against premature optimization. That advice is not an excuse to ignore performance. It is a reminder to optimize based on evidence. In real applications, a small fraction of the code usually drives most of the measurable pain. Find that fraction first.\nSo the best way to start performance work is to classify the problem. Is it rendering? Is it logic? Is it memory churn? Is it perceived slowness caused by feedback and loading design? Once you answer that, the next steps become much more rational.\nFurther Reading Developer Guide Threading and the EDT How Do I Improve Application Performance Or Track Down Performance Issues ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/038-what-is-performance-breaking-down-the-problem/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Performance and Memory Tuning\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/x-mUTz23Cd4?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003ePerformance problems become much easier to solve once you stop treating them as one category. \u0026ldquo;The app feels slow\u0026rdquo; can mean several very different things, and each one points to a different fix.\u003c/p\u003e\n\u003cp\u003eThis lesson makes that distinction well. Rendering problems are not the same as business-logic delays. Memory pressure is not the same as a blocking network call. A UI bug caused by nested scrollables or conflicting focus behavior is not really a performance issue at all, even if the user experiences it as sluggishness.\u003c/p\u003e","title":"What is Performance? Breaking Down the Problem"},{"content":" Module 12: Creating an Uber Clone\nTranscript let\u0026rsquo;s jump into the code and styling with a mock-up of the final application but before we begin i\u0026rsquo;d like to start by setting up some styles and basic utility methods i\u0026rsquo;ve created a new uber cn1 project and placed it in the package com.codname1.apps.uberclone i gave the main class the name uberclone as well in the main form i\u0026rsquo;d like to highlight three different lines first we have the default gap between the label text and icon which is relatively large in the uber wrap so i\u0026rsquo;ve set it to two millimeters by default next we lock the phone into portrait mode this isn\u0026rsquo;t the only thing we need to use for this finally we show the login form which will get to in the next part we need to install and configure some cn1 lib extensions we\u0026rsquo;ll install more later but for the first part we\u0026rsquo;ll need sms activation for the ui of the country picker we also need google native maps for the map ui support don\u0026rsquo;t forget to set up google maps in the project as mentioned in the maps module as i mentioned before locking your in orientation and code isn\u0026rsquo;t enough for ios in ios we need to define orientation lock in the project level which we can do in the codename one settings ios section some styles are essential to begin with so we need to add the following styles into the theme notice that a lot of these styles are a result of trial and error to get the ui to look like the designs the process of choosing the values boiled down to trying grabbing device screenshots adjusting runes repeat it sounds like a lot of work but it\u0026rsquo;s not too hard as you quickly get a sense of what needs fixing i define form as white which is really the main thing here on android by default they are a bit off-white i defined label as heavily padded with a light font black on white this is consistent with the common use of labels within the app so i\u0026rsquo;ve set foreground to black and background to white i\u0026rsquo;ve set padding to a generous four millimeters as padding is very heavy in the uber the margin is set to zero for almost all of the components here i use standard native light fonts for almost everything as they look great everywhere in this case i chose a 3.2 millimeter font which seems to closely match the dimensions of uber font choices one important thing to mention is that i used derive all on pretty much every style in the theme this works by right clicking a style and selecting derive all once you do that it creates styles for selected pressed disabled that derive from this style that\u0026rsquo;s a very useful starting point it\u0026rsquo;s important even for labels as they can be used in lead components and we\u0026rsquo;d like them to have a common base setting i defined toolbar as transparent without the border that exists on some platforms notice that this doesn\u0026rsquo;t handle them consistent title issue where some forms have a black title area where others have a transparent white title area i will discuss those later i\u0026rsquo;ve set the background to opaque white just to be sure i\u0026rsquo;ve also disabled the border of the base toolbar by explicitly defining it as empty i defined title command as black on white this is a bit problematic with the black toolbar which requires a bit of a hack and code to work the padding numbers are there to make the collapsible toolbar possible this collapse effect featured in several forms such as the country\u0026rsquo;s form margin is zero as usual and the font is relatively large four millimeters this is mostly used to size the back arrow icon and the search icon the side navigation panel is mostly black on white and relatively clean so i\u0026rsquo;ll just define the background as opaque white and ignored the black since that\u0026rsquo;s part of the command we have an underline at the bottom to separate the panel from the south component below so we need to reserve 2 pixels for it in the margin the padding is zero as usual as spacing will come from the commands not from the panel the underline separator from the south component is just an underlying gray border with a thickness of two pixels side command pretty much continues what we started in side navigation panel here we set the foreground to black on transparent color this will be useful with the black toolbar where we will only change the color to leave to white but leave the transparency in place the padding of the style command prevents duplicate padding when commands are one on top of the other which is why the bottom padding is so small margin is zero as usual and the font is again a standard size light font the text field in the uber app is based on the material design simple underlined text field even when running on ios so we need the text field to have an underlying border and work with black on white we define the ui as transparent with a black foreground the padding below is relatively low too so the line won\u0026rsquo;t be too far from the text input the left and right paddings are zero so the text starts will align with the line start the margin serves the role we usually use for padding it spaces out the component the underlying border is pretty simple a black two pixel border however in the selected version of the text field we have a four pixel version of the same border to indicate selection font is a standard three millimeter light font the text hint needs to align with the text field so it\u0026rsquo;s important to override it when we manipulate the text field we use the same padding as text fields i could have derived text field which might have been better a better approach but i didn\u0026rsquo;t want to get into that the margin is again identical to the one in the text field the font size is smaller and regular instead of common light font that looked closer to the choices uber made finally the floating action button which is just white on black nothing else with this we can move forward to creating the mockup although there are some additional styles we\u0026rsquo;ll define during the creation itself\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/039-2-basic-setup/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/-brmZYVWb0Y?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003elet\u0026rsquo;s jump into the code and styling\nwith a mock-up of the final application\nbut before we begin i\u0026rsquo;d like to start by\nsetting up some styles and basic utility\nmethods\ni\u0026rsquo;ve created a new uber cn1 project and\nplaced it in the package\ncom.codname1.apps.uberclone\ni gave the main class the name uberclone\nas well\nin the main form i\u0026rsquo;d like to highlight\nthree different lines\nfirst we have the default gap between\nthe label text and icon\nwhich is relatively large in the uber\nwrap\nso i\u0026rsquo;ve set it to two millimeters by\ndefault\nnext\nwe lock the phone into portrait mode\nthis isn\u0026rsquo;t the only thing we need to use\nfor this\nfinally we show the login form which\nwill get to in the next part\nwe need to install and configure some\ncn1 lib extensions\nwe\u0026rsquo;ll install more later but for the\nfirst part we\u0026rsquo;ll need sms activation\nfor the ui of the country picker\nwe also need google native maps for the\nmap ui support\ndon\u0026rsquo;t forget to set up google maps in\nthe project as mentioned in the maps\nmodule\nas i mentioned before locking your in\norientation and code isn\u0026rsquo;t enough for\nios\nin ios we need to define orientation\nlock in the project level\nwhich we can do in the codename one\nsettings ios section\nsome styles are essential to begin with\nso we need to add the following styles\ninto the theme\nnotice that a lot of these styles are a\nresult of trial and error to get the ui\nto look like the designs\nthe process of choosing the values\nboiled down to trying grabbing device\nscreenshots adjusting runes repeat\nit sounds like a lot of work but it\u0026rsquo;s\nnot too hard as you quickly get a sense\nof what needs fixing\ni define form as white\nwhich is really the main thing here\non android by default they are a bit\noff-white\ni defined label as heavily padded with a\nlight font\nblack on white\nthis is consistent with the common use\nof labels within the app\nso i\u0026rsquo;ve set foreground to black and\nbackground to white\ni\u0026rsquo;ve set padding to a generous four\nmillimeters as padding is very heavy in\nthe uber\nthe margin is set to zero for almost all\nof the components here\ni use standard native light fonts for\nalmost everything as they look great\neverywhere in this case i chose a 3.2\nmillimeter font\nwhich seems to closely match the\ndimensions of uber font choices\none important thing to mention is that i\nused derive all on pretty much every\nstyle in the theme\nthis works by right clicking a style and\nselecting derive all\nonce you do that it creates styles for\nselected pressed disabled\nthat derive from this style\nthat\u0026rsquo;s a very useful starting point it\u0026rsquo;s\nimportant even for labels as they can be\nused in lead components and we\u0026rsquo;d like\nthem to have a common base setting\ni defined toolbar as transparent without\nthe border that exists on some platforms\nnotice that this doesn\u0026rsquo;t handle them\nconsistent title issue\nwhere some forms have a black title area\nwhere others have a transparent white\ntitle area\ni will discuss those later\ni\u0026rsquo;ve set the background to opaque white\njust to be sure\ni\u0026rsquo;ve also disabled the border of the\nbase toolbar by explicitly defining it\nas empty\ni defined title command\nas black on white\nthis is a bit problematic with the black\ntoolbar which requires\na bit of a hack and code to work\nthe padding numbers are there to make\nthe collapsible toolbar possible\nthis collapse effect featured\nin several forms such as the country\u0026rsquo;s\nform\nmargin is zero as usual\nand the font is relatively large\nfour millimeters this is mostly used to\nsize\nthe back arrow icon\nand the search icon\nthe side navigation panel is mostly\nblack on white and relatively clean so\ni\u0026rsquo;ll just define the background as\nopaque white and ignored the black since\nthat\u0026rsquo;s part of the command\nwe have an underline at the bottom to\nseparate the panel from the south\ncomponent below\nso we need to reserve 2 pixels for it in\nthe margin\nthe padding is zero as usual\nas spacing will come from the commands\nnot from the panel\nthe underline separator from the south\ncomponent is just an underlying gray\nborder with a thickness of two pixels\nside command pretty much continues what\nwe started in side navigation panel\nhere we set the foreground to black on\ntransparent color\nthis will be useful with the black\ntoolbar where we will only change the\ncolor to leave\nto white but leave the transparency in\nplace\nthe padding of the style command\nprevents duplicate padding when commands\nare one on top of the other which is why\nthe bottom padding is so small\nmargin is zero as usual\nand the font is again a standard size\nlight font\nthe text field in the uber app is based\non the material design simple underlined\ntext field even when running on ios\nso we need the text field to have an\nunderlying border and work with black on\nwhite\nwe define the ui as transparent with a\nblack foreground\nthe padding below is relatively low\ntoo so the line won\u0026rsquo;t be too far from\nthe text input\nthe left and right paddings are zero so\nthe text starts\nwill align with the line start\nthe margin serves the role we usually\nuse for padding\nit spaces out the component\nthe underlying border is pretty simple a\nblack\ntwo pixel border\nhowever in the selected version of the\ntext field we have a four pixel version\nof the same border to indicate selection\nfont is a standard three millimeter\nlight font\nthe text hint needs to align with the\ntext field\nso it\u0026rsquo;s important to override it when we\nmanipulate the text field\nwe use the same padding as text fields i\ncould have derived text field which\nmight have been better a better approach\nbut i didn\u0026rsquo;t want to get into that\nthe margin is again identical to the one\nin the text field\nthe font size is smaller and regular\ninstead of common light font\nthat looked closer to the choices uber\nmade\nfinally the floating action button which\nis just white on black nothing else\nwith this we can move forward to\ncreating the mockup\nalthough there are some additional\nstyles we\u0026rsquo;ll define during the creation\nitself\u003c/p\u003e","title":"2. Basic Setup"},{"content":" Module 12: Performance and Memory Tuning\nIf there is one performance rule that deserves to be repeated until it becomes reflex, it is this: do not block the EDT. Most performance advice in Codename One eventually comes back to that point, because the EDT owns interaction and painting. When you make it wait, the whole application feels worse no matter how efficient the rest of the code may be.\nThat does not mean \u0026ldquo;move everything to another thread and hope for the best.\u0026rdquo; Background work still competes for CPU time. On mobile hardware especially, a badly behaved background task can starve the UI just as effectively as work on the EDT if it burns enough processor time. So good threading is not just about moving work away from the UI. It is about moving it away responsibly.\nThe lesson\u0026rsquo;s discussion of invokeAndBlock, callSerially, and idle-time work points to the real trade-off: convenience versus control. Sometimes a blocking abstraction makes code easier to write. Sometimes a cleaner callback or explicit background thread is the better choice. The right answer depends on how much work is being done and how sensitive the interaction needs to feel.\nCaching is the other half of the story. In practice, many of the biggest performance wins come from caching the right thing in the right place. But caching also creates memory pressure, and memory pressure causes its own performance problems. That is why there is no universal answer to questions like \u0026ldquo;should I cache this image or this component?\u0026rdquo; The cost depends on what gets duplicated, how often it is reused, and how aggressively memory needs to be reclaimed on target devices.\nThis is where soft references and other reclaimable caches become useful. They let the application benefit from reuse when memory is available without insisting on holding everything forever. The point is not to be clever for its own sake. It is to keep the application responsive while avoiding wasteful re-creation of expensive objects.\nThe lesson\u0026rsquo;s advice on form reuse is also still relevant. Reusing a form is often simpler and smoother than rebuilding it constantly, but that stops being true if the form drags along a huge memory footprint full of heavyweight images or other costly state. Performance work is always about choosing where to pay.\nSo the practical takeaway is this: keep the EDT lean, use threads deliberately, and treat caching as a measured optimization rather than a reflex. Most performance tuning becomes easier once those three habits are in place.\nFurther Reading Threading and the EDT What is Performance? Breaking Down the Problem How Do I Improve Application Performance Or Track Down Performance Issues ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/039-edt-threading-caching-and-soft-references/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Performance and Memory Tuning\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/85MyytvMS9I?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eIf there is one performance rule that deserves to be repeated until it becomes reflex, it is this: do not block the EDT. Most performance advice in Codename One eventually comes back to that point, because the EDT owns interaction and painting. When you make it wait, the whole application feels worse no matter how efficient the rest of the code may be.\u003c/p\u003e","title":"EDT, Threading, Caching and Soft References"},{"content":" Module 12: Creating an Uber Clone\nTranscript in this part we\u0026rsquo;ll create a mock-up for some of the forms starting with the login process we\u0026rsquo;ll start with the login form since the uber app is portrait locked it should be pretty easy to produce this ui however we\u0026rsquo;ll first start with one element and that\u0026rsquo;s the country button the reason it\u0026rsquo;s logistically separate is that it has some non-trivial logic and resides in two separate forms so it makes sense to define it in a single generic class the country code picker is a button subclass but it doesn\u0026rsquo;t really look like it because we set the uid to the country code picker ui id in this block of code we try to guess the current country based on the localization settings the flags.res file is included in the sms activation cn1 lib it\u0026rsquo;s a bit of an implementation detail so this code might break in the future if so we might need to copy the res file from there or update the code we don\u0026rsquo;t have all the flags for all the countries without a blank icon the alignment might seem broken so it\u0026rsquo;s crucial to have this show picker form is useful for overriding in the login form clicking this button should lead to a different form however there is a lot more going on here the cover transition collides with the default slide transition producing a weird effect so here we keep the transition instance remove the out transition so the cover effect will work properly we then bind a show listener that restores the old transition after we are done that\u0026rsquo;s important for when the user will click to move to the next form the styling for country code picker are pretty simple it\u0026rsquo;s black on transparent background the padding is big on the left but small on the right so the text element stays near the button margin is again zero and the font is pretty standard light three millimeter font so without further ado let\u0026rsquo;s go to the login form code this is the code of the first form you will see when the uber app launches it\u0026rsquo;s a relatively simple class without too many frills let\u0026rsquo;s go over a few elements of note initially i wrote the word uber without the right font it looked weird using an image for a logo is generally the best approach i want the logo to be square so height and width should be identical we place the entire tile section and logo in the center of the form so they will take up the available space we place the logo itself in the absolute center so it will float in the middle i override the behavior of the country picker button for consistency with the native uber app this looks like a text field but acts like a button in the native app so i implemented it as such considering the rows and size is important for proper layout the rest of the ui is relegated to the south of the form this would have issues in landscape mode but since the app is portray clocked this shouldn\u0026rsquo;t be a problem we need these two images to complete the form ui the tile png and uberlogo.png there are a few styles we need to define in order to finish this form the square logo ui id is used for the logo i still have the foreground defined as this is this used to be text and not an image the main thing here are the white opaque background we use some white padding on the logo but we don\u0026rsquo;t need margin the logo background style represents the pattern tile in behind the logo this is pretty easy to accomplish once we have the tile.png file we can style it to tile on both asus we set the transparency to 255 as the image is opaque and we want to make sure this is totally opaque we define the margin to zero as usual notice we ignore padding as it just doesn\u0026rsquo;t matter for this component the get moving with uber ui id just sets the padding to a right size so it\u0026rsquo;s spaced enough from the sides but close enough to the element below we don\u0026rsquo;t need margin color or anything else because we derive from label the main reason for this ui id is the large dominating 4.8 millimeter font size the phone number hint represents the text that looks like a hint next to the flag when we move to the next form it actually becomes the real hint text it\u0026rsquo;s gray with no background it has zero padding on the left to keep it close to the country picker button the font is 3.7 millimeters which looked right after some trial and error the separator ui id is a container which has an underline below it as a container we define it as a as completely transparent it has a two pixel bottom padding to leave space for the underline the margin is zero as usual the border is an underlying two pixel border in a gray color the connect with social button is the button at the bottom of the ui it looks like a label but has a bluish color i need to define the padding even though it should be derived from label as deriving from built-in types isn\u0026rsquo;t always 100 reliable i could have worked around it by defining a my label uiid and deriving from that i still chose to derive from label which mostly works but i define the font just to be on the safe side this is the ui we\u0026rsquo;ve made next to the native uber ui you will notice some minor differences mostly with fonts not being pixel perfect i didn\u0026rsquo;t aim for perfection with fonts as that can be endless there are some other nuances i\u0026rsquo;ll go into\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/040-3-login-and-country-code/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/Cc8YG-_M02M?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ein this part we\u0026rsquo;ll create a mock-up for\nsome of the forms starting with the\nlogin process\nwe\u0026rsquo;ll start with the login form\nsince the uber app is portrait locked it\nshould be pretty easy to produce this ui\nhowever\nwe\u0026rsquo;ll first start with one element and\nthat\u0026rsquo;s the country button\nthe reason it\u0026rsquo;s logistically separate\nis that it has some non-trivial logic\nand resides in two separate forms\nso it makes sense to define it\nin a single generic class\nthe country code picker\nis a button subclass\nbut it doesn\u0026rsquo;t really look like it\nbecause we set the uid\nto the country code picker ui id\nin this block of code we try to guess\nthe current country based on the\nlocalization settings\nthe flags.res file is included in the\nsms activation cn1 lib it\u0026rsquo;s a bit of an\nimplementation detail so this code might\nbreak in the future\nif so we might need to copy the res file\nfrom there or update the code\nwe don\u0026rsquo;t have all the flags for all the\ncountries\nwithout a blank icon\nthe alignment might seem broken\nso it\u0026rsquo;s crucial to have\nthis show picker form\nis useful for overriding\nin the login form clicking this button\nshould lead to a different form\nhowever\nthere is a lot more going on here the\ncover transition\ncollides with the default slide\ntransition producing a weird effect\nso here we keep the transition instance\nremove the out transition so the cover\neffect will work properly\nwe then bind a show listener that\nrestores the old transition\nafter we are done\nthat\u0026rsquo;s important for when the user will\nclick to move to the next form\nthe styling for country code picker\nare pretty simple\nit\u0026rsquo;s black on transparent\nbackground the padding is big on the\nleft but small on the right so the text\nelement stays near the button\nmargin is again zero\nand the font is pretty standard\nlight three millimeter font\nso without further ado let\u0026rsquo;s go to the\nlogin form code\nthis is the code of the first form you\nwill see when the uber app launches\nit\u0026rsquo;s a relatively simple class without\ntoo many frills\nlet\u0026rsquo;s go over a few elements of note\ninitially i wrote the word uber without\nthe right font it looked weird\nusing an image for a logo is generally\nthe best approach\ni want the logo to be square\nso\nheight and width should be identical\nwe place the entire tile section and\nlogo\nin the center of the form so they will\ntake up the available space\nwe place the logo itself\nin the absolute center so it will float\nin the middle\ni override the behavior of the country\npicker button\nfor consistency with the native uber app\nthis looks like a text field but acts\nlike a button\nin the native app so i implemented it as\nsuch\nconsidering the rows and size\nis important for proper layout\nthe rest of the ui is relegated to the\nsouth of the form\nthis would have issues in landscape mode\nbut since the app is portray clocked\nthis shouldn\u0026rsquo;t be a problem\nwe need\nthese two images to complete the form ui\nthe tile png\nand uberlogo.png\nthere are a few styles we need to define\nin order to finish this form\nthe square logo ui id\nis used for the logo\ni still have the foreground defined as\nthis is\nthis used to be text and not an image\nthe main thing here\nare the white opaque background\nwe use some white padding on the logo\nbut we don\u0026rsquo;t need margin\nthe logo background style represents the\npattern tile\nin behind the logo\nthis is pretty easy to accomplish\nonce we have the tile.png file\nwe can style it to tile on both asus\nwe set the transparency to 255\nas the image is opaque and we want to\nmake sure\nthis is totally opaque\nwe define the margin to zero as usual\nnotice we ignore padding as it just\ndoesn\u0026rsquo;t matter for this component\nthe get moving with uber ui id just sets\nthe padding to a right size so it\u0026rsquo;s\nspaced enough from the sides but close\nenough to the element below\nwe don\u0026rsquo;t need margin color or anything\nelse because we derive from label\nthe main reason for this ui id\nis the large dominating 4.8 millimeter\nfont size\nthe phone number hint represents the\ntext that looks like a hint next to the\nflag\nwhen we move to the next form it\nactually becomes the real hint text\nit\u0026rsquo;s gray with no background\nit has zero padding on the left to keep\nit close to the country picker button\nthe font is 3.7 millimeters which looked\nright after some trial and error\nthe separator ui id is a container\nwhich has an underline below it\nas a container we define it as a as\ncompletely transparent\nit has a two pixel bottom padding to\nleave space for the underline\nthe margin is zero as usual\nthe border is an underlying two pixel\nborder in a gray color\nthe connect with social button is the\nbutton at the bottom of the ui it looks\nlike a label but has a bluish color\ni need to define the padding even though\nit should be derived from label as\nderiving from built-in types isn\u0026rsquo;t\nalways 100 reliable\ni could have worked around it by\ndefining a my label uiid and deriving\nfrom that\ni still chose to derive from label\nwhich mostly works\nbut i define the font\njust to be on the safe side\nthis is the ui we\u0026rsquo;ve made next to the\nnative uber ui you will notice some\nminor differences mostly with fonts not\nbeing pixel perfect\ni didn\u0026rsquo;t aim for perfection with fonts\nas that can be endless\nthere are some other nuances i\u0026rsquo;ll go\ninto\u003c/p\u003e","title":"3. Login and Country Code"},{"content":" Module 12: Performance and Memory Tuning\nImages are often the biggest single contributor to both application size and runtime memory pressure. That means image choices are not just aesthetic or API-level decisions. They are core performance decisions.\nThe key lesson here is that not all image representations cost the same thing. Some image types are fast to draw but expensive in memory. Others are compact until decoded, but pay a cost when they need to expand into drawable form. Still others exist mainly to support specific low-level use cases and should not be your default tool.\nEncoded images are especially important in Codename One because they are the workhorse of practical memory management. The image can stay compact while idle and expand when actually needed. That makes them a strong fit for many UI situations, especially when the alternative is keeping a large decoded image resident all the time. But that benefit comes with a new responsibility: understand when an image should stay locked in memory and when it should be allowed to fall out of cache.\nThis is where many performance issues become subtle. A decoded image may render smoothly because it stays warm in memory, but too many of those images can cause memory pressure and cache churn elsewhere. An encoded image may be smaller overall, but if it is constantly being re-decoded during active use, the app can feel sluggish. The right answer depends on how often the image is used and whether it is central to the current screen.\nThe broader point is that image optimization is not just about file size. Runtime footprint matters just as much, and the simple width-times-height-times-four mental model is still a useful way to estimate the cost of keeping decoded images alive.\nFor modern projects, this lesson pairs well with the general advice to keep styling in CSS and use icon fonts or vector-friendly approaches where possible. Every place where an image can be replaced by a cheaper or more flexible representation is one less place where you have to pay this memory/performance trade-off.\nFurther Reading Themeing How Do I Fetch An Image From The Resource File, Add A Multiimage What is Performance? Breaking Down the Problem ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/040-the-different-image-types-and-their-impact-on-performance-ram/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Performance and Memory Tuning\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/DWifLQZyPDE?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eImages are often the biggest single contributor to both application size and runtime memory pressure. That means image choices are not just aesthetic or API-level decisions. They are core performance decisions.\u003c/p\u003e\n\u003cp\u003eThe key lesson here is that not all image representations cost the same thing. Some image types are fast to draw but expensive in memory. Others are compact until decoded, but pay a cost when they need to expand into drawable form. Still others exist mainly to support specific low-level use cases and should not be your default tool.\u003c/p\u003e","title":"The Different Image Types and Their Impact on Performance/RAM"},{"content":" Module 12: Creating an Uber Clone\nTranscript in this part we\u0026rsquo;ll refine the login form and go into low-level graphics for animation and background this is how i finished the previous part i discussed the fonts but there are other differences obviously the flag is slightly different since i used our own resource file but there are two other noticeable differences the first is the drop shadow behind the logo which is missing the second is the background rotation of the pattern which is ios specific in the native app but i don\u0026rsquo;t see a reason for that i\u0026rsquo;d like to have it on android too the simplest thing to do is generate a square image of the logo that already has a translucent shadow within this would be pretty trivial to anyone versed in photoshop and would look great on the device however my goal is to teach programming not photoshop so i\u0026rsquo;m picking the hard way of solving this the effects class in codename one allows us to create a shadow image for the given dimensions or image since the logo is square we can just use the dimensions approach the method accepts the size of the shadow the blur radius which means how far it should go out of the size limits and the opacity as a value between 0 and 1. so now we have an image of the shadow but the logo image and the background are already fixed so we need something new instead of using the logo as it is we place the shadow in a layer below using the layered layout and this will produce the desired effect with one huge caveat it\u0026rsquo;s really slow shadows are computationally slow we use gaussian blur to generate shadows and that\u0026rsquo;s a very slow algorithm the solution is to move that code offline the ui will appear and the shadow will appear a second later when it\u0026rsquo;s ready the placeholder is there so we can put the shadow into place when it\u0026rsquo;s ready when the shadow image is ready we replace it on the edt with the new shadow label the label uses the container ui id which is always transparent with zero padding and zero margin the android version of uber doesn\u0026rsquo;t include the rotation animation for reasons that are just unclear to me i think it might collide with some of the material design transitions or some other problem it works nicely on all os\u0026rsquo;s with the way i implemented it i could just rotate the tiles like the one pictured above and call it a day the effect would look decent and perform well however i wanted better control and in order to get that i need shapes shapes allow us to draw arbitrary vectors curves in a performant way since this is effectively a vector api rotation and scaling don\u0026rsquo;t distort the result in order to use this api i need to use the low level graphics api and the background painter we can set the painter for the logo object using this code notice that normally we don\u0026rsquo;t need a reference to the parent component logo but in this case we need it for the animation i\u0026rsquo;ll go into that soon but first i\u0026rsquo;d like to say a few words about painters styling can only go so far if you want to customize the background of a component in a completely custom way you can use the painter api to define the actual rendering of the background this overrides all style rendering and provides you with a graphic object you can use for drawing notice that the graphics api is a low level api and might have platform specific behaviors that aren\u0026rsquo;t as refined as the component style apis it\u0026rsquo;s harder to optimize low-level graphics code so use it with caution now that we got this out of the way let\u0026rsquo;s look at the painter code itself this is the rotation angle in degrees we increment this as part of the animation logic this is the shape object representing the background pattern we draw it or stroke it like a rubber stamp the constructor and the draw shape method create the pattern shape that we stroke later this code happens once to generate the lines and we then color them later on the register animated method of form is needed for low-level animations it triggers invocations of the animate method with every edt tick so we can update the animation state in this case we change the rotation angle with every tick the draw shape method adds logical lines and quads to the given path a quad means quadratic curve to the given position you can see three methods used on the path element move two moves the virtual pen in the air without drawing anything to a starting point line two draws a line from the last position of the pen to the given position quad 2 draws a quadratic curve bezier curve to the given position through the given curve position the paint method is the callback from the painter we fill the background rotate the graphics context and draw the shapes notice we just invoke draw shape and it draws with the current alpha and color in place the low level animation code invokes animate at fixed intervals based on edt heartbeats normally you would return true to trigger a repaint but here i only want to repaint a specific component notice that i only change the angle and move every other frame to conserve cpu also notice i rotate by 0.1 degrees which creates a very smooth slow and subtle rotation this paint method belongs to the animation interface we don\u0026rsquo;t need it as we always return force once all of this is done the login ui rotates in the background slowly and smoothly a shadow appears after a second and the ui looks in my opinion as good as the native ui\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/041-4-login-shadow-and-rotation/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/owhInk5YAtg?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ein this part we\u0026rsquo;ll refine the login form\nand go into low-level graphics for\nanimation and background\nthis is how i finished the previous part\ni discussed the fonts but there are\nother differences\nobviously the flag is slightly different\nsince i used our own resource file\nbut there are two other noticeable\ndifferences\nthe first is the drop shadow behind the\nlogo which is missing\nthe second is the background rotation of\nthe pattern which is ios specific in the\nnative app but i don\u0026rsquo;t see a reason for\nthat\ni\u0026rsquo;d like to have it on android too\nthe simplest thing to do is generate a\nsquare image of the logo\nthat already has a translucent shadow\nwithin\nthis would be pretty trivial to anyone\nversed in photoshop and would look great\non the device\nhowever my goal is to teach programming\nnot photoshop\nso i\u0026rsquo;m picking the hard way of solving\nthis\nthe effects class in codename one allows\nus to create a shadow image for the\ngiven dimensions or image\nsince the logo is square we can just use\nthe dimensions approach\nthe method accepts the size of the\nshadow\nthe blur radius which means how far it\nshould go out of the size limits\nand the opacity\nas a value between\n0 and 1.\nso now we have an image\nof the shadow\nbut the logo image and the background\nare already fixed so we need something\nnew\ninstead of using the logo as it is\nwe place the shadow in a layer below\nusing the layered layout\nand this will produce the desired effect\nwith one huge caveat\nit\u0026rsquo;s really slow\nshadows are computationally slow\nwe use\ngaussian blur to generate shadows and\nthat\u0026rsquo;s a very slow algorithm\nthe solution is to move that code\noffline the ui will appear and the\nshadow will appear a second later\nwhen it\u0026rsquo;s ready the placeholder is there\nso we can put the shadow into place\nwhen it\u0026rsquo;s ready\nwhen the shadow image is ready\nwe replace it on the edt with the new\nshadow label\nthe label uses the container ui id\nwhich is always transparent with zero\npadding\nand zero margin\nthe android version of uber doesn\u0026rsquo;t\ninclude the rotation animation for\nreasons that are just unclear to me\ni think it might collide with some of\nthe material design transitions or some\nother problem\nit works nicely on all os\u0026rsquo;s with the way\ni implemented it\ni could just rotate the tiles like\nthe one pictured above and call it a day\nthe effect would look decent and perform\nwell\nhowever i wanted better control\nand in order to get that i need shapes\nshapes allow us to draw arbitrary\nvectors curves\nin a performant way\nsince this is effectively a vector api\nrotation and scaling don\u0026rsquo;t distort the\nresult\nin order to use this api i need to use\nthe low level graphics api\nand the background painter\nwe can set the painter for the logo\nobject using this code\nnotice that normally we don\u0026rsquo;t need a\nreference to the parent component logo\nbut in this case we need it for the\nanimation\ni\u0026rsquo;ll go into that soon\nbut first i\u0026rsquo;d like to say a few words\nabout painters\nstyling can only go so far\nif you want to customize the background\nof a component in a completely custom\nway\nyou can use the painter api to define\nthe actual rendering of the background\nthis overrides all style rendering and\nprovides you with a graphic object\nyou can use for drawing\nnotice that the graphics api is a low\nlevel api and might have platform\nspecific behaviors that aren\u0026rsquo;t as\nrefined as the component style apis\nit\u0026rsquo;s harder to optimize low-level\ngraphics code so use it with caution\nnow that we got this out of the way\nlet\u0026rsquo;s look at the painter code itself\nthis is the rotation angle in degrees\nwe increment this as part of the\nanimation logic\nthis is the shape object representing\nthe background pattern\nwe draw it or stroke it like a rubber\nstamp\nthe constructor and the draw shape\nmethod\ncreate the pattern shape that we stroke\nlater\nthis code happens once to generate the\nlines\nand we then color them later on\nthe register animated method of form is\nneeded for low-level animations\nit triggers invocations of the animate\nmethod with every\nedt tick\nso we can update the animation state\nin this case we change the rotation\nangle with every tick\nthe draw shape method\nadds logical lines and quads to the\ngiven path\na quad means quadratic curve to the\ngiven position you can see three methods\nused on the path element\nmove two\nmoves the virtual pen in the air without\ndrawing anything to a starting point\nline two draws a line from the last\nposition of the pen to the given\nposition\nquad 2\ndraws a quadratic curve\nbezier curve to the given position\nthrough the given curve position\nthe paint method\nis the callback from the painter\nwe fill the background rotate the\ngraphics context and draw the shapes\nnotice we just invoke draw shape and it\ndraws with the current alpha and color\nin place\nthe low level animation code invokes\nanimate at fixed intervals based on edt\nheartbeats\nnormally you would return true to\ntrigger a repaint but here i only want\nto repaint a specific component\nnotice that i only change the angle and\nmove every\nother frame to conserve cpu\nalso notice i rotate by 0.1 degrees\nwhich creates a very smooth slow and\nsubtle\nrotation\nthis paint method belongs to the\nanimation interface\nwe don\u0026rsquo;t need it as we always return\nforce\nonce all of this is done the login ui\nrotates in the background slowly and\nsmoothly a shadow appears after a second\nand the ui looks in my opinion as good\nas the native ui\u003c/p\u003e","title":"4. Login Shadow and Rotation"},{"content":" Module 12: Performance and Memory Tuning\nPerformance problems do not always come from one obviously slow algorithm. Just as often they come from structural choices that look harmless until the app scales a little. Lists, parsing location, overdraw, network threading, and resource-file bloat all fall into that category.\nThe first useful point in this lesson is that List is not automatically the fast answer just because it has a reusable-cell architecture. On mobile, huge endlessly scrollable datasets are often the wrong interaction model in the first place, and smaller data sets can frequently be handled more cleanly with other UI structures. Performance is one reason, but usability is another.\nOverdraw is another example of a problem that is easy to ignore until it starts hurting. Drawing the same region several times is normal to a point, but too much layered opacity and background painting can create unnecessary rendering cost. That is why inspecting component hierarchy and reducing unnecessary opaque layers can matter so much.\nThe lesson is also right to push parsing and similar work off the EDT when possible. If a network response arrives quickly but the JSON parsing happens on the EDT, the user still experiences a slow app. Getting the work off the UI thread does not just improve raw performance. It protects the user\u0026rsquo;s sense that the app is alive.\nResource-file size deserves equal attention because large resources hurt more than one stage of the product. They make downloads heavier, builds larger, memory use worse, and startup or asset loading less predictable. In practice, most of that size is usually images, especially multiple density variants. So the most effective optimization is often to identify the biggest offenders rather than trying to shave a few bytes from everything.\nThis lesson is really a collection of reminders that performance is often about architecture and asset discipline, not just low-level code tricks. If the lists are appropriate, the parsing happens in the right place, and the resources stay under control, many other problems become much easier to manage.\nFurther Reading What is Performance? Breaking Down the Problem How Do I Create A List Of Items The Easy Way How Do I Fetch An Image From The Resource File, Add A Multiimage ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/041-list-network-parsing-and-resource-file-size/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Performance and Memory Tuning\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/ZEe_hb1Lz6Y?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003ePerformance problems do not always come from one obviously slow algorithm. Just as often they come from structural choices that look harmless until the app scales a little. Lists, parsing location, overdraw, network threading, and resource-file bloat all fall into that category.\u003c/p\u003e","title":"List, Network, Parsing and Resource File Size"},{"content":" Module 12: Creating an Uber Clone\nTranscript in this part we\u0026rsquo;ll finally leave the confines of the login form and move to the simple forms of social login and the country picker ui i\u0026rsquo;ll start with the social login markup since it\u0026rsquo;s so small and simple this is the form you see when you choose the social login option i crop the bottom as it\u0026rsquo;s just white this is a pretty trivial ui there isn\u0026rsquo;t that much to say about this form it\u0026rsquo;s trivial we use two icons for facebook and google and define the back arrow thanks to all the theming work we did up to this point everything just works and looks like the uber app we do need to define the flag button though as it\u0026rsquo;s a ui id that i reused in several forms it got the name from the country\u0026rsquo;s picker form which we\u0026rsquo;ll go into next the flag button is just a label in terms of padding etc it has a sub subtly larger font at 3.2 millimeters not much larger the country picker form lists the countries next to their flags the first letter of the country name is highlighted between the countries and when you scroll down the title area collapses to make more room it does that with a smooth animation effect speaking of the title area it\u0026rsquo;s white on black instead of black on white we reach this form when we click the country picker button but that only happens in the phone number entry form which we will discuss shortly let\u0026rsquo;s jump right into the code predictably the form is a box layout container on the y axis the init black title form method is a static method in a common utility class we\u0026rsquo;ll cover it soon we don\u0026rsquo;t have flags for all the countries so we need a blank space icon so the elements align here we loop over all the country codes and create a button with the flag letter ui id for every entry we also need to implement the alphabet letter headers every time the first character of a country changes we add a label representing the entry when an entry is selected we update the text and icon of the country code pickup button that launched this form we need to override the toolbar initialization so we can set the proper black toolbar ui id speaking of the black toolbar it is predictably styled as black and opaque we have a one millimeter padding which doesn\u0026rsquo;t exist in the default toolbar it\u0026rsquo;s helpful for the collapse animation effect so padding still remains the margin is zero as usual flag\u0026rsquo;s letter is the letter that appears on top of every letter change between country names the colors and the opacity are things are picked from the screenshot image the other aspects of this ui are derived from label the form with the black title requires some work which should be more generic as a black title area is used in several places within the uber application for this purpose we have the common code class which stores common static code in the application this is a non-trivial task as the logic needs to support animated collapse of the title area as the user scrolls down the method accepts a callback for the case of a search operation this isn\u0026rsquo;t implemented yet but if it\u0026rsquo;s null a search icon isn\u0026rsquo;t added we add the back command as a button which allows us to place it above the title in a custom way and animate the position we can\u0026rsquo;t use the title command uiid as is since it uses a black on white scheme in other forms i could have used a different ui id here if we have a search callback i build the layout that includes the search button otherwise i create a layout without it i place the title on top of the back button container using a layered layout it doesn\u0026rsquo;t seem to be on top because i\u0026rsquo;ve set the top margin so it resides below the black arrow icon i did this so i can animate the position of the label fluidly by changing the margin value the this one line allows the title to collapse into place next to the arrow it translates the style of the title which currently has a large top margin to one without top margin and with side margin this means that the change in the style causes the title to move next to the back arrow cover transition is used in the back title form on ios notice that cover transitions expect in and out values for cover and uncover the white on black title is a white title style and as the name suggests it has white foreground and a transparent background as the black portion comes from the black toolbar ui id the padding is pretty standard these numbers were picked to align properly with the commands both in expanded and collapsed states the margin is actually zero as we change this manually and code it might make sense to do the margin here for some cases the font is standard light font but four millimeters in size which should appear bigger but not huge subtle the left margin version of the style does define the side margin to leave room for the arrow this means that the collapse animation will mutate into this ui id which has no top margin so it will effectively align with the back arrow however the left margin will keep it from going on on top of the arrow it also evens out the padding so things look more aligned now that they are on the same row derive the white on black title ui id so the settings we don\u0026rsquo;t override are identical the font is the same but a smaller three millimeter size this will also animate as the title slides into place it\u0026rsquo;s subtle but noticeable\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/042-5-social-login-and-country-picker/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/gM-InTtdhVE?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ein this part we\u0026rsquo;ll finally leave the\nconfines of the login form\nand move to the simple forms of social\nlogin and the country picker ui\ni\u0026rsquo;ll start with the social login markup\nsince it\u0026rsquo;s so small and simple\nthis is the form you see when you choose\nthe social login option\ni crop the bottom as it\u0026rsquo;s just white\nthis is a pretty trivial ui\nthere isn\u0026rsquo;t that much to say about this\nform it\u0026rsquo;s trivial\nwe use two icons for facebook and google\nand define the back arrow\nthanks to all the theming work we did up\nto this point everything just works and\nlooks like the uber app\nwe do need to define the flag button\nthough\nas it\u0026rsquo;s a ui id that i reused in several\nforms\nit got the name from the country\u0026rsquo;s\npicker form which we\u0026rsquo;ll go into next\nthe flag button is just a label in terms\nof padding etc\nit has a sub\nsubtly larger font at 3.2 millimeters\nnot much larger\nthe country picker form\nlists the countries next to their flags\nthe first letter of the country name is\nhighlighted between the countries and\nwhen you scroll down the title area\ncollapses to make more room\nit does that with a smooth animation\neffect\nspeaking of the title area it\u0026rsquo;s white on\nblack instead of black on white\nwe reach this form when we click the\ncountry picker button but that only\nhappens in the phone number entry form\nwhich we will discuss shortly\nlet\u0026rsquo;s jump right into the code\npredictably the form is a box layout\ncontainer on the y axis\nthe init black title form method is a\nstatic method in a common utility class\nwe\u0026rsquo;ll cover it soon\nwe don\u0026rsquo;t have flags for all the\ncountries so we need a blank space icon\nso the elements align\nhere we loop over all the country codes\nand create a button with the flag\nletter ui id for every entry we also\nneed to implement the alphabet letter\nheaders\nevery time the first character of a\ncountry changes we add a label\nrepresenting the entry\nwhen an entry is selected\nwe update the text and icon of the\ncountry code pickup button that launched\nthis form\nwe need to override the toolbar\ninitialization so we can set the proper\nblack toolbar ui\nid speaking of the black toolbar\nit is predictably styled as black and\nopaque\nwe have a one millimeter padding which\ndoesn\u0026rsquo;t exist in the default toolbar\nit\u0026rsquo;s helpful for the collapse animation\neffect so\npadding still remains\nthe margin is zero as usual\nflag\u0026rsquo;s letter is the letter that appears\non top of every\nletter change between country names\nthe colors\nand the opacity are things are picked\nfrom the screenshot image\nthe other aspects of this ui are derived\nfrom label\nthe form with the black title requires\nsome work which should be more generic\nas a black title area is used in several\nplaces within the uber application\nfor this purpose we have the common code\nclass which stores common static code in\nthe application\nthis is a non-trivial task as the logic\nneeds to support animated collapse of\nthe title area as the user scrolls down\nthe method accepts a callback for the\ncase of a search operation\nthis isn\u0026rsquo;t implemented yet\nbut\nif it\u0026rsquo;s null\na search icon isn\u0026rsquo;t added\nwe add the\nback command\nas a button\nwhich allows us to place it above the\ntitle in a custom way and animate the\nposition\nwe can\u0026rsquo;t use the title command uiid\nas is\nsince it uses a black on white scheme\nin other forms\ni could have used a different ui id here\nif we have a search callback\ni build the layout that includes the\nsearch\nbutton otherwise i create a layout\nwithout it\ni place the title on top of the back\nbutton container using a layered layout\nit doesn\u0026rsquo;t seem to be on top because\ni\u0026rsquo;ve set the top margin so it resides\nbelow the black\narrow icon\ni did this so i can animate the position\nof the label fluidly by changing the\nmargin value\nthe this one line allows the title to\ncollapse into place next to the arrow it\ntranslates the style of the title which\ncurrently has a large top margin\nto one without top margin and with side\nmargin\nthis means that the change in the style\ncauses the title to move next to the\nback arrow\ncover transition is used in the back\ntitle form on ios\nnotice that cover transitions expect in\nand out values for cover and uncover\nthe white on black title is a white\ntitle style\nand as the name suggests it has white\nforeground and a transparent background\nas the black portion comes from the\nblack toolbar ui id\nthe padding is pretty standard these\nnumbers were picked to align properly\nwith the commands both in expanded and\ncollapsed states\nthe margin is actually zero\nas we change this manually and code it\nmight make sense to do the margin here\nfor some cases\nthe font is\nstandard light font\nbut four millimeters in size which\nshould appear bigger but not huge\nsubtle\nthe left margin version of the style\ndoes define the side margin to leave\nroom for the arrow this means that the\ncollapse animation will mutate\ninto this ui id which has no top margin\nso it will effectively align with the\nback arrow\nhowever the left margin will keep it\nfrom going on\non top of the arrow\nit also evens out the padding so things\nlook more aligned\nnow that they are on the same row\nderive the white on black title ui id so\nthe settings\nwe don\u0026rsquo;t override are identical\nthe font is the same but a smaller three\nmillimeter size\nthis will also animate as the title\nslides into place it\u0026rsquo;s subtle but\nnoticeable\u003c/p\u003e","title":"5. Social Login and Country Picker"},{"content":" Module 12: Performance and Memory Tuning\nThe most important rule of performance debugging is simple: stop guessing. Profiling exists because intuition is unreliable, especially in systems with several interacting layers.\nThis lesson makes that point with exactly the right kind of story. Teams can spend hours arguing about where a slowdown must be coming from, only to discover through profiling that the real problem is somewhere much less glamorous. That is not an exception. That is how performance work usually goes.\nThe built-in performance monitor in the simulator is useful because it gives you visibility into rendering behavior without requiring external tooling. It will not solve every performance question, but it can show you which components are drawing slowly, whether unlocked images are being rendered in suspicious places, and where overdraw or repeated painting is happening in the hierarchy.\nThat tool is especially helpful because it teaches you to ask \u0026ldquo;why was this painted?\u0026rdquo; rather than merely \u0026ldquo;why does this feel slow?\u0026rdquo; Once you inspect the drawing tree and the associated stack traces, rendering behavior becomes something you can reason about instead of something you vaguely experience.\nDesktop profilers add another layer of insight. CPU and memory profilers on the simulator side can help you spot suspicious hotspots, excessive invocation counts, or unexpected memory growth. They are not a perfect proxy for device behavior, but they are good enough to invalidate bad assumptions and point you toward real candidates for investigation.\nThe most practical habit from this lesson is the back-of-the-envelope check. If the numbers a profiler shows you do not roughly match the size of the data or the amount of work you think you are doing, that mismatch is itself a clue. Simple sanity checks are often what turn profiler output into understanding.\nFurther Reading What is Performance? Breaking Down the Problem How Do I Improve Application Performance Or Track Down Performance Issues Profiling on Devices iOS and Android ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/042-profiling-on-the-desktop-using-the-performance-monitor-tool/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Performance and Memory Tuning\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/BY1lMQz873g?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe most important rule of performance debugging is simple: stop guessing. Profiling exists because intuition is unreliable, especially in systems with several interacting layers.\u003c/p\u003e\n\u003cp\u003eThis lesson makes that point with exactly the right kind of story. Teams can spend hours arguing about where a slowdown must be coming from, only to discover through profiling that the real problem is somewhere much less glamorous. That is not an exception. That is how performance work usually goes.\u003c/p\u003e","title":"Profiling on the Desktop, Using the Performance Monitor Tool"},{"content":" Module 12: Creating an Uber Clone\nTranscript in this part we\u0026rsquo;ll go into the sms activation flow the first form in the sms activation flow is the enter mobile number form it\u0026rsquo;s a simple form even though there are some interesting subtle features here the cool thing is that we did almost all of the work for this element already Text Fields let\u0026rsquo;s jump right into the code that makes that form we\u0026rsquo;ll use standard back navigation since the toolbar is pretty standard here the phone number text field is right next to the country code button we place it in the center of the border layout so it will take up all available space i want the padding on the text field and button to match so they align properly once paddings are set they are always in pixels so we need to change the style to use pixels i don\u0026rsquo;t want to impact the left right padding values so i extract them first and save them so i can restore them into the ui i could technically create a separate ui id to align both but i wanted to do this in the code so future changes to the theme don\u0026rsquo;t break alignment just so you\u0026rsquo;ll get a sense of why this exists this screenshot shows side by side how this looks with and without the alignment code guess which is the right one you can start editing a text field by invoking start editing however this is a bit more challenging to do with a form that isn\u0026rsquo;t showing yet so we have a special case for that set edit on show and this is pretty much it for this form SMS Verification once the number is entered we move to the sms verification stage or password entry stage in this case i\u0026rsquo;ve hard coded the sms verification stage i didn\u0026rsquo;t do the sms resend countdown but i did do the number input notice that the text fields look like android text fields but have a sort of center alignment structure also notice that the error mode spans the four text elements let\u0026rsquo;s jump into the code and look at how this was done Digits Form the enter sms verification digits form is a bit of a mouthful but it describes the function of the form rather well let\u0026rsquo;s go over this form line by line we use a border layout and place a box in the center which we make scrollable on the y axis the reason for the border layout is so we can stick the countdown label in the south otherwise i would have used box layout for the entire form notice i set the container to be scrollable on the y-axis this is important for containers where we have text input it allows our keyboard code to resize the container properly when the keyboard shows i\u0026rsquo;d like to also point out that i used the standard back command in the toolbar we create an array of text fields to loop over this allows us to easily change the code to accept six digits i\u0026rsquo;ll discuss the create digits method soon yes this works it adds all the components and the array so it will add the four digit text fields the error label is always there we just hide it for now i don\u0026rsquo;t animate the recent text again notice that i use board layout to position the recent label at the bottom and place the rest of the stuff in a box layout in the center when the floating action button is pressed we validate the input so we can decide whether to show an error or proceed the generic creation code creates the array of numeric text fields and aligns the hints to the center this logic makes sure that once we type a character the input will automatically move to the next text field in case of an error we just change the underline style we could have also done this by invoking set ui id which might have been more elegant we bind a listener to each text field and if the length of the text is 1 we stop editing and move to the next text field and this is pretty much it with the exception of the styles we had to add to make this happen Digits Style the digit style is a special case of text field specifically designed for this form the main reason for a special style is the problematic center alignment and text field because of the way this works i preferred using a one millimeter padding on the sides to give the feel of center alignment in this case center alignment works in text area label etc however it\u0026rsquo;s flaky in text fields because it\u0026rsquo;s really hard to get the position right when moving from lightweight to native editing another important bit is the smaller margin that makes the fields stand closer to one another Selected Style as i mentioned before since this is a specialization of text field we derive from text field the text field class one thing to notice is that the selected style we need to override the border as well to implement a 4 pixel underline border it\u0026rsquo;s because we derived from the unselected digit and not from the selected version of text field so we need to redefine how selected digit entry looks however we also override the font size to make it slightly smaller and thus more consistent with the native uber app the error label is just a red on white label it has a bit of a smaller padding so it can use up space it still has zero margin like most components but it has a smaller light font at 2.8 millimeters which is more consistent with the material design aesthetic the recent code style just pads the text so it will align properly with the floating action button it leaves margin as 0 by default but it has smaller text size than a typical label Password Entry the last form in the sms activation flow is the password entry form it\u0026rsquo;s a trivial form after the others we\u0026rsquo;ve been through here i\u0026rsquo;ll gloss over it relatively quickly this is the entire form code literally in one page after the activation form there is literally nothing new or interesting here the only aspect that\u0026rsquo;s here and wasn\u0026rsquo;t there is the forget password uiid which we align with the floating action button in this case we have two elements that we enclose in a box layout y in the south most of the work here is in the ui id itself the forget password buttons have a bluish color and are transparent the padding is carefully measured to align properly with the floating action button margin is zero as usual the font is a relatively small 2.5 millimeter size and that concludes the sms activation ui flow mockup\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/043-6-sms-activation-flow/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/cRqvkIpJlkg?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ein this part we\u0026rsquo;ll go into the sms\nactivation flow\nthe first form in the sms activation\nflow is the enter mobile number form\nit\u0026rsquo;s a simple form even though there are\nsome interesting subtle features here\nthe cool thing is that we did almost all\nof the work for this element already\nText Fields\nlet\u0026rsquo;s jump right into the code that\nmakes that form\nwe\u0026rsquo;ll use standard back navigation since\nthe toolbar is pretty standard here\nthe phone number text field is right\nnext to the country code button\nwe place it in the center of the border\nlayout so it will take up all available\nspace\ni want the padding on the text field and\nbutton to match so they align properly\nonce paddings are set they are always in\npixels so we need to change the style to\nuse pixels\ni don\u0026rsquo;t want to impact the left right\npadding values so i extract them first\nand save them so i can restore them into\nthe ui\ni could technically create a separate ui\nid to align both but i wanted to do this\nin the code so future changes to the\ntheme don\u0026rsquo;t break alignment\njust so you\u0026rsquo;ll get a sense of why this\nexists\nthis screenshot shows\nside by side how this looks with and\nwithout the alignment code\nguess\nwhich is the right one\nyou can start editing a text field by\ninvoking start editing\nhowever this is a bit more challenging\nto do\nwith a form that isn\u0026rsquo;t showing yet so we\nhave a special case for that\nset edit on show\nand this is pretty much it for this form\nSMS Verification\nonce the number is entered\nwe move to the sms verification stage or\npassword entry stage\nin this case\ni\u0026rsquo;ve hard coded the sms verification\nstage i didn\u0026rsquo;t do the sms resend\ncountdown\nbut i did do the number input\nnotice that the text fields look like\nandroid text fields but have a sort of\ncenter alignment structure\nalso notice that the error mode spans\nthe four text elements\nlet\u0026rsquo;s jump into the code and look at how\nthis was done\nDigits Form\nthe enter sms verification digits form\nis a bit of a mouthful but it describes\nthe function of the form rather well\nlet\u0026rsquo;s go over this form line by line\nwe use a border layout and place a box\nin the center\nwhich we make scrollable on the y axis\nthe reason for the border layout is so\nwe can stick the countdown label in the\nsouth\notherwise i would have used\nbox layout for the entire form\nnotice i set the container to be\nscrollable on the y-axis this is\nimportant for containers where we have\ntext input it allows our keyboard code\nto resize the container properly\nwhen the keyboard shows\ni\u0026rsquo;d like to also point out that i used\nthe standard back command\nin the toolbar\nwe create an array of text fields to\nloop over this allows us to easily\nchange the code to accept six digits\ni\u0026rsquo;ll discuss the create digits method\nsoon\nyes\nthis works it adds all the components\nand the array so it will add the four\ndigit text fields\nthe error label\nis always there\nwe just hide it\nfor now i don\u0026rsquo;t animate the recent text\nagain notice that i use board layout to\nposition the recent label at the bottom\nand place the rest of the stuff in a box\nlayout in the center\nwhen the floating action button is\npressed we validate the input so we can\ndecide whether to show an error or\nproceed\nthe generic creation code creates the\narray of numeric text fields and aligns\nthe hints to the center\nthis logic makes sure that once we type\na character the input will automatically\nmove to the next text field\nin case of an error\nwe just change the underline style\nwe could have also done this by invoking\nset ui id which might have been more\nelegant\nwe bind a listener to each text field\nand if the length of the text is 1\nwe stop editing and move to the next\ntext field\nand this is pretty much it with the\nexception of the styles we had to add to\nmake this happen\nDigits Style\nthe digit style is a special case of\ntext field specifically designed for\nthis form\nthe main reason for a special style is\nthe problematic center alignment and\ntext field\nbecause of the way this works i\npreferred using a one millimeter padding\non the sides to give the feel of center\nalignment in this case\ncenter alignment works in text area\nlabel etc however it\u0026rsquo;s flaky in text\nfields because it\u0026rsquo;s really hard to get\nthe position right when moving from\nlightweight to native editing\nanother important bit\nis the smaller margin that makes the\nfields stand closer to one another\nSelected Style\nas i mentioned before since this is a\nspecialization of text field we derive\nfrom text field the text field class\none thing to notice\nis that the selected style\nwe need to override the border as well\nto implement a\n4 pixel underline border\nit\u0026rsquo;s because we derived from the\nunselected digit and not from the\nselected version of text field so we\nneed to redefine how selected digit\nentry looks\nhowever we also override the font size\nto make it slightly smaller and thus\nmore consistent with the native uber app\nthe error label is just a red on white\nlabel\nit has a bit of a smaller padding\nso it can use up space\nit still has zero margin like most\ncomponents\nbut it has a smaller light font at 2.8\nmillimeters\nwhich is more consistent with the\nmaterial design aesthetic\nthe recent code style\njust pads the text so it will align\nproperly with the floating action button\nit leaves margin as 0 by default\nbut it has smaller text size than a\ntypical label\nPassword Entry\nthe last form in the sms activation flow\nis the password entry form\nit\u0026rsquo;s a trivial form after the others\nwe\u0026rsquo;ve been through\nhere i\u0026rsquo;ll gloss over it relatively\nquickly\nthis is the entire form code literally\nin one page\nafter the activation\nform there is literally nothing new or\ninteresting here the only aspect that\u0026rsquo;s\nhere and wasn\u0026rsquo;t there is the forget\npassword uiid\nwhich we align with the floating action\nbutton\nin this case we have\ntwo elements that we enclose in a box\nlayout y in the south\nmost of the work here is in the ui id\nitself\nthe forget password buttons\nhave a bluish color and are transparent\nthe padding is carefully measured to\nalign properly with the floating action\nbutton\nmargin is zero as usual\nthe font is a relatively small 2.5\nmillimeter size\nand that concludes the sms activation ui\nflow mockup\u003c/p\u003e","title":"6. SMS Activation Flow"},{"content":" Module 12: Performance and Memory Tuning\nThe simulator gets you far, but not all the way. Some performance problems only become visible on the real device, where GPU behavior, memory pressure, input latency, and platform-specific implementation details finally line up the way your users will experience them.\nThat is why device profiling matters. Android Studio and Xcode provide the next level of evidence once the simulator has stopped being enough. The goal is not to abandon the desktop tools. It is to move to hardware when you need to confirm what is really happening under mobile conditions.\nThe Android guidance in the older lesson is still useful because it combines two kinds of observation: profiler data and developer-option visual debugging. GPU overdraw visualization, in particular, is one of those rare tools that can make a rendering problem immediately visible even before you have fully quantified it. If a screen is awash in red, you already know where to start asking questions.\nOn iOS, the tooling differs, but the principle is identical. Use the platform profiler to isolate expensive methods, understand where time is being spent on device, and confirm whether the suspected bottleneck is real. The purpose is not just to collect screenshots of charts. It is to narrow the problem until you can act on it.\nThe broader lesson is that performance work should move from general to specific. Start with conceptual classification, then use simulator tools, then escalate to device profiling when the evidence demands it. That progression keeps you from over-investing in low-level profiling too early while still giving you a path to real answers when desktop measurements are no longer enough.\nFurther Reading Profiling on the Desktop, Using the Performance Monitor Tool What is Performance? Breaking Down the Problem How Do I Improve Application Performance Or Track Down Performance Issues ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/043-profiling-on-devices-ios-and-android/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Performance and Memory Tuning\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/YwkwqXkHGwg?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe simulator gets you far, but not all the way. Some performance problems only become visible on the real device, where GPU behavior, memory pressure, input latency, and platform-specific implementation details finally line up the way your users will experience them.\u003c/p\u003e","title":"Profiling on Devices iOS and Android"},{"content":" Module 12: Creating an Uber Clone\nTranscript in this section we finally get to the map ui i hope you followed the instructions before for configuring the map if not please follow through with that if things don\u0026rsquo;t work and if you don\u0026rsquo;t see the map or it acts funny check out with us in the online support forums you can also check out the map section in the deep dive into mobile development course which comes bundled before we begin we need a class we discussed before in the maps module the map layout i didn\u0026rsquo;t change much as left it as is since it\u0026rsquo;s already available elsewhere i won\u0026rsquo;t go into the full discussion here and go right into the form itself before we proceed i\u0026rsquo;d like to highlight some subtle things in this screenshot and discuss what we will and will not do i won\u0026rsquo;t do the side menu right now but i will do it soon the way to field is really a button that leads to a different ui this ui is overlaid on top of the map so it is a part of this form i\u0026rsquo;ll position one taxi in a hard-coded location as part of the mock-up the icons at the bottom are historic rides i\u0026rsquo;ll add two hard-coded historic rides for now i won\u0026rsquo;t go into the notice at the bottom it\u0026rsquo;s it\u0026rsquo;s possible but it would be non-trivial let\u0026rsquo;s jump right into the code you need the js key from google maps as explained in the map extension page this must have a filled up value we usually use border layout which implicitly disables scrollability layout layout doesn\u0026rsquo;t do that and the form\u0026rsquo;s content pane is scrollable on the y-axis by default notice we didn\u0026rsquo;t use a thread here and instead used call serially on idle method on the login form i didn\u0026rsquo;t use that because the animation might have prevented idle from occurring this shadow is used later on in the show navigation toolbar method the transition and the main application are based on cover and the transition out will only be a problem the map is on the lowest layer and everything is placed on top of it the layer is on top of the map and uses the map layout here we will place the car and other landmarks we need i place a car on top of the map in tel aviv notice that the car is just a label i\u0026rsquo;ve set the opacity to 140 to match the translucent cars in the native app notice that the map layout takes a quart as constraint so it can properly position the car this is the small square we place next to the where to button i could have used a unicode value too but it wasn\u0026rsquo;t available in all the fonts notice the where to element is just a button as it moves us to a separate ui and isn\u0026rsquo;t really a text field the history buttons are floating action button instances that are customized in terms of styling i used text area instead of span label because i wanted the history element to act as a single component with lead component lead components can take over a hierarchy of several components and handle the events for everyone so in this case click on the text area below the history will trigger an event in the floating action button the bottom of the map has a gradient overlay that darkens the bottom this is probably in place to make the history labels readable i just generated a gradient image in photoshop and placed it here we do two important things here we use the overlay toolbar which floats on top of the ui we initialize the side menu which we will discuss soon that was a lot to cover but there is a lot more we did mention three new styles above which isn\u0026rsquo;t that much all things considered the wear 2 style has some subtle nuances such as dark gray text the padding is large and obvious i played with it a bit to get it right the margin is special we want some margin from the sides so it won\u0026rsquo;t touch them we need a lot of margin from the top to leave room for the title area the corners are rounded on the native widget this is very subtle so i left it at 0.3 millimeters which should be very easy it also has a shadow which is more obvious and 80 opacity the font isn\u0026rsquo;t big just slightly bigger than normal but the typical light font the history button is the round button on the bottom of the map leading to historic rides it\u0026rsquo;s black on white but is implemented as a floating action button so it derives from that and uses the border settings from the floating action button the the history label is the dark text element below which is technically a text area but acts as a label the text color for this is black while the padding is two millimeters on all sides except for the top where we want to be as close as possible to the floating action button which is already well padded margin is zero as usual and the font is a relatively small 2.2 millimeters so we can fit multiple rides in one form\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/044-7-map-form/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/UU6HCbenVAA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ein this section we finally get to the\nmap ui\ni hope you followed the instructions\nbefore for configuring the map\nif not\nplease follow through with that if\nthings don\u0026rsquo;t work and if you don\u0026rsquo;t see\nthe map or it acts funny check out with\nus in the online support forums\nyou can also check out the map section\nin the deep dive into mobile development\ncourse which comes bundled\nbefore we begin\nwe need a class we discussed before in\nthe maps module\nthe map layout\ni didn\u0026rsquo;t change much as\nleft it as is\nsince it\u0026rsquo;s already available elsewhere i\nwon\u0026rsquo;t go into the full discussion here\nand go right into the form itself\nbefore we proceed i\u0026rsquo;d like to highlight\nsome subtle things in this screenshot\nand discuss what we will and will not do\ni won\u0026rsquo;t do the side menu right now\nbut i will do it soon\nthe way to field is really a button that\nleads to a different ui\nthis ui is overlaid on top of the map so\nit is a part of this form\ni\u0026rsquo;ll position\none taxi in a hard-coded location as\npart of the mock-up\nthe icons at the bottom are historic\nrides i\u0026rsquo;ll add two hard-coded historic\nrides for now\ni won\u0026rsquo;t go into the notice at the bottom\nit\u0026rsquo;s it\u0026rsquo;s possible\nbut it would be non-trivial\nlet\u0026rsquo;s jump right into the code\nyou need the js key from google maps as\nexplained in the map extension page\nthis\nmust have a filled up value\nwe usually use border layout which\nimplicitly disables scrollability\nlayout layout doesn\u0026rsquo;t do that\nand the form\u0026rsquo;s content pane is\nscrollable on the y-axis by default\nnotice we didn\u0026rsquo;t use a thread here\nand instead used call serially on idle\nmethod\non the login form i didn\u0026rsquo;t use that\nbecause the animation might have\nprevented idle from occurring\nthis shadow is used later on in the show\nnavigation toolbar method\nthe transition and the main application\nare based on cover and the transition\nout will only be a problem\nthe map is on the lowest layer and\neverything is placed on top of it\nthe layer is on top of the map and uses\nthe map layout\nhere we will place the car and other\nlandmarks we need\ni place a car on top of the map in tel\naviv\nnotice that the car is just a label\ni\u0026rsquo;ve set the opacity to 140 to match the\ntranslucent cars in the native app\nnotice that the map layout takes a quart\nas constraint\nso it can properly position the car\nthis is the small square we place next\nto the where to button\ni could have used a unicode value too\nbut it wasn\u0026rsquo;t available in all the fonts\nnotice the where to element is just a\nbutton as it moves us to a separate ui\nand isn\u0026rsquo;t really a text field\nthe history buttons are floating action\nbutton instances\nthat are customized in terms of styling\ni used text area instead of span label\nbecause i wanted the history element to\nact as a single component with lead\ncomponent\nlead components can take over a\nhierarchy of several components and\nhandle the events for everyone so in\nthis case click on the text area below\nthe history will trigger an event in the\nfloating action button\nthe bottom of the map has a gradient\noverlay that darkens the bottom\nthis is probably in place to make the\nhistory labels readable\ni just generated a gradient image in\nphotoshop and placed it here\nwe do\ntwo important things here\nwe use the overlay toolbar which floats\non top of the ui\nwe initialize the side menu\nwhich we will discuss soon\nthat was a lot to cover\nbut there is a lot more\nwe did mention three new styles above\nwhich isn\u0026rsquo;t that much all things\nconsidered\nthe wear 2 style has some subtle nuances\nsuch as\ndark gray text\nthe padding is large and obvious i\nplayed with it a bit to get it right\nthe margin is special we want some\nmargin from the sides so it won\u0026rsquo;t touch\nthem\nwe need a lot of margin from the top to\nleave room for the title area\nthe corners are rounded on the native\nwidget this is very subtle so i left it\nat 0.3 millimeters which should be very\neasy\nit also has a shadow which is more\nobvious\nand 80 opacity\nthe font isn\u0026rsquo;t big just slightly bigger\nthan normal\nbut the typical light font\nthe history button is the round button\non the bottom of the map leading to\nhistoric rides it\u0026rsquo;s black on white but\nis implemented as a floating action\nbutton\nso it derives from that\nand uses the border settings from the\nfloating action button\nthe\nthe history label is the dark text\nelement below which is technically a\ntext area but acts as a label\nthe text color for this is black\nwhile the padding is two millimeters on\nall sides except for the top where we\nwant to be as close as possible to the\nfloating action button which is already\nwell padded\nmargin is zero as usual\nand the font is a relatively small 2.2\nmillimeters so we can fit multiple rides\nin one form\u003c/p\u003e","title":"7. Map Form"},{"content":" Module 12: Performance and Memory Tuning\nPerformance advice is easiest to remember when it is attached to a real mistake. That is why this case study is valuable. Instead of repeating general rules, it shows how ordinary-looking decisions in a real application created noticeable problems and how those problems were fixed.\nThe first example is a perfect reminder not to trust first impressions. The contacts demo seemed slow for an obvious reason, but profiling and inspection uncovered a different issue entirely: the same resource file was being loaded repeatedly in places where the code looked superficially innocent. That kind of bug is common because the expensive part is often hidden behind constructors, helpers, or convenience APIs.\nThe second example is equally important because it shows the limits of the \u0026ldquo;just move it to a background thread\u0026rdquo; reflex. Loading contact images off the EDT sounded like the right fix, and in one sense it was. But the background work still competed with the user experience during scrolling. The real improvement came from coordinating the work with user activity so the app deferred expensive updates until interaction settled down.\nThat is a strong pattern to remember. Performance is often not about doing less work overall. It is about doing work at a better time. If the UI is busy, defer the optional work. If the user is idle, use that moment to fill in detail. This is one of the cleanest ways to improve perceived and actual responsiveness at the same time.\nSo the real lesson from the case study is methodological. Do not assume. Measure. Look for hidden repeated work. And when a background task still harms the experience, ask whether the issue is not the work itself but its timing relative to user interaction.\nFurther Reading What is Performance? Breaking Down the Problem EDT, Threading, Caching and Soft References Profiling on the Desktop, Using the Performance Monitor Tool ","permalink":"https://www.codenameone.com/courses/course-02-deep-dive-mobile-development-with-codename-one/044-case-study-performance-problems-in-the-kitchen-sink/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Performance and Memory Tuning\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/qGJaVaQ_MNY?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003ePerformance advice is easiest to remember when it is attached to a real mistake. That is why this case study is valuable. Instead of repeating general rules, it shows how ordinary-looking decisions in a real application created noticeable problems and how those problems were fixed.\u003c/p\u003e","title":"Case Study: Performance Problems in the Kitchen Sink"},{"content":" Module 12: Creating an Uber Clone\nTranscript when you tap the where to button on the map form you see something that might look like a new form but it isn\u0026rsquo;t really what you see initially is this and it seems like a new form but notice that the focus is on the where to text field if we switch focus to the where from text field on top you will see something else you will see the map and the ability to type in a new location so what we really have here are two separate overlays on top of the map one above and one below there is another septal behavior that i only noticed when i started playing with this ui notice the line and the shapes next to the text field when you move the focus between the fields the shapes flip to highlight the focused field we could build something like this with a dialog or interaction dialog but i chose to go with simpler container instances on top of the map to do this i first had to add a listener to the where to button then i add the show navigation button method let\u0026rsquo;s dive into this method we create a new layer on top of the current layers in the form layers are associated with a component class which allows us to keep it unique and prevents different code from messing with our layer also notice that we replicate the look of the title area without actually creating a title area the square image already exists from before we created it for the where to button we add a new circle image that we can place next to the from two fields we place the text fields in a border layout next to the labels representing the circle and square we place that in a box layout y container and that\u0026rsquo;s effectively the entire ui of the top portion the background painter allows us to control the shadow from the top area and draw the line between the circle square images the fact that we have a background painter makes some of the aspects of the ui id less significant for instance background color but we still need it for padding margin etc the shadow image is created asynchronously by the call serially on idle code and the constructor so it might might not be ready when this is drawn we fill the rectangle on top of the drop shadow covering half of it this makes it feel like a directional shadow i used fill rect instead of draw line to make a 2 pixel wide line i could have used draw line with stroke but this is simpler and probably faster the entire layer uses border layout north makes sense for this as we wanted to span the width but remain at preferred height in the north we\u0026rsquo;ll use the center for the rest of the ui soon the component animates down from the top with animate layout we pre position the component location above the from so animate layout will slide everything from the right point this ui requires three new styles first is the wear toolbar which is an opaque white container we have five millimeter padding on the bottom for the shadow of the container and as usual the zero margin the from two text field is opaque with a grayish color background and black foreground it has two millimeters of padding and two millimeters of margin to keep it spaced it uses a standard light font the component also has a selected version which has slightly darker grayish color it derives from the unselected version of the uid we also have a custom ui id which for the most part just uses a darker gray color for the hint text the margin is zero again most everything else is derived from the from to text field\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/045-8-where-to-ui/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/-7XHkBMK4NY?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ewhen you tap the where to button on the\nmap form you see something that might\nlook like a new form but it isn\u0026rsquo;t really\nwhat you see initially is this and it\nseems like a new form\nbut notice that the focus is on the\nwhere to text field\nif we switch focus to the where from\ntext field on top you will see something\nelse\nyou will see the map and the ability to\ntype in a new location\nso what we really have here are two\nseparate overlays on top of the map\none above and one below\nthere is another septal behavior that i\nonly noticed when i started playing with\nthis ui\nnotice the line and the shapes next to\nthe text field\nwhen you move the focus between the\nfields the shapes\nflip to highlight the focused field\nwe could build something like this with\na dialog or interaction dialog but i\nchose to go with simpler container\ninstances on top of the map\nto do this i first had to add a listener\nto the where to\nbutton then i add the show navigation\nbutton method\nlet\u0026rsquo;s dive into this method\nwe create a new layer on top of the\ncurrent layers\nin the form\nlayers are associated with a component\nclass\nwhich allows us to keep it unique and\nprevents different code from messing\nwith our layer\nalso notice that we replicate the look\nof the title area without actually\ncreating a title area\nthe square image already exists from\nbefore\nwe created it for the where to button\nwe add a new circle image that we can\nplace next to the from two fields\nwe place the text fields in a border\nlayout next to the labels representing\nthe circle and square\nwe place that in a box layout y\ncontainer and that\u0026rsquo;s effectively the\nentire ui of the top portion\nthe background painter allows us to\ncontrol the shadow from the top area and\ndraw the line between the circle\nsquare images\nthe fact that we have a background\npainter makes some of the aspects of the\nui id less significant\nfor instance background color\nbut we still need it for padding margin\netc\nthe shadow image\nis created asynchronously\nby the call serially on idle code and\nthe constructor\nso it might might not be ready when this\nis drawn\nwe fill the rectangle on top of the drop\nshadow\ncovering half of it\nthis makes it feel like a directional\nshadow\ni used fill rect instead of draw line to\nmake a 2 pixel wide line\ni could have used draw line with stroke\nbut this is simpler and probably faster\nthe entire layer uses border layout\nnorth makes sense for this as we wanted\nto span the width but remain at\npreferred height in the north\nwe\u0026rsquo;ll use the center for the rest of the\nui soon\nthe component animates down from the top\nwith animate layout we pre position the\ncomponent location above\nthe from so animate layout will slide\neverything\nfrom the right point\nthis ui requires three new styles\nfirst is\nthe wear toolbar\nwhich is an opaque white container\nwe have five millimeter padding on the\nbottom for the shadow of the container\nand as usual the\nzero margin\nthe from two text field is opaque with a\ngrayish color background and black\nforeground\nit has\ntwo millimeters of padding\nand two millimeters of margin to keep it\nspaced\nit uses a standard light font\nthe component also has a selected\nversion\nwhich has\nslightly darker grayish color\nit derives from the unselected version\nof the\nuid\nwe also have a custom ui id which for\nthe most part just uses a darker gray\ncolor for the hint text\nthe margin is zero again\nmost everything else is derived from the\nfrom to text field\u003c/p\u003e","title":"8. Where To UI"},{"content":" Module 12: Creating an Uber Clone\nTranscript the where2 ui is a pretty big piece of the puzzle and it also includes the navigation ui which is the bottom portion up until now we focused on this part of the toolbar area now we need to do this portion the destination ui toggle is a huge part of the navigation ui it\u0026rsquo;s the bottom section of the form that contains the list of destinations we can build it on top of the code we wrote for the navigation ui and place it in the center of the layer so it will play nicely with the rest of the ui for now i\u0026rsquo;ll ignore this portion as it\u0026rsquo;s mostly a specialization of other things and can be done relatively easily if you understand the rest of the things i did let\u0026rsquo;s jump right into the show navigation bar method the top elements are relatively simple multi buttons we use container as their ui id so they will be transparent with zero padding and margin the separator is just a label with a specific style notice that blank label buttons etc are hidden by default in codename one and you should invoke set show even if blank if you want such a label to still render we can reuse the form ui id here because that\u0026rsquo;s effectively what we want we want this ui to appear as if it\u0026rsquo;s a form we need this to be scrollable but we don\u0026rsquo;t want the scroll bar on the side as it might cause aesthetic issues the showing of this element is animated from the bottom of the form while this ui is very simple it did define a few ui ids let\u0026rsquo;s start with where to button line 1 which represents the entries in the list of elements and also adds the underline the color is just black over transparent which in this case leads to white the padding on the left side is relatively low since the icon will take the extra padding on the other sides we have typical four millimeter padding margin is zero as usual we put the underline here because the design placed the underline only under the text and it will place it under the icon which has a different ui id the underline is a gray two pixel high line the font is the standard three millimeter light font the where to button icon style applies to the icon which has less horizontal padding so it won\u0026rsquo;t drift too far from the text but identical vertical padding so it will align properly with the text it derives from where to button line one so they will fit together well we need the no border version of the style so it will remove the underline border on the last entry otherwise we can see an out of place underline in that one last entry in the list we derive from the same style so everything else is identical the wear separator is just a gray padded line so it has the right gray color and is completely opaque so with no background transparency it\u0026rsquo;s exactly two millimeters tall so it will stand out but won\u0026rsquo;t take out an entire line margin is zero so it can reach the edge of the parent container now that we added this we need to show this ui and hide it when the user toggles the focus in the text fields we can do this by binding focus listeners to the to and from text fields when focus is lost or gained we toggle between the square and circle modes by setting the icon to the appropriate labels we always have one container in the layer except for the case where the second component is the where2 container it\u0026rsquo;s always the second component because it\u0026rsquo;s always added last we set the position of this container below the forms animate and layout moves the component outside of the screen to the position we asked for using a smooth animation this callback is invoked when the unlayout completes at this point we have an invalid ui that needs a layout but before we do that we remove the component that we animated out of the form now that the ui appears we also need to remove it when going back so i\u0026rsquo;ll update the back action listener from above to handle the where to ui as well this is the exact same unlayout operation we did before and finally we need to make a subtle but important change to the background painter code from before because of the drop shadow a gap is formed between the top and bottom pieces so a special case here paints a white rectangle under the shadow to hide the gap without that the shadow would appear on top of the map and not on top of the white background once this is done opening the where to ui and toggling the fields should work as expected\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/046-9-where-to-ui-part-ii/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/Lai--eYYJTw?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ethe where2 ui is a pretty big piece of\nthe puzzle and it also includes the\nnavigation ui\nwhich is the bottom portion\nup until now we focused on this part of\nthe toolbar area\nnow we need to do this portion the\ndestination ui toggle\nis a huge part of the navigation ui\nit\u0026rsquo;s the bottom section of the form that\ncontains the list of destinations\nwe can build it on top of the code we\nwrote for the navigation ui and place it\nin the center\nof the layer\nso it will play nicely with the rest of\nthe ui\nfor now i\u0026rsquo;ll ignore this portion\nas it\u0026rsquo;s mostly a specialization\nof other things and can be done\nrelatively easily if you understand the\nrest of the things i did\nlet\u0026rsquo;s jump right into the show\nnavigation bar method\nthe top elements are relatively\nsimple multi buttons we use container as\ntheir ui id so they will be transparent\nwith zero padding and margin\nthe separator\nis just a label with a specific style\nnotice that blank label\nbuttons etc are hidden by default in\ncodename one\nand you should invoke set show even if\nblank\nif you want such a label to still render\nwe can reuse the form ui id here\nbecause that\u0026rsquo;s effectively what we want\nwe want this ui to appear as if it\u0026rsquo;s a\nform\nwe need this to be scrollable but we\ndon\u0026rsquo;t want the scroll bar on the side as\nit might cause\naesthetic issues\nthe showing of this element\nis animated from the bottom\nof the form\nwhile this ui is very simple\nit did define a few ui ids\nlet\u0026rsquo;s start with where to button line 1\nwhich represents the entries in the list\nof elements and also adds the underline\nthe color is just black over transparent\nwhich in this case leads\nto white\nthe padding on the left side is\nrelatively low since the icon will take\nthe extra padding on the other sides\nwe have typical four millimeter padding\nmargin is zero\nas usual\nwe put the underline here because the\ndesign placed the underline only under\nthe text and it will place it under the\nicon which has a different ui id\nthe underline is a gray two pixel high\nline\nthe font is the standard three\nmillimeter light font\nthe where to button icon style\napplies to the icon which has\nless horizontal padding so it won\u0026rsquo;t\ndrift too far from the text\nbut identical vertical padding\nso it will align properly with the text\nit derives from where to button line one\nso they will fit together well\nwe need the no border version of the\nstyle\nso it will remove the underline border\non the last entry\notherwise we can see\nan out of place underline in that one\nlast entry in the list\nwe derive from the same style so\neverything else is identical\nthe wear separator\nis just a gray padded line so it has the\nright gray color and is completely\nopaque so\nwith no background transparency\nit\u0026rsquo;s exactly\ntwo millimeters tall so it will stand\nout but won\u0026rsquo;t take out an entire line\nmargin is zero so it can reach the edge\nof the parent container\nnow that we added this we need to show\nthis ui and hide it when the user\ntoggles the focus in the text fields\nwe can do this by binding focus\nlisteners\nto the to and from text fields\nwhen focus is lost or gained we toggle\nbetween the square and circle modes by\nsetting the icon\nto the appropriate labels\nwe always have one container in the\nlayer except for the case where the\nsecond component is the where2 container\nit\u0026rsquo;s always the second component because\nit\u0026rsquo;s always added last\nwe set the position of this container\nbelow the forms\nanimate and layout moves the component\noutside of the screen to the position we\nasked for\nusing a smooth animation\nthis callback is invoked when the\nunlayout completes\nat this point we have an invalid ui that\nneeds a layout but before we do that we\nremove the component that we animated\nout of the form\nnow\nthat the ui appears we also need to\nremove it when going back\nso i\u0026rsquo;ll update the back action listener\nfrom above to handle the where to ui as\nwell\nthis is the exact same unlayout\noperation\nwe did before\nand finally\nwe need to make a subtle but important\nchange to the background painter code\nfrom before\nbecause of the drop shadow a gap is\nformed between the top and bottom pieces\nso a special case here paints a white\nrectangle under the shadow to hide the\ngap\nwithout that the shadow would appear\non top of the map and not on top of the\nwhite background\nonce this is done\nopening the where to ui\nand toggling the fields should work\nas expected\u003c/p\u003e","title":"9. Where To UI - Part II"},{"content":" Module 12: Creating an Uber Clone\nTranscript we are nearing the end of the mock-up code the next thing on the agenda is the side menu ui i\u0026rsquo;ve moved that code into a separate hard-coded class for reuse in other forms frankly i\u0026rsquo;m not sure if this ui is used in other forms but i think it\u0026rsquo;s a good habit to separate the menu from the component code the code in the common code class which i used for the black toolbar as well it\u0026rsquo;s a sort of util class that\u0026rsquo;s really convenient when you have repeating ui elements one thing you will notice is that there just isn\u0026rsquo;t all that much code here the main reason is that most of the ui is within the theme and we already defined most of these ui elements such as side command uid let\u0026rsquo;s dive into the code we\u0026rsquo;ll discuss the get avatar method soon this code generates the avatar image at the top with the name next to it the gap between the text and the icon in the avatar is larger than average the legal button is a south component it\u0026rsquo;s a special case in the on top side menu that allows you to place an element below the menu itself its styling is separate and it slides in out so we need to give it the psi navigation panel styling to let\u0026rsquo;s move to the get avatar method which generates the round image of the user we create an opaque 10 millimeter black image to use as a mask masks allow us to crop out unwanted pieces of an image in this case we want to make the image round we fill the shape we want in white in this case as an arc notice we activate anti-aliasing otherwise the resulting image will look jagged which is also why we avoided shape clipping here the font image class can use the given color and opacity settings we use the version of the class that accepts a style object and size so we\u0026rsquo;ll have fine grained control from code we can\u0026rsquo;t apply a mask to an image of a size that\u0026rsquo;s different from the mask size masking doesn\u0026rsquo;t work well with complex images such as font images so we convert it to a regular image first\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/047-10-side-menu/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/AFvuY7Ev-XA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ewe are nearing the end of the mock-up\ncode\nthe next thing on the agenda is the side\nmenu ui\ni\u0026rsquo;ve moved that code into a separate\nhard-coded class for reuse in other\nforms frankly i\u0026rsquo;m not sure if this ui is\nused in other forms but i think it\u0026rsquo;s a\ngood habit to separate the menu\nfrom the component code\nthe code in the common code class which\ni used for the black toolbar as well\nit\u0026rsquo;s a sort of util class that\u0026rsquo;s really\nconvenient when you have repeating ui\nelements\none thing you will notice is that there\njust isn\u0026rsquo;t all that much code here\nthe main reason is that\nmost of the ui is\nwithin the theme and we already defined\nmost of these ui elements such as side\ncommand uid\nlet\u0026rsquo;s dive into the code\nwe\u0026rsquo;ll discuss the get avatar method soon\nthis code generates the avatar image at\nthe top\nwith the name next to it\nthe gap between the text and the icon in\nthe avatar is larger than average\nthe legal button\nis a south component\nit\u0026rsquo;s a special case in the on top side\nmenu that allows you to place an element\nbelow the menu itself\nits styling is separate and it slides in\nout\nso\nwe need to give it the psi navigation\npanel styling to\nlet\u0026rsquo;s move to the get avatar method\nwhich generates the round image of the\nuser\nwe create an opaque 10 millimeter black\nimage\nto use as a mask\nmasks allow us to crop out unwanted\npieces of an image in this case we want\nto make the image round\nwe fill the shape we want in white in\nthis case as an arc\nnotice we activate anti-aliasing\notherwise the resulting image will look\njagged\nwhich is also why we avoided\nshape clipping here\nthe font image class can use the given\ncolor and opacity settings\nwe use the version of the class that\naccepts a style object and size so we\u0026rsquo;ll\nhave fine grained control from code\nwe can\u0026rsquo;t apply a mask to an image of a\nsize that\u0026rsquo;s different from the mask size\nmasking doesn\u0026rsquo;t work well with complex\nimages such as font images\nso we convert it to a regular image\nfirst\u003c/p\u003e","title":"10. Side Menu"},{"content":" Module 12: Creating an Uber Clone\nTranscript now that we got the mock-up running let\u0026rsquo;s jump to the other side of the fence and set up the server if you aren\u0026rsquo;t familiar with spring boot or mysql or don\u0026rsquo;t understand why i picked both of them i suggest checking the previous modules where i discussed the reasons for this extensively and gave a long overview over both you can create a new database by logging into mysql and issuing a create database command i created a new spring boot project which includes maven dependencies for jpa which is the java persistence architecture or hibernate jersey which is the json and xml serialization framework web which is useful for web service development websocket for connecting over the newer websocket protocol security is mostly used for password hashing which we will discuss and mysql support is needed for the jdbc connectivity and finally braintree for the payment processing we\u0026rsquo;ll need later on before we get into the code let\u0026rsquo;s take a minute or so to think about the things we need from the server the first thing the server needs to offer is an ability to add a new user we also need authentication and authorization for the user such as password validation and authentication we need a way to update the user information we need to track car positions so we can show them on the map we need the ability to hail a car and pick up a driver we need a we need to pay the hailed car so the system knows the car is paired to us we need to log every trip taken including distance path etc and finally we need to provide rating facility so we can rate the drivers i\u0026rsquo;m glossing over some things here such as billing push etc now that we have a spring boot project let\u0026rsquo;s skip ahead to the server code we\u0026rsquo;ll start with storage which is a good place to start a common design strategy is deciding on the data structure and then filling in the blanks a good way to decide on the elements we need in the user object is through the ui the account setting class contains a lot of the data we need the user jpa entity uses an auto increment id value for simplicity let\u0026rsquo;s go over the various pieces here these are part of the user settings such as just general configuration the password stores the hashed value of password and not the plain text version we\u0026rsquo;ll discuss hashing passwords soon we will use these when we need to enable login with a social network account these are the internal network ids we\u0026rsquo;ll use for verification a driver is also a user in the system if this user is a driver this is marked as true by referring to both the end user and the driver with the same class we can simplify the code if this is a driver this is the description of his car we\u0026rsquo;ll need for the app this field is set to true if we are currently in the process of hailing a taxi if the taxi is taken by user this field maps to the user id it is set to null if the taxi is available we will have a separate object dealing with rating but we can sum it for every query so the rating value will be cached here this is the position and direction of the current user whether it\u0026rsquo;s a taxi or an end user notice i chose to just store the location values instead of using one of the custom location based apis supported by hibernate and mysql i looked into those apis and they are very powerful if you need complex location based apis but for most simple purposes like we have here they are an overkill and would have made the project more complex than it needs to be if you are building a complex gis application i would suggest delving into some of those custom apis this is a picture of the user stored in the database blob one last column is the auth token which we initialize with a unique random id we will use this token to update the user and perform operations only the user is authorized for think of authorization as a key to the server we want to block a different user from sending a request that pretends to be our user this is possible to do if a hacker sniffs out our network traffic and tries to pretend he\u0026rsquo;s our app one approach would be sending the password to the server every time but that means storing and sending a password which holds risk in this case we generate a random and long key that\u0026rsquo;s hard to brute force we send the key to the client and it stores that key from that point on we have proof that this user is valid i\u0026rsquo;ve discussed this before in the restaurant app if you want to check that out the repository class for the user starts off pretty standard entries we first have the option to find a user based on common features you would expect such as the auth token phone etc however we also need some more elaborate location-based queries in this case i verify that the entry is a driver by always passing true to the driver value i also use the between keyword to make sure that the entries i find fall between the given latitude longitude values the find by driver method finds all the drivers in a region it\u0026rsquo;s useful to draw the driver on the map even if they are currently busy the second method returns only the available drivers and is used when hailing like before we need a data access object or dao to abstract the underlying user object and make client server communication easier notice several things about this dao first notice that we don\u0026rsquo;t provide the of avatar in the dial it doesn\u0026rsquo;t really fit here as we\u0026rsquo;ll apply it directly to the image also notice that the auth token and password are never returned from the server they are there for the client requests only in this case the password would be the actual password and not the hash as the client doesn\u0026rsquo;t know the hash and the server doesn\u0026rsquo;t store the password i\u0026rsquo;ll skip the rest of the code as it\u0026rsquo;s pretty obvious including constructors setters and getters we create the user dao instances in the server by asking the user object notice we have two versions of the method one of which includes some private information and is useful internally the other is the one we need to ask for when dealing with client requests the user service class is a business object that abstracts the user access code if we think of the user object as the database abstraction and the dao as a communication abstraction the service is the actual api of the server we will later wrap it with a web service call to make that api accessible to the end user this might seem like an overkill with too many classes which is a common problem for java developers however in this case it\u0026rsquo;s justified by using the service class i can build unit tests that test the server logic only without going through the complexities of the web tier i can also connect some of the common apis to the websocket layer moving forward so having most of my business logic in this class makes a lot of sense i have two other wired values here first is the crude interface we discussed earlier the tarkan used to work with users and drivers the second one is this spring boot interface used to hash and salt the passwords just using this interface means that even in a case of a hack your user\u0026rsquo;s passwords would still be safe i\u0026rsquo;ll discuss this further soon adding a user consists of creating a new user object with the dao and invoking the built-in crude save method here we encode the password this is pretty seamless in spring but remarkably secure as it uses a salted hash passwords aren\u0026rsquo;t encrypted they are hashed and salted encryption is a two-way algorithm you can encode data and then decode it back hashing codes the data in such a way that can\u0026rsquo;t be reversed to verify the password we need to rehash it and check the hashed strings hashing alone isn\u0026rsquo;t enough as it can be assaulted with various attacks one of the tricks against hash attacks is salt the salt is random data that\u0026rsquo;s injected into the hash an attacker can distinguish between the salt and hash data which makes potential attacks much harder the password hashing algorithm of spring boot always produces a 60 character string which would be pretty hard to crack i\u0026rsquo;ll soon discuss the process of checking a password for validity as it\u0026rsquo;s a pretty big subject notice that get avatar uses the id value that leaves a small security weakness where a user can scan the ids for images of the drivers users i\u0026rsquo;m not too concerned about that issue so i\u0026rsquo;m leaving it in place however letting a user update the avatar is something that needs a secure token continuing with the security aspect notice that things such as password and token are special cases that we don\u0026rsquo;t want to update using the same flow as they are pretty sensitive we have three login methods and they are all technically very similar so they all delegate to a single login api call they all throw the user authentication exception which is a simple subclass of exception if a user wasn\u0026rsquo;t found in the list we failed this should never ever happen but it\u0026rsquo;s important to test against such conditions as during a hack these should never happen conditions might occur since the passwords are hashed and sorted we can\u0026rsquo;t just compare regenerating the hash and comparing that wouldn\u0026rsquo;t work either as salt is random the only way to test is to use the matches method we need to manually set the auth value as it\u0026rsquo;s not there by default to prevent a credential leak the one place where the auth value should exist is in the login process when we log in at first we need to check if the user with the given phone or social network exists the ui flow for users that exist and don\u0026rsquo;t exist is slightly different a small piece of the puzzle i skipped before is the security configuration class in spring boot we can use configuration classes like this instead of xml which i prefer by far first we need to disable some oauth and csrf attack protection both of these make a lot of sense for web-based javascript applications which are vulnerable to attacks and can use the built-in authentication but in a native app they just add complexity and overhead so they aren\u0026rsquo;t really necessary and can cause problems if you recall the password encoded from before this is the location where we include the actual implementation of this encoder you can place it in any configuration class but i thought it\u0026rsquo;s fitting to put it into the security configuration class so far so good but the user service is a server-only class we\u0026rsquo;d like to expose this functionality to the client code to do that we can add a json-based web service by using user web the user web service class notice that this is just a thin layer on top of the injected user service class the user service class we throw a user authentication exception when login failed this code automatically translates an exception of that type to an error dao object which returns a different error json effectively this means that when this exception type is thrown a user will receive a forbidden http response with the json body containing an error message of invalid password maps the user exists with phone number url so it will return true or false strings based on whether the user actually exists images just map to our url for the given image id so the url user slash avatar slash user id will return the image for the given user with the mime type image jpeg if the image isn\u0026rsquo;t there we\u0026rsquo;ll return an http not found error 404 which we can handle in the client code the user update avatar auth token api is a mime multipart upload request which we can use to upload an image a multi-part upload is encoded using base64 and is the http standard for file upload we check whether an id is set to determine if this is an add or an update operation however we don\u0026rsquo;t use the id value for editing then internally as the underlying api uses the token\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/048-11-the-spring-boot-server/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/EkiTDQn9Cpg?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003enow that we got the mock-up running\nlet\u0026rsquo;s jump to the other side of the\nfence and set up the server\nif you aren\u0026rsquo;t familiar with spring boot\nor mysql or don\u0026rsquo;t understand why i\npicked both of them i suggest\nchecking the previous modules where i\ndiscussed the reasons for this\nextensively and gave a long overview\nover both\nyou can create a new database by logging\ninto mysql and issuing a create database\ncommand\ni created a new spring boot project\nwhich includes maven dependencies for\njpa which is the java persistence\narchitecture or hibernate\njersey which is the json and xml\nserialization framework\nweb which is useful for web service\ndevelopment\nwebsocket for connecting over the newer\nwebsocket protocol\nsecurity is mostly used for password\nhashing which we will discuss\nand mysql support is needed for the jdbc\nconnectivity\nand finally braintree for the payment\nprocessing we\u0026rsquo;ll need later on\nbefore we get into the code let\u0026rsquo;s take a\nminute or so to think about the things\nwe need from the server\nthe first thing the server needs to\noffer\nis an ability to add a new user\nwe also need\nauthentication and authorization for the\nuser such as password validation and\nauthentication\nwe need a way to update the user\ninformation\nwe need to track car positions so we can\nshow them on the map\nwe need the ability to hail a car and\npick up\na driver\nwe\nneed a\nwe need to pay the hailed car so the\nsystem knows the car is paired to us\nwe need to log every trip taken\nincluding distance path etc\nand finally we need to provide rating\nfacility so we can rate the drivers\ni\u0026rsquo;m\nglossing over some things here such as\nbilling push etc\nnow that we have a spring boot project\nlet\u0026rsquo;s skip ahead to the server code\nwe\u0026rsquo;ll start with storage which is a good\nplace to start a common design strategy\nis deciding on the data structure and\nthen filling in the blanks\na good way to decide on the elements we\nneed in the user object is through the\nui\nthe account setting class contains\na lot of the data we need\nthe user jpa entity uses an auto\nincrement id value for simplicity\nlet\u0026rsquo;s go over the various pieces here\nthese are\npart of the user settings such as\njust general configuration\nthe password stores\nthe hashed value of password and not the\nplain text version we\u0026rsquo;ll discuss hashing\npasswords soon\nwe will use these when we need to enable\nlogin with a social network account\nthese are the internal network ids\nwe\u0026rsquo;ll\nuse for verification\na driver is also a user in the system\nif this user is a driver this is marked\nas true\nby referring to both the end user and\nthe driver with the same class we can\nsimplify the code\nif this is a driver\nthis is the description of his car\nwe\u0026rsquo;ll need for the app\nthis field is set to true\nif we are currently in the process of\nhailing a taxi\nif the taxi is taken by user this field\nmaps to the user id it is set to null if\nthe taxi is available\nwe will have a separate object dealing\nwith rating\nbut we can sum it for every query so the\nrating value will be cached here\nthis is the position and direction of\nthe current user\nwhether it\u0026rsquo;s a taxi or an end user\nnotice i chose to just store the\nlocation values instead of using one of\nthe custom location based apis\nsupported by hibernate and mysql\ni looked into those apis and they are\nvery powerful if you need complex\nlocation based apis\nbut for most simple purposes like we\nhave here\nthey are an overkill and would have made\nthe project more complex than it needs\nto be\nif you are building a complex gis\napplication i would suggest delving into\nsome of those custom apis\nthis is a picture of the user stored in\nthe database blob\none last column is the auth token which\nwe initialize with a unique random id\nwe will use this token to update the\nuser and perform operations only the\nuser is authorized for think of\nauthorization as a key to the server we\nwant to block a different user from\nsending a request that pretends to be\nour user\nthis is possible to do if a hacker\nsniffs out our network traffic and tries\nto pretend he\u0026rsquo;s our app\none approach would be sending the\npassword to the server every time\nbut that means storing and sending a\npassword which holds risk in this case\nwe generate a random and long key that\u0026rsquo;s\nhard to brute force\nwe send the key to the client\nand it stores that key\nfrom that point on we have proof that\nthis user is valid\ni\u0026rsquo;ve discussed this before in the\nrestaurant app if you want to check that\nout\nthe repository class\nfor the user starts off\npretty standard entries\nwe first\nhave the option to find a user based on\ncommon features\nyou would expect such as the auth token\nphone etc\nhowever\nwe also need some more elaborate\nlocation-based queries\nin this case\ni verify that the entry\nis a driver by always passing true to\nthe driver value\ni also use the between keyword to make\nsure that the entries i find\nfall between the given latitude\nlongitude values\nthe find by driver method finds all the\ndrivers in a region\nit\u0026rsquo;s useful to draw the driver on the\nmap\neven if they are currently busy\nthe second method returns only the\navailable drivers\nand is used when hailing\nlike before we need a data access object\nor dao to abstract the underlying user\nobject and make client server\ncommunication easier\nnotice several things about this dao\nfirst notice that we don\u0026rsquo;t provide the\nof avatar in the dial\nit doesn\u0026rsquo;t really fit here\nas we\u0026rsquo;ll apply it directly to the image\nalso notice that the auth token and\npassword are never returned from the\nserver they are there for the client\nrequests only\nin this case the password\nwould be the actual password and not the\nhash as the client doesn\u0026rsquo;t know the hash\nand the server doesn\u0026rsquo;t store the\npassword\ni\u0026rsquo;ll skip the rest of the code as it\u0026rsquo;s\npretty obvious\nincluding constructors\nsetters and getters\nwe create the user dao instances\nin the server by asking the user object\nnotice we have two versions of the\nmethod\none of which includes some private\ninformation and is useful internally\nthe other is the one we need to ask for\nwhen dealing with client requests\nthe user service class is a business\nobject that abstracts the user access\ncode\nif we think of the user object as the\ndatabase abstraction and the dao as a\ncommunication abstraction the service is\nthe actual api\nof the server we will later wrap it with\na web service call to make that api\naccessible to the end user\nthis might seem like an overkill with\ntoo many classes which is a common\nproblem for java developers\nhowever in this case it\u0026rsquo;s justified\nby using the service class i can build\nunit tests that test the server logic\nonly without going through the\ncomplexities of the web tier\ni can also connect some of the common\napis to the websocket layer moving\nforward\nso having most of my business logic in\nthis class makes a lot of sense\ni have two other wired values here\nfirst is the crude interface we\ndiscussed earlier the tarkan used to\nwork with users and drivers\nthe second one is this spring boot\ninterface\nused to hash and salt the passwords just\nusing this interface means that even in\na case of a hack your user\u0026rsquo;s passwords\nwould still be safe\ni\u0026rsquo;ll discuss this further soon\nadding a user consists of creating a new\nuser object\nwith the dao and invoking the built-in\ncrude save method\nhere we encode the password this is\npretty seamless in spring but remarkably\nsecure as it uses a salted hash\npasswords aren\u0026rsquo;t encrypted they are\nhashed and salted\nencryption is a two-way algorithm you\ncan encode data and then decode it back\nhashing codes the data in such a way\nthat can\u0026rsquo;t be reversed to verify the\npassword we need to rehash it and check\nthe hashed strings\nhashing alone isn\u0026rsquo;t enough\nas it can be assaulted with various\nattacks\none of the tricks against hash attacks\nis salt\nthe salt is random data that\u0026rsquo;s injected\ninto the hash\nan attacker can distinguish between the\nsalt and hash data which makes potential\nattacks much harder\nthe password hashing algorithm of spring\nboot always produces a 60 character\nstring which would be pretty hard to\ncrack\ni\u0026rsquo;ll soon discuss the process of\nchecking a password for validity as it\u0026rsquo;s\na pretty big subject\nnotice that\nget avatar uses the id value that leaves\na small security weakness\nwhere a user can scan the ids for images\nof the drivers users\ni\u0026rsquo;m not too concerned about that issue\nso i\u0026rsquo;m leaving it in place however\nletting a user update the avatar is\nsomething that needs a secure token\ncontinuing with the security aspect\nnotice that things such as password and\ntoken are special cases that we don\u0026rsquo;t\nwant to update using the same flow as\nthey are pretty sensitive\nwe have\nthree login methods\nand they are all technically very\nsimilar so they all delegate to a single\nlogin api call\nthey all throw the user authentication\nexception which is a simple subclass of\nexception\nif a user wasn\u0026rsquo;t found in the list\nwe failed\nthis should never\never happen but it\u0026rsquo;s important to test\nagainst such conditions as during a hack\nthese should never happen conditions\nmight occur\nsince the passwords are hashed and\nsorted\nwe can\u0026rsquo;t just compare\nregenerating the hash and comparing that\nwouldn\u0026rsquo;t work either as salt is random\nthe only way to test is to use the\nmatches method\nwe need to manually set the auth value\nas it\u0026rsquo;s not there by default to prevent\na credential leak\nthe one place where the auth value\nshould exist is in the login process\nwhen we log in\nat first we need to check if the user\nwith the given phone or social network\nexists\nthe ui flow for users that exist and\ndon\u0026rsquo;t exist is slightly different\na small piece of the puzzle i skipped\nbefore is the security configuration\nclass\nin spring boot we can use configuration\nclasses like this instead of xml\nwhich i prefer by far\nfirst we need to disable some oauth and\ncsrf attack protection\nboth of these make a lot of sense for\nweb-based javascript applications which\nare vulnerable to attacks\nand can use the built-in authentication\nbut in a native app they just add\ncomplexity and overhead so they aren\u0026rsquo;t\nreally necessary and can cause problems\nif you recall the password encoded from\nbefore\nthis is the location where we include\nthe actual implementation of this\nencoder\nyou can place it in any configuration\nclass but i thought it\u0026rsquo;s fitting to put\nit into the security configuration class\nso far so good\nbut the user service is\na server-only class\nwe\u0026rsquo;d like to expose this functionality\nto the client code to do that we can add\na json-based web service by using user\nweb the user web service class\nnotice that this is just a thin layer on\ntop of the injected user service class\nthe user service class we throw a\nuser authentication exception when login\nfailed\nthis code automatically translates an\nexception of that type to an error dao\nobject which returns a different error\njson effectively\nthis means that when this exception type\nis thrown a\nuser will receive a forbidden http\nresponse\nwith the json body containing an error\nmessage of invalid password\nmaps the\nuser exists with phone number url so it\nwill return true or\nfalse strings based on whether the user\nactually exists\nimages just map to our url for the given\nimage id so the url user slash avatar\nslash user id will return the image for\nthe given user with the mime type image\njpeg if the image isn\u0026rsquo;t there we\u0026rsquo;ll\nreturn an http not found\nerror 404\nwhich we can handle in the client code\nthe user update avatar auth token api is\na mime multipart upload request\nwhich we can use to upload an image\na multi-part upload is encoded using\nbase64 and is the http standard for file\nupload\nwe check whether an id is set\nto determine\nif this is\nan add or an update operation however we\ndon\u0026rsquo;t use the id value for editing then\ninternally as the underlying api uses\nthe token\u003c/p\u003e","title":"11. The Spring Boot Server"},{"content":" Module 12: Creating an Uber Clone\nTranscript continuing the server side code will now delve into the location logic which maps to the websocket support in spring boot WebSockets websocket is a special type of socket that is created through http or https request a web server that supports web sockets opens a regular http connection and then uses the socket open there to continue working as a regular socket as a result the websocket setup is slower than a regular tcp socket but they provide the same level of flexibility after creation the advantage over tcp sockets is compatibility and the ability to patch pass through potential problematic firewalls as those would see a websocket as another http connection the websocket api includes two types of packets text and binary in this case i\u0026rsquo;ll use the binary protocol because it\u0026rsquo;s pretty easy to do this in java up until now all our communications went through web services which is convenient and scalable the fact we can use tools like curl and the network monitor to see what is going on under the hood is very helpful however web services suffer from the performance overhead and fixed structure issues of http for more interactive data we would prefer something like websockets some people use websockets for all their communications and it might work for your use cases a lot of developers use the text-based websocket as a substitute to web services altogether and in some cases that makes sense however as i mentioned before we have decades of experience with http it works well and has a huge infrastructure of tools behind it websockets are a low level api there are some higher level abstractions on top of them but these often go back to the problems of http without giving much in return WebSocketConfig spring boot has decent support for websockets but you need to activate it first we need to define a configuration class that sets up the websocket environment this class serves as a configuration tool for the websocket api defining limits quotas and handlers here i set common configuration arguments for websocket messages setting buffer sizes for the different types here i find the handler class to the ws msg url which will receive all of the websocket callbacks before we go into the handler class let\u0026rsquo;s create a special service class to handle location-based callbacks similarly to the user service LocationService most of the location apis map to the user class but it\u0026rsquo;s logically separate from the user service we will periodically update the user\u0026rsquo;s location notice that location can only be updated by the user himself as the token is required for that operation it\u0026rsquo;s more intuitive to work with radius from the client but the jpa query language makes it easier to work in absolute coordinates so i convert the kilometer radius unit to latitude longitude values we have two versions of the query one finds all of the drivers in the area so we can draw them on the map the second searches for available drivers only for hailing purposes i use a version of the method that only returns a part of the user data as we normally don\u0026rsquo;t need all of the data once this is in place we can implement the handler class which is the actual websocket implementation but first let\u0026rsquo;s review the communication Handler - Packet structure for location update protocol this is the binary structure we will use when receiving request on the server for a location update so when a user changes his current location we will send this data the message type should be 1 for a location update from the user the length of the user token string followed by a byte array of the token length representing the string notice that i used bytes instead of cars since the token is 100 ascii i can rely on that fact and reduce the packet size further the location data and the radius slash direction of the user a byte which is set to one when we are hailing a taxi in which case it will seek only the available drivers once this packet is processed the server would return the cars within the search radius by sending a packet back Handler - Packet structure for response in this case we don\u0026rsquo;t need the token as this is a message from the server the response type can be 2 for driver position update and 3 for available driver position update the entry indicates the number of drivers in the returned data the rest of the lines repeat for every driver response size times and include the position data for every driver now that we understand the protocol let\u0026rsquo;s dig into the code that implements it the handler class is a binary websocket handler that receives callbacks on incoming packets let\u0026rsquo;s go over the code these are constants used in the binary protocol to communicate the type of request or response this is a callback for a binary message from the client the api works with nios bytebuffer which allows us to run through a request efficiently we get the length of the user token string and the battery again i used bytes instead of cars since the token is 100 ascii we can rely on that assuming this is a location update we pull out the data and update the user object we prepare to return a response based on the seeking flag we also need to mark the response type correctly i used a bytearray output stream to construct the response i use try with resources to close the streams automatically when i\u0026rsquo;m done i just write out the response data to the stream and finally we convert the battery data from the stream to a battery then send to the client this is it for the basic server code\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/049-12-server-websocket-handler/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/3-ZH2IFIIMY?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003econtinuing the server side code will now\ndelve into the location logic\nwhich maps to the websocket support in\nspring boot\nWebSockets\nwebsocket is a special type of socket\nthat is created through http or https\nrequest\na web server that supports web sockets\nopens a regular http connection and then\nuses\nthe socket open there to continue\nworking as a regular socket\nas a result the websocket setup is\nslower than a regular tcp socket\nbut they provide the same level of\nflexibility\nafter creation\nthe advantage over tcp sockets is\ncompatibility and the ability to patch\npass through potential problematic\nfirewalls\nas those would see a websocket as\nanother http\nconnection\nthe websocket api includes two types of\npackets\ntext and binary\nin this case i\u0026rsquo;ll use the binary\nprotocol because it\u0026rsquo;s pretty easy to do\nthis in java\nup until now all our communications\nwent through web services\nwhich is convenient and scalable\nthe fact we can use tools like curl and\nthe network monitor to see what is going\non under the hood\nis very helpful\nhowever web services suffer\nfrom the performance overhead and fixed\nstructure issues of http\nfor more interactive data we would\nprefer something like websockets\nsome people use websockets for all their\ncommunications and it might work for\nyour use cases\na lot of developers use the text-based\nwebsocket as a substitute to web\nservices altogether\nand in some cases that makes sense\nhowever as i mentioned before we have\ndecades of experience with http it works\nwell and has a huge infrastructure of\ntools behind it\nwebsockets are a low level api there are\nsome higher level abstractions on top of\nthem\nbut these often go back to the problems\nof http without giving much in return\nWebSocketConfig\nspring boot has\ndecent support for websockets but you\nneed to activate it first\nwe need to define a configuration class\nthat sets up the websocket environment\nthis class serves as a configuration\ntool for the websocket api defining\nlimits quotas and handlers\nhere i set common configuration\narguments for websocket messages\nsetting buffer sizes\nfor the different types\nhere i find the handler class to the ws\nmsg url which will receive all of the\nwebsocket callbacks\nbefore we go into the handler class\nlet\u0026rsquo;s create a special service class to\nhandle location-based callbacks\nsimilarly to the user service\nLocationService\nmost of the location apis\nmap to the user class\nbut it\u0026rsquo;s logically separate from the\nuser service\nwe will periodically update the user\u0026rsquo;s\nlocation\nnotice that location can only be updated\nby the user himself\nas the token is required\nfor that operation\nit\u0026rsquo;s more intuitive to work with radius\nfrom the client but the jpa query\nlanguage\nmakes it easier to work in absolute\ncoordinates so i convert the kilometer\nradius unit\nto latitude longitude values\nwe have two versions of the query\none finds all of the drivers in the area\nso we can draw them on the map\nthe second searches for available\ndrivers\nonly for hailing purposes\ni use a version of the method that only\nreturns a part of the user data as we\nnormally don\u0026rsquo;t need\nall of the data\nonce this is in place we can implement\nthe handler class which is the actual\nwebsocket implementation\nbut first let\u0026rsquo;s review the communication\nHandler - Packet structure for location update\nprotocol this is the binary structure we\nwill use when receiving request\non the server for a location update\nso when a user changes his current\nlocation we will send this data\nthe message type should be 1 for a\nlocation update from the user\nthe length of the user token string\nfollowed by a byte array of the token\nlength representing the string\nnotice that i used bytes instead of cars\nsince the token is 100 ascii\ni can rely on that fact and reduce the\npacket size further\nthe location data and the radius\nslash direction of the user\na byte which is set to one when we are\nhailing a taxi in which case it will\nseek\nonly the available drivers\nonce this packet is processed the server\nwould return the cars within the search\nradius by sending a packet back\nHandler - Packet structure for response\nin this case we don\u0026rsquo;t need the token as\nthis is a message from the server\nthe response type can be 2 for driver\nposition update and 3 for available\ndriver position update\nthe entry\nindicates the number of drivers\nin the returned data\nthe rest of the lines repeat for every\ndriver\nresponse size times\nand include the position data for every\ndriver\nnow that we understand the protocol\nlet\u0026rsquo;s dig into the code that implements\nit\nthe handler class is a binary websocket\nhandler that receives callbacks on\nincoming packets\nlet\u0026rsquo;s go over the code\nthese are constants used in the binary\nprotocol to communicate the type of\nrequest or response\nthis is a callback for a binary message\nfrom the client\nthe api works with nios\nbytebuffer which allows us to run\nthrough a request\nefficiently\nwe get the length of the user token\nstring and the battery again i used\nbytes instead of cars since the token is\n100 ascii\nwe can rely on that\nassuming this is a location update\nwe pull out the data and update the user\nobject\nwe prepare to return a response based on\nthe seeking flag\nwe also need to mark the response type\ncorrectly\ni used a bytearray output stream to\nconstruct the response\ni use try with resources to close the\nstreams automatically when i\u0026rsquo;m done\ni just write out the response data to\nthe stream\nand finally we convert the battery data\nfrom the stream to a battery\nthen send to the client\nthis is it for the basic server code\u003c/p\u003e","title":"12. Server WebSocket Handler"},{"content":" Module 12: Creating an Uber Clone\nTranscript now that we have a server and a mock client we need to connect them together so we have a working prototype we also need to implement some core functionality such as sms activation before we get started we need to add some things to the client project first we need to add the websockets cn1 lib from the extension manager this is pretty simple to do if you already added a cn1 lib before next we need to sign up to twillow.com as developers they have a free trial account notice we don\u0026rsquo;t need to install support for the twillow lib since we already installed the sms activation cn1 lib before notice that we are sending the sms activation code from the client side this is a bad practice you should use the server twillo api and send the sms activation code from there i chose this approach because it\u0026rsquo;s seamless and shows the usage of the apis on the client which is what i\u0026rsquo;m trying to teach however keeping authentication code in the server is far more secure you will need the following values from the twillow developer account account id sid account sid auth token and phone number make sure to pick a us phone number for the free account otherwise payment would be required once you have those values you can create a new globals class which we will use for the global application data notice you might want to replace localhost with your ip during development so you can test the device against a server running on your machine the device would obviously need to be connected to the same wifi the following values are the values we have from twillow for convenience i used static import for these constants within the code the user class on the client side mirrors the user dao but uses the properties syntax so we can leverage observability json persistence and other core capabilities if you are familiar with properties already you won\u0026rsquo;t notice anything special about this class it\u0026rsquo;s just a standard property object if you aren\u0026rsquo;t familiar with properties please check out the video covering them as it would be helpful moving forward we need to define a connection layer that will abstract the server access code this will allow us flexibility as we modify the server implementation and the client implementation it will also make testing far easier by separating the different pieces into tiers the abstraction is similar to the one we have in the server i chose to go with a mostly static class implementation for the user service as it\u0026rsquo;s inherently a static web service it makes no sense to have more than one user service once logged in we will cache the current user object here so we have all the data locally and don\u0026rsquo;t need server communication for every query we bind the user object to preferences so changes to the user object implicitly connect to the preferences storage api and vice versa preferences allow us to store keys and values in storage which maps every entry to a similar key value pay whether we are logged in or not or out is determined by the token value we need that to send updates to the server side i\u0026rsquo;m creating the four digit verification code and sending it via the twillow sms web service api i\u0026rsquo;m also storing the value and preferences so i can check against it when it\u0026rsquo;s received even if the app dies for some reason this method is invoked to validate the received sms code notice i don\u0026rsquo;t just use equals instead the validation string might include the four sms text this can happen on android where we can automatically validate notice i still limit the length of the string to prevent an attack where a user can inject all possible four code combinations into this method maps to the user exists method in the server which we use to determine add slash login flows i use the rest api to make a single connection with the get method in this case the response is the string true or the string force so i can just check against the letter t when adding a user i use the rest api\u0026rsquo;s post method here i can set the body to the json content content of the user object the response is a string token representing the user which we can now store into preferences the login method accepts a phone and password and is invoked after we\u0026rsquo;ve validated the phone it can succeed or fail if we get back a token that means the user authentication exception wasn\u0026rsquo;t thrown in the server and we can set it into the preferences otherwise we need to send a failure callback\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/050-13-client-side-userservice/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/l97sDefhHMM?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003enow that we have a server and a mock\nclient we need to connect them together\nso we have a working prototype\nwe also need to implement some core\nfunctionality such as sms activation\nbefore we get started we need to add\nsome things to the client project\nfirst we need to add the websockets cn1\nlib from the extension manager this is\npretty simple to do\nif you already added a cn1 lib before\nnext we need to sign up to twillow.com\nas developers\nthey have a free trial account notice we\ndon\u0026rsquo;t need to install support for the\ntwillow lib since we already installed\nthe sms activation cn1 lib before\nnotice that we are sending the sms\nactivation code from the client side\nthis is a bad practice\nyou should use the server twillo api and\nsend the sms activation code from there\ni chose this approach because it\u0026rsquo;s\nseamless and shows the usage of the apis\non the client which is what i\u0026rsquo;m trying\nto teach\nhowever\nkeeping authentication code in the\nserver is far more secure\nyou will need the following values from\nthe twillow developer account\naccount id\nsid account sid\nauth token\nand phone number\nmake sure to pick a us phone number for\nthe free account otherwise payment would\nbe required\nonce you have those values you can\ncreate a new globals class which we will\nuse for the global application data\nnotice you might want to replace\nlocalhost with your ip during\ndevelopment so you can test the device\nagainst a server running on your machine\nthe device would obviously need to be\nconnected to the same wifi\nthe following values\nare the values we have from twillow\nfor convenience i used static import for\nthese constants within the code\nthe user class on the client side\nmirrors the user dao\nbut uses the properties syntax so we can\nleverage observability json persistence\nand other core capabilities\nif you are familiar with properties\nalready you won\u0026rsquo;t notice anything\nspecial about this class it\u0026rsquo;s just a\nstandard property object\nif you aren\u0026rsquo;t familiar with properties\nplease check out the video covering them\nas it would be helpful moving forward\nwe need to define a connection layer\nthat will abstract the server access\ncode this will allow us flexibility as\nwe modify the server implementation and\nthe client implementation it will also\nmake testing far easier by separating\nthe different pieces into tiers\nthe abstraction is\nsimilar to the one we have in the server\ni chose to go with a mostly static class\nimplementation for the user service\nas it\u0026rsquo;s inherently a static web service\nit makes no sense to have more than one\nuser service\nonce logged in\nwe will cache the current user object\nhere\nso we have all the data locally\nand don\u0026rsquo;t need server communication for\nevery query\nwe bind the user object to preferences\nso changes to the user object implicitly\nconnect to the preferences storage api\nand vice versa\npreferences allow us to store keys and\nvalues in storage which maps every entry\nto a similar key value pay\nwhether we are logged in or not or out\nis determined by the token value\nwe need that to send updates to the\nserver side\ni\u0026rsquo;m creating the four digit verification\ncode\nand sending it via the twillow sms web\nservice api\ni\u0026rsquo;m also storing the value and\npreferences so i can check against it\nwhen it\u0026rsquo;s received even if the app dies\nfor some reason\nthis method\nis invoked to validate the received sms\ncode\nnotice i don\u0026rsquo;t just use equals\ninstead the validation string might\ninclude the four sms text\nthis can happen on android where we can\nautomatically validate\nnotice i still limit the length of the\nstring to prevent an attack where a user\ncan inject all possible four code\ncombinations\ninto this method\nmaps to the user\nexists method in the server which we use\nto determine\nadd slash login flows\ni use the rest api to make a single\nconnection with the get method\nin this case the response is the string\ntrue or the string force so i can just\ncheck against the letter t\nwhen adding a user i use the rest api\u0026rsquo;s\npost method\nhere i can set the body to the json\ncontent content\nof the user object\nthe response is a string token\nrepresenting the user which we can now\nstore into preferences\nthe login method accepts a phone and\npassword and is invoked\nafter we\u0026rsquo;ve validated the phone\nit can succeed\nor fail\nif we get back a token that means the\nuser authentication exception\nwasn\u0026rsquo;t thrown in the server and we can\nset it into the preferences\notherwise we need to send a failure\ncallback\u003c/p\u003e","title":"13. Client Side UserService"},{"content":" Module 12: Creating an Uber Clone\nTranscript the next step is binding this to the ui for a fully working sms activation process the sms activation process is practically done the first step is in the enter mobile number form where we need to change the event handling on the floating action button this code might produce a dialog if we show it in the current form it might go back to this form instead of enter sms verification digits form by using this callback we can make sure the next form is shown only android supports intercepting sms\u0026rsquo;s so this code will only run on that platform in that case we automatically validate against the string we get from the next sms if that works we automatically skip ahead to the password form regardless of the above we send an sms message to the given phone number next we need to validate the input in a case where sms isn\u0026rsquo;t validated automatically or if the user rejected the permission on android we can do this in the enter sms verification digits form class by editing the is valid method this pretty much does the sms activation but we\u0026rsquo;d also want the countdown functionality to work if you recall the ui there is a countdown label for resending the sms to implement that we need to first define two new member variables and define two helper methods the vari the variables represent the countdown value in seconds for resending the sms and the timer object which we need to cancel once it elapses the format method formats time in seconds as two digits four minutes and two digits for seconds next we need to make the following changes to the constructor code we schedule the timer to elapse every second and repeat on the current form we update the text which we draws automatically notice that it\u0026rsquo;s also a good practice to revalidate normally but since the string size would be roughly the same this shouldn\u0026rsquo;t be necessary we cancel the timer so we don\u0026rsquo;t keep sending the sms\u0026rsquo;s over again notice we don\u0026rsquo;t cancel the timer in case of success we don\u0026rsquo;t need to since it\u0026rsquo;s a ui timer it\u0026rsquo;s bound to the form and once we leave the current form it will no longer elapse this sends us to the password entry form where we now have two versions of the ui we connect to the server to check if the user exists and shown infinite progress ui over the previous form if the user exists we show a welcome back prompt otherwise we enter a new password we also need to change the code that handles the floating action button event to actually add or load the user if the user exists we call the login method and show the map on success if the server returned an error on the login we dispose the progress dialog and show the error message label we prepared before we use revalidate as the error label size changed and will occupy more space if the user didn\u0026rsquo;t exist before we create a new user object and add that user to the server then show the map if the operation is successful the error handling code is pretty similar to the previous code\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/051-14-sms-activation-and-interception/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/TOWhbEhiRe4?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ethe next step is binding this to the ui\nfor a fully working sms activation\nprocess\nthe sms activation process is\npractically done\nthe first step is in the enter mobile\nnumber form where we need to change the\nevent handling on the floating action\nbutton\nthis code might produce a dialog\nif we show it in the current form it\nmight go back to this form instead of\nenter sms verification digits form\nby using this callback we can make sure\nthe next form is shown\nonly android supports intercepting sms\u0026rsquo;s\nso this code will only run on that\nplatform\nin that case we automatically validate\nagainst the string we get from the next\nsms\nif that works we automatically skip\nahead to the password form\nregardless of the above\nwe send an sms message\nto the given phone number\nnext we need to validate the input\nin a case where sms isn\u0026rsquo;t validated\nautomatically\nor if the user rejected the permission\non android\nwe can do this in the enter sms\nverification digits form class\nby editing the is valid method\nthis pretty much does the sms activation\nbut we\u0026rsquo;d also want the countdown\nfunctionality to work\nif you recall the ui there is a\ncountdown label for resending the sms\nto implement that we need to first\ndefine two new member variables and\ndefine two helper methods\nthe vari\nthe variables represent the countdown\nvalue in seconds\nfor resending the sms\nand the timer object\nwhich we need to cancel\nonce it elapses\nthe format method\nformats time in seconds as two digits\nfour minutes and two digits for seconds\nnext we need to make the following\nchanges to the constructor code\nwe schedule the timer to elapse every\nsecond and repeat on the current form\nwe update the text which we draws\nautomatically notice that it\u0026rsquo;s also a\ngood practice to revalidate normally\nbut since the string size would be\nroughly the same\nthis shouldn\u0026rsquo;t be necessary\nwe cancel the timer so we don\u0026rsquo;t keep\nsending the sms\u0026rsquo;s over again\nnotice we don\u0026rsquo;t cancel the timer in case\nof success we don\u0026rsquo;t need to\nsince it\u0026rsquo;s a ui timer it\u0026rsquo;s bound to the\nform and once we leave the current form\nit will no longer elapse\nthis sends us to the password entry form\nwhere we now have two versions of the ui\nwe connect to the server to check if the\nuser exists and shown infinite progress\nui\nover the previous form\nif the user exists we show a welcome\nback prompt\notherwise we enter a new password\nwe also need to change the code that\nhandles the floating action button event\nto actually add or load the user\nif the user exists\nwe call the login method and show the\nmap\non success\nif the server returned an error on the\nlogin\nwe dispose the progress dialog and show\nthe error message label\nwe prepared before\nwe use revalidate as the error label\nsize changed\nand will occupy more space\nif the user didn\u0026rsquo;t exist before we\ncreate a new user object and add that\nuser to the server\nthen show the map\nif the operation is successful the error\nhandling code is pretty similar to the\nprevious code\u003c/p\u003e","title":"14. SMS Activation and Interception"},{"content":" Module 12: Creating an Uber Clone\nTranscript next we\u0026rsquo;ll bind the websocket logic and map UI to bring this all together we can get started with a location service class similarly to the user service class that would abstract the local location unlock the user service class the location service class should also deal with the physical location of the device these are the same constants we have on the server when sending a location update to the server I don\u0026rsquo;t want to exceed a fixed amount of updates so we won\u0026rsquo;t burden the server or our Network the Clause has a private Constructor so the only way to create the location service is via the bind method which in turn invokes the instance method bind impul we provide two callbacks one is for a car being added which we will use to bind a new car to the UI and the other is for location updates so we can position the map location update notifies the server about changes to the location and also invokes the Callback once we can position the map we invoke the callback with the location so the map can be shifted to our current position once the server socket is connected we start sending location updates there we open the websocket connection using the connect call we cache the last set of values so we don\u0026rsquo;t send data to the server unless something changed easy threads lets us Post jobs onto a dedicated thread so we don\u0026rsquo;t have to block the main EDT it also means we don\u0026rsquo;t need to deal with synchronization or any other complexity related to that as all operations happen on that thread until on open is invoked the connection isn\u0026rsquo;t ready that\u0026rsquo;s why the server member field is only initialized here when it\u0026rsquo;s actually ready if we already have a location we should send a user location update one we have once we have the socket Connection in place the connection is single threaded as I mentioned before there is this it method is similar to is EDT and indicates if the current thread is the one managed by the easy thread if not we use the run runnable which invokes the Target runnable on the easy thread similarly to call serially if the values didn\u0026rsquo;t change since last update so we do nothing we don\u0026rsquo;t update too much there is a chance we\u0026rsquo;ll miss an update here but it\u0026rsquo;s probably not a deal breaker if a user didn\u0026rsquo;t move much we create a byte array output stream into which we construct the message that we received on the server with the header location Etc I currently hard coded a one kilometer search radius and find explicitly that we aren\u0026rsquo;t in taxi hailing mode one line to actually send the binary data it would be similar with text Data with the exception of passing overhead the IR exception isn\u0026rsquo;t likely as this is a ram-based stream the here we received the messages sent from the server specifically driver search result we store user instances in a map where the user ID is the key this saves us from sending duplicate core added events and allows us to just mutate the user properties which other code can observe using the built-in listeners and properties notice that this code is running on the websocket thread so events need to go back into the EDT to prevent potential issues this is really important we need to handle errors properly in a websocket application otherwise a failure can leave us without a connection the Callback interface is Trivial it\u0026rsquo;s mostly used as a Lambda expression in the code and that\u0026rsquo;s it for the location service\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/052-15-location-service-client-side/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/TRF76P1Dwwc?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003enext we\u0026rsquo;ll bind the websocket logic and\nmap UI to bring this all together\nwe can get started with a location\nservice class similarly to the user\nservice class that would abstract the\nlocal location\nunlock the user service class the\nlocation service class should also deal\nwith the physical location of the device\nthese are the same constants we have on\nthe server\nwhen sending a location update to the\nserver I don\u0026rsquo;t want to exceed a fixed\namount of updates so we won\u0026rsquo;t burden the\nserver or our Network\nthe Clause has a private Constructor so\nthe only way to create the location\nservice is via the bind method which in\nturn invokes the instance method bind\nimpul\nwe provide two callbacks one is for a\ncar being added which we will use to\nbind a new car to the UI and the other\nis for location updates so we can\nposition the map\nlocation update notifies the server\nabout changes to the location and also\ninvokes the Callback once we can\nposition the map\nwe invoke the callback with the location\nso the map can be shifted to our current\nposition\nonce the server socket is connected we\nstart sending location updates there\nwe open the websocket connection using\nthe connect call\nwe cache the last set of values so we\ndon\u0026rsquo;t send data to the server unless\nsomething changed\neasy threads lets us Post jobs onto a\ndedicated thread so we don\u0026rsquo;t have to\nblock the main EDT\nit also means we don\u0026rsquo;t need to deal with\nsynchronization or any other complexity\nrelated to that as all operations happen\non that thread\nuntil on open is invoked the connection\nisn\u0026rsquo;t ready\nthat\u0026rsquo;s why the server member field is\nonly initialized here\nwhen it\u0026rsquo;s actually ready\nif we already have a location we should\nsend a user location update\none we have once we have the socket\nConnection in place\nthe connection is single threaded as I\nmentioned before\nthere is this it method is similar to is\nEDT and indicates if the current thread\nis the one managed by the easy thread if\nnot we use the run runnable which\ninvokes the Target runnable on the easy\nthread similarly to call serially\nif the values didn\u0026rsquo;t change since last\nupdate so we do nothing\nwe don\u0026rsquo;t update too much there is a\nchance we\u0026rsquo;ll miss an update here but\nit\u0026rsquo;s probably not a deal breaker if a\nuser didn\u0026rsquo;t move much\nwe create a byte array output stream\ninto which we construct the message that\nwe received on the server with the\nheader location\nEtc\nI currently hard coded a one kilometer\nsearch radius and find explicitly that\nwe aren\u0026rsquo;t in taxi hailing mode\none line to actually send the binary\ndata it would be similar with text Data\nwith the exception of passing overhead\nthe IR exception isn\u0026rsquo;t likely as this is\na ram-based stream\nthe\nhere we received the messages sent from\nthe server specifically driver search\nresult\nwe store user instances in a map where\nthe user ID is the key\nthis saves us from sending duplicate\ncore added events and allows us to just\nmutate the user properties which other\ncode can observe using the built-in\nlisteners and properties\nnotice that this code is running on the\nwebsocket thread so events need to go\nback into the EDT to prevent potential\nissues\nthis is really important we need to\nhandle errors properly in a websocket\napplication otherwise a failure can\nleave us without a connection\nthe Callback interface is Trivial it\u0026rsquo;s\nmostly used as a Lambda expression in\nthe code\nand that\u0026rsquo;s it for the location service\u003c/p\u003e","title":"15. Location Service - Client Side"},{"content":" Module 12: Creating an Uber Clone\nTranscript we discussed the location service class now let\u0026rsquo;s see how this maps into the ui back in the map form we can change the map player code which during markup just featured a fixed position car image we bind to the location service where we get a callback every time a driver comes into play we create a label for every car and set the icon with the right angle we keep the angle in a client property so when there is a change event we can check if the angle actually changed one important piece of information that might not be clear from the code is that the core image must be square we use the rotate method on the car image which assumes a square image otherwise it will appear cropped we place the new car where the user is located thanks to the map layout the change listener on the angle property automatically rotates the icon image in the right direction but it does that only if the angle changed to avoid performance penalty we update latitude and longitude separately but we need to guard against duplicate changes so we first test the existing value we can\u0026rsquo;t replace a constraint in the layout so we remove the component and add it back animate layout should still work in this case and it will move the car gracefully to its new position once all of this is done we should be able to see everything working right now we don\u0026rsquo;t have drivers in our database but we can add a fake driver by pushing an entry to the mysql database this will create a fake driver entry and allow you to see him when you log in assuming you configured the values in globals.java you should be able to run the server and client then activate the device using sms and see the driver i used the password from my account so i would be able to log in as the driver later you can just copy the same password value from your account as you already know the password\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/053-16-connecting-the-location-service-to-the-map-form/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/ymocxBIQn0o?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ewe discussed the location service class\nnow let\u0026rsquo;s see how this maps into the ui\nback in the map form we can change the\nmap player code which during markup just\nfeatured a fixed position car image\nwe bind to the location service where we\nget a callback every time a driver comes\ninto play\nwe create a label for every car and set\nthe icon with the right angle we keep\nthe angle in a client property\nso when there is a change event\nwe can check if the angle actually\nchanged\none important piece of information that\nmight not be clear from the code is that\nthe core image must be square\nwe use the rotate method on the car\nimage which assumes a square image\notherwise it will appear cropped\nwe place the new car where the user is\nlocated\nthanks to the map layout\nthe change listener on the angle\nproperty\nautomatically rotates the icon image in\nthe right direction\nbut it does that only if the angle\nchanged\nto avoid performance\npenalty we update latitude and longitude\nseparately\nbut we need to guard against duplicate\nchanges so we first test the existing\nvalue\nwe can\u0026rsquo;t replace a constraint in the\nlayout so we remove the component and\nadd it back\nanimate layout should still work in this\ncase\nand it will move the car gracefully to\nits new position\nonce all of this is done\nwe should be able to see everything\nworking right now we don\u0026rsquo;t have drivers\nin our database but we can add a fake\ndriver by pushing an entry to the mysql\ndatabase\nthis will create a fake driver entry and\nallow you to see him when you log in\nassuming you configured the values in\nglobals.java you should be able to run\nthe server and client then activate the\ndevice using sms\nand see the driver\ni used the password from my account so i\nwould be able to log in as the driver\nlater\nyou can just copy the same password\nvalue from your account\nas you already know the password\u003c/p\u003e","title":"16. Connecting the Location Service to the Map Form"},{"content":" Module 12: Creating an Uber Clone\nTranscript we finally have a client server application that works but we don\u0026rsquo;t have any real functionality to get to that point we need some web services WebServices from the Device? i chose to invoke the google web services from the device code instead of using our server to proxy the calls i did this because this is a mobile programming course not a server development course this makes sense for a simple project and is arguably faster as i connect directly to google however if i was building a real world application i would have directed all requests to our server and invoked google from there this might have a performance penalty but it\u0026rsquo;s worth it here are some of the advantages api keys would be stored on the server and would thus be more secure from theft we can cache queries and reduce api costs between users currently i can only cache calls per user but if lots of people are searching for the same things this can add up i can use analytics and statistics in the server code and notice patterns about user behavior and finally i can switch to a different company for the web service implementation to get a better deal if google discontinues its service i don\u0026rsquo;t have to ship an app update either Googles GIS Services we\u0026rsquo;ll use four google location-based web services to implement the functionality of this app with geocoding we provide an address or location and get back a location on the map this is useful when a driver receives a set of locations and need to know the actual map coordinates reverse geocoding is the exact opposite it provides the name of a given location this is useful for pointing a pin on the map and naming the location directions provides directions trip time etc we can get the points of the path and plot them out on the map the places api allows searching for a place similar to the geocoding api the auto complete version lets us type into a text field and see suggestions appear we\u0026rsquo;ll use it for the search functionality New Fields in Globals all of these apis require developer keys which you can obtain from their respective websites i\u0026rsquo;ve edited the globals class to include these new keys required by the three apis make sure to replace the dashes with the relevant keys you can get the keys by going to the directions geocoding and places websites and follow the process there we use the maps api geocode json url for reverse geocoding google provides this example for usage of the api it\u0026rsquo;s just a latitude longitude pair and your api key Reverse Geocoding - Result the result of that url look like this response json let\u0026rsquo;s go over two important pieces we need to get this result array from the response we only care about the first element and will discard the rest this is the only attribute we need at this time from this api now that we know what we are looking for let\u0026rsquo;s look at the code that accomplishes this SearchService i\u0026rsquo;ll use the search service class to encapsulate this functionality for each of these services there is an edge case where location isn\u0026rsquo;t ready yet when this method is invoked in this case i found it best to just do nothing usually it\u0026rsquo;s best to fail by throwing an exception but that is a valid situation to which i have a decent fallback option so i prefer doing nothing if we send two such calls in rapid succession i only need the last one so i\u0026rsquo;m canceling the previous request the reverse geocode api latitude long argument determines the location for which we are looking we get the past result as a map containing a hierarchy of objects the callback is invoked asynchronously when the response arrives this gets the result list from the json and extracts the first element from there we extract the one attribute we care about the formatted address entry and invoke the callback method with this result the places autocomplete api is a bit more challenging since this api is invoked as a user types we\u0026rsquo;ll need the ability to cancel a request just as we would with the geocoding calls caching is also crucial in this case so we must cache as much as possible to avoid overuse of the api and performance issues let\u0026rsquo;s start by reviewing the api url and responses the default sample from google wasn\u0026rsquo;t very helpful so i had to read the docs a bit and came up with this url the search is relevant to a specific location and radius otherwise it would suggest places from all over the world which probably doesn\u0026rsquo;t make sense for an uber style application notice the radius is specified in meters the input value is a the string for which we would like autocomplete suggestions Places Autocomplete - Result this request produces this json result all predictions are again within an array but this time we\u0026rsquo;ll need all of them the ui would require the text broken down so we need the main text and we\u0026rsquo;ll need the secondary text to we\u0026rsquo;ll also need the place id and the reason for this is a huge omission in this api notice it has no location information we will need the place id value to query again for the location SuggestionResult before we move on to the code will need a way to send the results back we can do that with a list of suggestion result entries this is a pretty trivial class and doesn\u0026rsquo;t require any explaining the class solves the issue of getting the location for a specific entry with the method get location i won\u0026rsquo;t go too much into the details of that code above since it\u0026rsquo;s very similar to the code we saw before we just get additional details about a place and parse the results notice that this is a part of the suggestion result class so we don\u0026rsquo;t invoke this unless we actually need the location of a place there is one last thing we need before we go into the suggestion method itself we need variables to cache the data and current request otherwise multiple incoming requests might collide and block the network we need the last suggestion request so we can cancel it the last suggestion value lets us distinguish duplicate values this can sometimes happen as an edit event might repeat a request that was already sent for example if a user types and deletes a character this can happen since we will wait two 500 milliseconds before sending characters the location cache reduces duplicate requests notice that this can grow to a level of a huge memory leak but realistically that would require a huge number of searches if this still bothers you we can have the cash map class that serializes extra data to storage\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/054-17-reverse-gecoding-google-webservice/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/A72rY4rU7E0?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ewe finally have a client server\napplication that works\nbut we don\u0026rsquo;t have any real functionality\nto get to that point we need some web\nservices\nWebServices from the Device?\ni chose to invoke the google web\nservices from the device code instead of\nusing our server to proxy the calls\ni did this because this is a mobile\nprogramming course not a server\ndevelopment course\nthis makes sense for a simple project\nand is arguably faster as i connect\ndirectly to google\nhowever if i was building a real world\napplication i would have directed all\nrequests to our server and invoked\ngoogle from there\nthis might have a performance penalty\nbut it\u0026rsquo;s worth it\nhere are some of the advantages\napi keys would be stored on the server\nand would thus be more secure from theft\nwe can cache queries and reduce api\ncosts between users\ncurrently i can only cache calls per\nuser but if lots of people are searching\nfor the same things\nthis can add up\ni can use analytics and statistics in\nthe server code\nand notice patterns about user behavior\nand finally i can switch to a different\ncompany for the web service\nimplementation to get a better deal\nif google discontinues its service i\ndon\u0026rsquo;t have to ship an app update either\nGoogles GIS Services\nwe\u0026rsquo;ll use\nfour google location-based web services\nto implement the functionality of this\napp\nwith geocoding we provide an address or\nlocation and get back a location on the\nmap\nthis is useful when a driver receives a\nset of locations and need to know\nthe actual map coordinates\nreverse geocoding\nis the exact opposite\nit provides the name of a given location\nthis is useful for pointing a pin on the\nmap and naming the location\ndirections provides\ndirections trip time etc we can get the\npoints of the path and plot them out on\nthe map\nthe places api allows searching for a\nplace similar to the geocoding api\nthe auto complete version\nlets us type into a text field and see\nsuggestions appear\nwe\u0026rsquo;ll use it for the search\nfunctionality\nNew Fields in Globals\nall of these apis require developer keys\nwhich you can obtain from their\nrespective websites\ni\u0026rsquo;ve edited the globals class to include\nthese new keys required by the three\napis\nmake sure to replace the dashes with the\nrelevant keys\nyou can get the keys by going to the\ndirections geocoding and places websites\nand follow the process\nthere\nwe use the maps api geocode json url for\nreverse geocoding\ngoogle provides this example for usage\nof the api\nit\u0026rsquo;s just a latitude longitude pair\nand your api key\nReverse Geocoding - Result\nthe result of that url\nlook like this response json\nlet\u0026rsquo;s go over two important pieces\nwe need to get this result array from\nthe response\nwe only care about the first element and\nwill discard the rest\nthis is the only attribute we need at\nthis time from this api\nnow that we know what we are looking for\nlet\u0026rsquo;s look at the code that accomplishes\nthis\nSearchService\ni\u0026rsquo;ll use the search service class to\nencapsulate this functionality\nfor each of these services\nthere is an edge case where location\nisn\u0026rsquo;t ready yet when this method is\ninvoked\nin this case i found it best to just do\nnothing\nusually it\u0026rsquo;s best to fail by throwing an\nexception\nbut that is a valid situation\nto which i have a decent fallback option\nso i prefer doing nothing\nif we send two such calls in rapid\nsuccession i only need the last one\nso i\u0026rsquo;m canceling the previous request\nthe reverse geocode api\nlatitude long argument\ndetermines the location\nfor which we are\nlooking\nwe get the past result as a map\ncontaining a hierarchy of objects the\ncallback is invoked asynchronously\nwhen the response arrives\nthis gets the result list from the json\nand extracts the first element from\nthere\nwe extract the one attribute we care\nabout\nthe formatted address entry and invoke\nthe callback method with this result\nthe places autocomplete api is a bit\nmore challenging since this api is\ninvoked as a user types\nwe\u0026rsquo;ll need the ability to cancel a\nrequest just as we would with the\ngeocoding calls\ncaching is also crucial in this case\nso we must cache as much as possible to\navoid overuse of the api\nand performance issues\nlet\u0026rsquo;s start by reviewing the api url and\nresponses\nthe default sample from google wasn\u0026rsquo;t\nvery helpful so i had to read the docs a\nbit and came up with this url\nthe search is relevant to a specific\nlocation and radius\notherwise it would suggest places from\nall over the world which probably\ndoesn\u0026rsquo;t make sense for an uber style\napplication notice the radius is\nspecified in meters\nthe input value is a the string for\nwhich we would like\nautocomplete suggestions\nPlaces Autocomplete - Result\nthis request produces this json result\nall predictions\nare again within an array but this time\nwe\u0026rsquo;ll need all of them\nthe ui would require the text broken\ndown so we need the main text\nand we\u0026rsquo;ll need the secondary text to\nwe\u0026rsquo;ll also need the place id and the\nreason for this is a huge omission in\nthis api\nnotice it has no location information\nwe will need the place id value to query\nagain for the location\nSuggestionResult\nbefore we move on to the code\nwill need a way to send the results back\nwe can do that with a list of suggestion\nresult entries\nthis is a pretty trivial class and\ndoesn\u0026rsquo;t require any explaining\nthe class solves the issue of getting\nthe location for a specific entry\nwith the method get location\ni won\u0026rsquo;t go too much into the details of\nthat code above since it\u0026rsquo;s\nvery similar to the code we saw before\nwe just get additional details about a\nplace and parse the results\nnotice that this is a part of the\nsuggestion result class\nso we don\u0026rsquo;t invoke this unless we\nactually need the location of a place\nthere is one last thing we need before\nwe go into the suggestion method itself\nwe need variables to cache the data and\ncurrent request\notherwise multiple incoming requests\nmight collide and block the network\nwe need the last\nsuggestion request so we can cancel it\nthe last suggestion value\nlets us distinguish duplicate values\nthis can sometimes happen as an edit\nevent might repeat a request\nthat was already sent\nfor example if a user types and deletes\na character\nthis can happen since we will wait two\n500 milliseconds before sending\ncharacters\nthe location cache\nreduces duplicate requests notice that\nthis can grow to a level of a\nhuge memory leak\nbut realistically that would require a\nhuge number of searches\nif this still bothers you we can have\nthe cash map class\nthat serializes extra data to storage\u003c/p\u003e","title":"17. Reverse Gecoding Google Webservice"},{"content":" Module 12: Creating an Uber Clone\nTranscript we can now move forward to the last two pieces of the search service class if the last request is this request which can happen as a user types and deletes etc then we don\u0026rsquo;t want to do anything let the last request finish however if it isn\u0026rsquo;t then we want to kill the last request which might still be queued and blocking us from going forward we check if an entry is already in the cache as users might type and revise a lot thus triggering significant web service cost overhead we clean the variable values and then invoke the response notice i use call serially in this case to defer the response to the next cycle if we call back immediately we might delay the input code which is currently in place by shifting the callback to the next edt cycle we guarantee that suggest locations will behave in a similar way whether the data is cached locally or not the request extracts the predictions array so we can construct the result list we iterate over the entries notice i discard the generic context which is legal in java but might produce a warning i could have used a more elaborate syntax that would have removed the warning but that would have created more verbus code with no actual benefit i extract the elements from the map and create the suggestion result entries then store the whole thing in cash followed by the on success call notice that this in this case i didn\u0026rsquo;t need the call serially since the response is already asynchronous the final web service api we will cover is the directions api which will allow us to set the path taken by the car on the map the directions api is challenging it returns encoded data in a problematic format this is the sample query from google notice we can give the origin and destination values as longitude latitude pair which is what we\u0026rsquo;ll actually do the response is a bit large so i trimmed a lot of it to give you a sense of what we are looking for the one thing that matters to us from the response is the overview polyline entry which seems like a bunch of gibberish but it isn\u0026rsquo;t this is a special notation from google that encodes the latitude longitude values of the entire trip in a single string this encoding is described by google in their map documentation being lazy i found someone who already implemented the algorithm in java and his code worked as is i won\u0026rsquo;t go into the code since it\u0026rsquo;s mostly just bitwise shifting to satisfy requirements from google the method signature is the only thing that matters it takes an encoded string and returns the path matching that string as a list of coordinates that we will be able to add into the map shortly now that this is all out of the way the directions method is relatively simple this method is just another rest call that doesn\u0026rsquo;t include anything out of the ordinary we extract the overview polyline value and pass it to the callback response\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/055-18-directions-and-places-google-web-services/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/KhSWyE6rAN8?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ewe can now move forward to the last two\npieces of the search service class\nif the last request is this request\nwhich can happen as a user types and\ndeletes etc\nthen we don\u0026rsquo;t want to do anything\nlet the last request finish\nhowever\nif it isn\u0026rsquo;t then we want to kill the\nlast request which might still be queued\nand blocking us from going forward\nwe check if an entry is already in the\ncache\nas users might type and revise a lot\nthus triggering significant web service\ncost overhead\nwe clean the variable values\nand then invoke the response\nnotice i use call serially\nin this case to defer the response to\nthe next cycle\nif we call back immediately we might\ndelay the input code which is currently\nin place\nby shifting the callback to the next edt\ncycle we guarantee that suggest\nlocations will behave in a similar way\nwhether the data is cached locally or\nnot\nthe request extracts the predictions\narray so we can construct the result\nlist\nwe iterate over the entries\nnotice i discard the generic context\nwhich is legal in java but might produce\na warning\ni could have used a more elaborate\nsyntax that would have removed the\nwarning but that would have created more\nverbus code with no actual benefit\ni extract the elements from the map\nand create the suggestion result entries\nthen store the whole thing in cash\nfollowed by the on success call\nnotice that this in this case i didn\u0026rsquo;t\nneed the call serially since the\nresponse is already asynchronous\nthe final web service api we will cover\nis the directions api which will allow\nus to set the path taken by the car on\nthe map\nthe directions api is challenging it\nreturns encoded data in a problematic\nformat\nthis is the sample query from google\nnotice we can give the origin and\ndestination values as longitude latitude\npair\nwhich is\nwhat we\u0026rsquo;ll actually do\nthe response is a bit large so i trimmed\na lot of it to give you a sense of what\nwe are looking for\nthe one thing that matters to us from\nthe response\nis the overview polyline entry which\nseems like a bunch of gibberish but it\nisn\u0026rsquo;t\nthis is a special notation from google\nthat encodes the latitude longitude\nvalues of the entire trip in a single\nstring\nthis encoding is described by google\nin their map documentation\nbeing lazy i found someone\nwho already implemented the algorithm in\njava\nand his code worked as is\ni won\u0026rsquo;t go into the code since it\u0026rsquo;s\nmostly just bitwise shifting to satisfy\nrequirements from google\nthe method signature is the only thing\nthat matters\nit takes an encoded string and returns\nthe path matching that string\nas a list of coordinates that we will be\nable to add into the map\nshortly\nnow that this is all out of the way the\ndirections method is relatively simple\nthis method is just another rest call\nthat doesn\u0026rsquo;t include anything out of the\nordinary we extract the overview\npolyline value and pass it to the\ncallback response\u003c/p\u003e","title":"18. Directions and Places Google Web Services"},{"content":" Module 12: Creating an Uber Clone\nTranscript now that the basic infrastructure is out of the way we\u0026rsquo;ll start wiring it into the ui starting with search the initial search ui i did in the mock-up was very naive it just toggled the completion on and off the real uber app allows us to swipe the search ui down and then pick a location in a map using a pin this then updates the text field with the selected location alternatively if you type into the text field locations are suggested to you as you type there is a great deal of nuanced behavior in this ui so i only focused on the big ticket features the first big feature is the swipe down feature which allows us to swipe down the completion ui as we type the second is the actual completion ui where elements update as we type and finally the ability to point at a location on the map with a pin and select that location i didn\u0026rsquo;t implement a lot of the relatively easy features such as bookmarked locations or history in the search ui those should be trivial to fill in in order to implement these i moved most of the ui logic into separate classes specifically auto complete address input and completion container both of which i\u0026rsquo;ll discuss shortly a major feature of auto complete address input is its ability to fold slash unfold the completion container it accomplishes this by binding pointer listeners to the parent form and using them to implement the drag and drop behavior on the left you can see the search ui with completion suggestions appearing below when the suggestions are dragged down we can pick the location from the map as you can see on the right as the map is dragged the location name is updated into the text field i refactored some of the code from the map form class into the autocomplete address input class it made it easier to implement some of the related logic i chose to derive text field rather than encapsulated mostly due to convenience encapsulation would have worked just as well for this case with the exception of these last two variables every other variable here is in the service of the drag and drop logic we use the data change listener to send events to the completion logic however this callback can be very verbose and it\u0026rsquo;s sometimes invoked by set text the solution is a special version of set text that blocks this callback and reduces the noise in the completion code with the block change event variable the last focused text field is the one that now handles the completion so if the user was in the to text field everything typed will now impact the completion for two and vice versa pointer listeners on the form allow us to detect pointer events everywhere we bind them in the init component method and remove them in the de-initialize method this prevents a memory leak and a situation where pointer processing code keeps running and taking up cpu the initialize is invoked when a component is removed from the ui or its hierarchy is removed it\u0026rsquo;s also invoked when a different form is shown instead of the current form init component is invoked when a component is there it will be invoked if a component is added to an already showing form or if a parent form is shown you can rely on init component and de-initialize working in tandem they might be invoked multiple times in a valid situations for instance a dialogue shown on top of the form triggers a de-initialize on the components of the form followed by an init component when it\u0026rsquo;s disposed despite using the shorthand lambda syntax for event handling i need to keep a reference to the drag and release event objects so i can remove them later the dragged element is always the second element 0 is the first it can be dragged between the center location and the south location if this is indeed a drag operation we\u0026rsquo;d like to block the event from propagating onwards when a component is in the south we set its preferred size to 1 8 of the display height so it won\u0026rsquo;t peak up too much when it\u0026rsquo;s dragged up we just increase that size during drag components in the center ignore their preferred size and take up available space so we use margin to provide the drag effect this prevents a drag event on a different region of the form from triggering this event for instance if a user drags the map dragging just displayed a motion we now need to remove the component and place it where it should be we also reset the ui id so styling changes for instance margin unit type etc will reset to the default when we place the container in the south we set the preferred size and margin to match when we place it in the center we set the preferred size to null which will which is a special case that resets previous manual settings and restores the default the location of a text field uses strings but what we really care for care about is coordinates on the map which is why i store them here this is used both by the map pen logic and by the search logic we will use later\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/056-19-auto-complete-location-search-ui/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/Jk3tTyZroP0?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003enow that the basic infrastructure is out\nof the way\nwe\u0026rsquo;ll start wiring it into the ui\nstarting with search\nthe initial search ui i did in the\nmock-up was very naive\nit just toggled the completion on and\noff\nthe real uber app allows us to swipe the\nsearch ui down and then pick a location\nin a map using a pin\nthis then updates the text field with\nthe selected location\nalternatively if you type into the text\nfield locations are suggested to you as\nyou type\nthere is a great deal of nuanced\nbehavior in this ui so i only focused on\nthe big ticket features\nthe first big feature is the swipe down\nfeature which allows us to swipe down\nthe completion ui as we type\nthe second is the actual completion ui\nwhere elements update as we type\nand finally the ability to point at a\nlocation on the map\nwith a pin\nand select that location\ni didn\u0026rsquo;t implement a lot of the\nrelatively easy features such as\nbookmarked locations or history in the\nsearch ui\nthose should be trivial to fill in\nin order to implement these i moved most\nof the ui logic into separate classes\nspecifically auto complete address input\nand completion container both of which\ni\u0026rsquo;ll discuss shortly\na major feature of auto complete address\ninput is its ability to fold slash\nunfold the completion container\nit accomplishes this by binding pointer\nlisteners to the parent form and using\nthem to implement the drag and drop\nbehavior\non the left you can see the search ui\nwith completion suggestions appearing\nbelow\nwhen the suggestions are dragged down\nwe\ncan pick the location from the map as\nyou can see on the right\nas the map is dragged the location name\nis updated\ninto the text field\ni refactored some of the code from the\nmap form class into the autocomplete\naddress input class\nit made it easier to implement some of\nthe related logic\ni chose to derive text field rather than\nencapsulated\nmostly due to convenience\nencapsulation would have worked just as\nwell\nfor this case\nwith the exception of these last two\nvariables every other variable here is\nin\nthe service of the drag and drop logic\nwe use the data change listener to send\nevents to the completion logic\nhowever\nthis callback can be very verbose and\nit\u0026rsquo;s sometimes invoked by set text\nthe solution is a special version of set\ntext that blocks this callback and\nreduces the noise\nin the completion code\nwith the block change event variable\nthe last focused text field is the one\nthat now handles the completion\nso if the user was in the to text field\neverything typed will now impact the\ncompletion for two\nand vice versa\npointer listeners on the form allow us\nto detect pointer events everywhere\nwe bind them in the init component\nmethod and remove them in the\nde-initialize method\nthis prevents a memory leak and a\nsituation where pointer processing code\nkeeps running and taking up cpu\nthe initialize is invoked when a\ncomponent is removed from the ui or its\nhierarchy is removed\nit\u0026rsquo;s also invoked when a different form\nis shown instead of the current form\ninit component is invoked when a\ncomponent is there\nit will be invoked if a component is\nadded to an already showing form or if a\nparent form is shown\nyou can rely on init component and\nde-initialize working in tandem\nthey might be invoked multiple times in\na valid situations for instance a\ndialogue shown on top of the form\ntriggers a de-initialize on the\ncomponents of the form\nfollowed by an init component when it\u0026rsquo;s\ndisposed\ndespite using the shorthand lambda\nsyntax for event handling i need to keep\na reference to the drag and release\nevent objects so i can remove them later\nthe dragged element is always the second\nelement 0 is the first\nit can be dragged between the center\nlocation and the south location\nif this is indeed a drag operation we\u0026rsquo;d\nlike to block the event from propagating\nonwards\nwhen a component is in the south we set\nits preferred size to 1 8 of the display\nheight\nso it won\u0026rsquo;t peak up too much\nwhen it\u0026rsquo;s dragged up we just increase\nthat size during drag\ncomponents in the center ignore their\npreferred size and take up available\nspace so we use margin to provide the\ndrag effect\nthis prevents a drag event on a\ndifferent region of the form from\ntriggering this event\nfor instance if a user drags the map\ndragging just displayed a motion\nwe now need to remove the component and\nplace it where it should be we also\nreset the ui id\nso styling changes for instance margin\nunit type etc\nwill reset to the default\nwhen we place the container in the south\nwe set the preferred size and margin to\nmatch\nwhen we place it in the center we set\nthe preferred size to null which will\nwhich is a special case\nthat resets previous manual settings and\nrestores the default\nthe location of a text field\nuses strings\nbut what we really care for care about\nis\ncoordinates on the map\nwhich is why i store them here\nthis is used both by the map pen logic\nand by the search logic we will use\nlater\u003c/p\u003e","title":"19. Auto Complete Location Search UI"},{"content":" Module 12: Creating an Uber Clone\nTranscript we\u0026rsquo;ll continue the search ui implementation as we step into the completion container class the completion container tries to coordinate the two instances of the autocomplete address input class by providing a single class that handles the completion ui most of the code in this class should be very familiar and some of it is refactored code from the map form while other code relates to the suggest suggest location api we implemented earlier the name of the class is misleading completion container is not a container here instead of deriving i encapsulated the ui logic and tried to expose only the business logic event dispatches allow us to broadcast events using the add remove listener observer style api we use this dispatcher to broadcast an event when a user presses a completion button this method is invoked when completion is in progress it invokes the web service call to request completion suggestions for a given string we fill up the container with buttons if one of the buttons is pressed we fetch the location from the web service and fill it into the autocomplete address input we then fire the event dispatcher to process the actual selection in the ui we have two types of entries here one with only one line of text and one with two lines of text this is mostly in place to fit the ui ids correctly with the right underline behavior this method is invoked externally to clear up the content of the completion ui and show the clean set of initial options history is positioned here so we could later fill this with actual search history etc this method constructs and animates the completion ui into place notice that we place the content in a container which we wrap up in a border layout this allows us to manipulate the preferred size without breaking the scrolling behavior of the child container in order to accomplish the design for the buttons i had to add the where to button line to uiid it uses grey text on a transparent background padding aligns with the text above we keep the top padding to zero so it won\u0026rsquo;t drift away from the first line in the where to button margin is zero as usual we have an underline here instead of the underline of the first line of text we use a slightly smaller font but the standard main light font nevertheless\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/057-20-search-completion-container/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/T8l7k2OeGpo?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ewe\u0026rsquo;ll continue the search ui\nimplementation as we step into the\ncompletion container class\nthe completion container\ntries to coordinate the two instances of\nthe autocomplete address input class\nby providing a single class that handles\nthe completion ui\nmost of the code in this class should be\nvery familiar\nand some of it is refactored code from\nthe map form while other code relates to\nthe suggest suggest location api\nwe implemented earlier\nthe name of the class is misleading\ncompletion container is not a container\nhere instead of deriving i encapsulated\nthe ui logic and tried to expose only\nthe business logic\nevent dispatches allow us to broadcast\nevents\nusing the add remove listener observer\nstyle api\nwe use this dispatcher to broadcast an\nevent when a user presses a completion\nbutton\nthis method is invoked when completion\nis in progress\nit invokes the web service call to\nrequest completion suggestions for a\ngiven string\nwe fill up the container with buttons if\none of the buttons is pressed we fetch\nthe location from the web service and\nfill it into the autocomplete\naddress input\nwe then fire the event dispatcher to\nprocess the actual selection in the ui\nwe have two types of entries here\none with only one line of text and one\nwith two lines of text\nthis is mostly in place to fit the ui\nids correctly with the right underline\nbehavior\nthis method is invoked externally\nto clear up the content of the\ncompletion ui and show the clean set of\ninitial options\nhistory is positioned here\nso we could later fill this with actual\nsearch history etc\nthis method constructs and animates the\ncompletion ui into place\nnotice that we place the content in a\ncontainer which we wrap up in a border\nlayout\nthis allows us to manipulate the\npreferred size without breaking the\nscrolling behavior\nof the child container\nin order to accomplish the design for\nthe buttons i had to add the where to\nbutton line to uiid\nit uses grey text on a transparent\nbackground\npadding aligns with the text above\nwe keep the top padding to zero so it\nwon\u0026rsquo;t drift away from the first line in\nthe where to button\nmargin is zero\nas usual\nwe have an underline here instead of the\nunderline of the first line of text\nwe use a slightly smaller font but the\nstandard main light font nevertheless\u003c/p\u003e","title":"20. Search Completion Container"},{"content":" Module 12: Creating an Uber Clone\nTranscript next we\u0026rsquo;ll bring these changes into the map form class which handles the actual heavy lifting of search first we need to add a couple of members to the class some of these variables really exist in the method body i just move them into the class level i\u0026rsquo;m skipping that code since it\u0026rsquo;s pretty trivial we use map container to place a pin and position it we can track map position events using this object we need the last focused entry so we can set the text in the text field when the user drags the map to point at a location the listener is important for cleanup to prevent multiple listener instances that way we always have at most one the timer instance allows us to cancel it we use it to delay web service requests so we don\u0026rsquo;t send them too frequently the where to button we need to hide it when the search ui is showing and show it again when it\u0026rsquo;s done we place a lot of elements in that layer on top of the map it\u0026rsquo;s pretty useful indicates whether we are in the navigation mode or in another mode such as map or browse mode this is important as we can\u0026rsquo;t enter navigation mode twice Code now that we have these variables in place let\u0026rsquo;s look at the code we created and placed a new layer for the pin image placement this allows us to drag the completion container down and see the pin image on the map that also means we can remove it easily once we exit the search ui i refactored the text fields to use this new api and set the location to the current location be to the default normally a user wouldn\u0026rsquo;t enter the origin address only the destination so using the current location makes sense Map i\u0026rsquo;m using name my current location method to fetch the name of the location of origin the map listener is used for the point location on the map functionality if i drag the map it will fetch the location from there and set it to the last focused text field however we wait 500 millisecond seconds before doing that so we don\u0026rsquo;t send too many web service requests we cancel the timer if there is one that\u0026rsquo;s already in the waiting stage this used to be if layer dot get component count is greater than one but that doesn\u0026rsquo;t make sense anymore as the completion container is always there only folded or expanded so i check if the completion container is in the center or the south when a button is pressed in the search completion we get an event to begin navigation at which point we ask for directions and enter navigation mode i\u0026rsquo;ll discuss the whole navigation mode in the route section i use animation completion event to show the completion bar which also has an animation in place one thing i neglected to mention in the map is the map listener which we bind using this new method this prevents duplicate map listeners and allows us to easily clear the selection\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/058-21-plotting-the-route-on-the-map-setup/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/FKTM8jAepJs?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003enext we\u0026rsquo;ll bring these changes into the\nmap form class which handles the actual\nheavy lifting of search\nfirst we need to add a couple of members\nto the class\nsome of these variables really exist in\nthe method body\ni just move them into the class level\ni\u0026rsquo;m skipping that code since it\u0026rsquo;s pretty\ntrivial\nwe use map container to place a pin and\nposition it\nwe can track map position events using\nthis object\nwe need the last focused entry\nso we can set the text in the text field\nwhen the user drags the map to point at\na location\nthe listener is important for cleanup to\nprevent multiple listener instances\nthat way we always have at most one\nthe timer instance allows us to cancel\nit\nwe use it to delay web service requests\nso we don\u0026rsquo;t send them too frequently\nthe where to button\nwe need to hide it when the search ui is\nshowing and show it again when it\u0026rsquo;s done\nwe place a lot of elements in that layer\non top of the map\nit\u0026rsquo;s pretty useful\nindicates whether we are in the\nnavigation mode or in another mode such\nas map or browse mode\nthis is important as we can\u0026rsquo;t enter\nnavigation mode twice\nCode\nnow that we have these variables in\nplace\nlet\u0026rsquo;s look at the code\nwe created and placed a new layer for\nthe pin image placement\nthis allows us to drag the completion\ncontainer down and see the pin image on\nthe map\nthat also means we can remove it easily\nonce we exit the search ui\ni refactored the text fields to use this\nnew api\nand set the location to the current\nlocation\nbe to the default\nnormally a user wouldn\u0026rsquo;t enter the\norigin address\nonly the destination\nso using the current location makes\nsense\nMap\ni\u0026rsquo;m using\nname my current location method\nto fetch the name of the location of\norigin\nthe map listener is used for the point\nlocation on the map functionality\nif i drag the map it will fetch the\nlocation from there and set it to the\nlast focused text field\nhowever we wait 500 millisecond seconds\nbefore doing that\nso we don\u0026rsquo;t send too many web service\nrequests\nwe cancel the timer if there is one\nthat\u0026rsquo;s already in the waiting stage\nthis used to be if layer dot get\ncomponent count is greater than one\nbut that doesn\u0026rsquo;t make sense anymore as\nthe completion container is always there\nonly folded or expanded\nso\ni check if the completion container is\nin the center\nor the south\nwhen a button is pressed in the search\ncompletion we get an event to begin\nnavigation at which point we ask for\ndirections and enter navigation mode\ni\u0026rsquo;ll discuss the whole navigation mode\nin the route section\ni use animation completion event to show\nthe completion bar which also has an\nanimation\nin place\none thing i neglected to mention in the\nmap is the map listener\nwhich we bind using this new method\nthis prevents duplicate map listeners\nand allows us to easily clear the\nselection\u003c/p\u003e","title":"21. Plotting the Route On the Map - Setup"},{"content":" Module 12: Creating an Uber Clone\nTranscript with that out of the way search should work but how does it display the result for that we need to add additional features to the map form that address these capabilities before we go into that let\u0026rsquo;s check out what that means Ride Booking UI the ride booking ui plots the path of the ride on the map and includes two tags one pointing at your current location and one on the destination the first tag is divided to a time indication and name the latter only contains the name notice that the elements have rounded rectangle shape with a pointy end on one side to point at the position within the path Tags let\u0026rsquo;s start with creating these tags the tag code itself is trivial it\u0026rsquo;s just a label or a container with some details nothing special except for one important detail the black and white border in order to implement the unique shape of the tag i created a new border class notice i used the preferred width of the west component to determine the black section this is done in the black line position method before we go any further i\u0026rsquo;d like to make one point clear i would have used a nine piece border if this were a real application i would have just cut a nine piece border and moved on however since the point is teaching i chose to do this the hard way UI IDs before we get into the black and white border there are a few ui ids we need to define the navigation label uid is the black on white label that appears in the tag the only unique thing about it is the relatively small amount of padding so the tag doesn\u0026rsquo;t take up too much space the margin is predictably zero and the font is slightly smaller than usual the navigation minute label ui id is the white on black minute value it\u0026rsquo;s center aligned it has zero padding below to keep the text and number close together but has similar padding on the other side either sides to match the navigation label it has zero margin and it has a smaller font size than usual although not a tiny font the navigation minute disk label uid is used for the text below that the text with the word min it derives from navigation minute label and has an even smaller font size than that Border that these are out of the way let\u0026rsquo;s take a look at the border notice we can just subclass the border class just like we can implement painters etc this provides a similar path for customization but is sometimes more flexible most of this code is based on the built-in round wrecked border class drawing this type of border is pretty expensive so we draw onto an image and place that image in cache within the component using put client property we use this value as the key the black line position is used in the version of this border that\u0026rsquo;s partially black here we create the border image that we will cache for the given component since a shadow is set on the border and that can take up some processing power to speed this up we have two versions of the method fast and slow we call the fast one and invoke the slow one asynchronously to update the border we do a shadow effect by drawing a gradient with varying alpha degrees then blurring that out if we have a cached version of the border image we will just use that as the background of the component assuming the size of the component didn\u0026rsquo;t change otherwise we create that image and update it later with the slower version that includes the gradient shadow effect we create the shape of the component if it\u0026rsquo;s the one with the black line we place the corner in the top right otherwise we place it in the bottom left we can now fill out the shape as part of the image creation code if we have a black line we do the fill operation twice with different clip sizes to create that effect\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/059-22-plotting-the-route-on-the-map-to-from-tags/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/vjTexRDCihA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ewith that out of the way search should\nwork\nbut how does it display the result\nfor that we need to add additional\nfeatures to the map form that address\nthese capabilities\nbefore we go into that\nlet\u0026rsquo;s check out what that means\nRide Booking UI\nthe ride booking ui plots the path of\nthe ride on the map\nand includes two tags one pointing at\nyour current location and one on the\ndestination the first tag is divided to\na time indication and name\nthe latter only contains the name\nnotice that the elements have rounded\nrectangle shape\nwith a pointy end on one side to point\nat the position within the path\nTags\nlet\u0026rsquo;s start with creating these tags\nthe tag code itself is trivial it\u0026rsquo;s just\na label or a container with some details\nnothing special\nexcept for one important detail\nthe black and white border\nin order to implement the unique shape\nof the tag i created a new border class\nnotice i used the preferred width of the\nwest component to determine the black\nsection\nthis is done in the black line position\nmethod\nbefore we go any further i\u0026rsquo;d like to\nmake one point clear\ni would have used a nine piece border if\nthis were a real application i would\nhave just cut a nine piece border and\nmoved on\nhowever\nsince the point is teaching i chose to\ndo this the hard way\nUI IDs\nbefore we get into the black and white\nborder\nthere are a few ui ids we need to define\nthe navigation label uid\nis the black on white label that appears\nin the tag\nthe only unique thing about it\nis the relatively small amount of\npadding\nso the tag doesn\u0026rsquo;t take up too much\nspace\nthe margin is predictably zero\nand the font is slightly smaller than\nusual\nthe navigation minute label ui id\nis the white on black minute value\nit\u0026rsquo;s center aligned\nit has zero padding below to keep the\ntext and number close together\nbut has similar padding on the other\nside either sides to match the\nnavigation label\nit has zero margin\nand it has a smaller font size than\nusual although not a tiny font\nthe navigation minute disk label uid\nis used for the text below that the text\nwith the word min\nit derives from navigation minute label\nand has an even smaller font size than\nthat\nBorder\nthat these are out of the way\nlet\u0026rsquo;s take a look at the border\nnotice we can just subclass the border\nclass just like we can implement\npainters etc\nthis provides a similar path for\ncustomization but is sometimes more\nflexible\nmost of this code is based on the\nbuilt-in\nround wrecked border class\ndrawing this type of border is pretty\nexpensive\nso we draw onto an image and place that\nimage in cache within the component\nusing put client property\nwe use this value\nas the key\nthe black line position is used in the\nversion of this border that\u0026rsquo;s partially\nblack\nhere we create the border image that we\nwill cache for the given component\nsince a shadow is set on the border and\nthat can take up some processing power\nto speed this up we have two versions of\nthe method\nfast and slow we call the fast one and\ninvoke the slow one asynchronously to\nupdate the border\nwe do a shadow effect by drawing a\ngradient with varying alpha degrees then\nblurring that out\nif we have a cached version of the\nborder image we will just use that as\nthe background of the component\nassuming the size of the component\ndidn\u0026rsquo;t change\notherwise we create that image and\nupdate it later\nwith the slower version that includes\nthe gradient shadow effect\nwe create the shape of the component\nif it\u0026rsquo;s the one with the black line we\nplace the corner in the top right\notherwise we place it in the bottom left\nwe can now fill out the shape as part of\nthe image creation code\nif we have a black line we do the fill\noperation twice with different clip\nsizes to create that effect\u003c/p\u003e","title":"22. Plotting the Route On the Map - to/from Tags"},{"content":" Module 12: Creating an Uber Clone\nTranscript finally after all the buildup let\u0026rsquo;s draw the path on the map form we\u0026rsquo;ve had quite a bit of code and it brought us to the point where the navigation ui should function as expected this is implemented in the enter navigation mode method which i mentioned before as you might recall it it\u0026rsquo;s invoked when clicking an entry in the search results this method is invoked from a callback on navigation we have the coordinates of the path to display on the map as the arguments to the method as you may recall these coordinates are returned by the directions method the first thing we do is remove the existing search ui from the form and animate it out due to the way events are chained this method can be invoked more than once in some unique cases this works around that behavior we convert the path to an array and add it to the map this uses native path plotting for these coordinates i could have used a painter or something similar and might still use it later on i move the camera to show the entire path within the form i create the two tags and add them to the ui notice that the from tag has a right alignment also notice i used the trimmed string method to limit the string length i\u0026rsquo;ll cover that method soon the back behavior is just a button style to look like a command it invokes the exit navigation mode method which we will get to shortly this is the ui to approve the taxi we are ordering i used a white container with the form uiid on the south portion of the form as a layer Trimming before i continue i also use the trimmed string method in the code before to trim the tag components there isn\u0026rsquo;t much to say about this method we rely on the fact that addresses usually have a comma after them if the string is missing that or is too long we have special cases for those this guarantees a string of decent length for the tag elements Exit Navigation the one last missing piece of the code is the exit navigation mode call which just removes all the elements and sets the invisible pieces back to visible it\u0026rsquo;s pretty trivial UI we also have a few ui ids of note mentioned in the code the first is ride title which is the title area for the ride ui it\u0026rsquo;s pretty much a label so it has black over transparent colors but it\u0026rsquo;s centered it has the same padding as a label zero margin and same font margin separator is a separator that has marginal margins on the side which we use in the ride dialog other separators in the app reach the edge of their parent container it has a couple of pixels of padding in the bottom to leave room for the separator it has the margin to keep it away from the edges of the parent container and it features a standard underline border the black button is just a standard white over black button with center text alignment as is common with buttons it\u0026rsquo;s got some padding but not too much so it won\u0026rsquo;t look huge it\u0026rsquo;s got some margin so it won\u0026rsquo;t literally touch the things next to it and to compensate over smaller padding it uses a subtool round wrecked effect that just is just barely noticeable at 0.2 millimeters and it\u0026rsquo;s got a slightly larger regular font instead of the typical smaller light font once all of this is done we can just see navigation work and appear on the map as expected\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/060-23-plotting-the-route-on-the-map-completion/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/aW3OlGTmasw?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003efinally after all the buildup let\u0026rsquo;s draw\nthe path on the map form\nwe\u0026rsquo;ve had\nquite a bit of code and it brought us to\nthe point where the navigation ui should\nfunction as expected\nthis is implemented in the enter\nnavigation mode method\nwhich i mentioned before\nas you might recall it it\u0026rsquo;s invoked when\nclicking an entry in the search results\nthis method is invoked from a callback\non navigation\nwe have the coordinates of the path to\ndisplay on the map\nas the arguments to the method as you\nmay recall these coordinates are\nreturned by the directions\nmethod the first thing we do is remove\nthe existing search ui from the form\nand animate it out\ndue to the way events are chained this\nmethod can be invoked more than once in\nsome unique cases\nthis works around that behavior\nwe convert the path to an array and add\nit to the map\nthis uses native path\nplotting for these coordinates\ni could have used a painter or something\nsimilar\nand might still use it later on\ni move the camera to show the entire\npath within the form\ni create the two tags and add them to\nthe ui\nnotice that the from tag has a right\nalignment\nalso notice i used the trimmed string\nmethod to limit the string length\ni\u0026rsquo;ll cover that method soon\nthe back behavior is just a button style\nto look like a command it invokes the\nexit navigation mode method which we\nwill get to shortly\nthis is the ui to approve the taxi we\nare ordering\ni used a white container with the form\nuiid on the south portion of the form\nas a layer\nTrimming\nbefore i continue\ni also use the trimmed string method in\nthe code before to trim the tag\ncomponents\nthere isn\u0026rsquo;t much to say about this\nmethod we rely on the fact that\naddresses usually have a comma after\nthem\nif the string is missing that or is too\nlong we have special cases for those\nthis guarantees a string of decent\nlength\nfor the tag elements\nExit Navigation\nthe one last missing piece of the code\nis the exit navigation mode call\nwhich just removes all the elements and\nsets the invisible pieces back to\nvisible\nit\u0026rsquo;s pretty trivial\nUI\nwe also have a few ui ids of note\nmentioned in the code\nthe first is ride title which is the\ntitle area for the ride ui it\u0026rsquo;s pretty\nmuch a label so it has black over\ntransparent colors\nbut\nit\u0026rsquo;s centered\nit has the same padding as a label\nzero margin\nand same font\nmargin separator is a separator that has\nmarginal margins on the side\nwhich we use in the ride dialog\nother separators in the app\nreach the edge of their parent container\nit has a couple of pixels of padding in\nthe bottom\nto leave room for the separator\nit has the margin to keep it away from\nthe edges of the parent container\nand it features a standard underline\nborder\nthe black button\nis just a standard white over black\nbutton\nwith center text alignment as is common\nwith buttons\nit\u0026rsquo;s got some padding but not too much\nso it won\u0026rsquo;t look huge\nit\u0026rsquo;s got some margin so it won\u0026rsquo;t\nliterally touch\nthe things next to it\nand to compensate over smaller padding\nit uses a subtool round wrecked effect\nthat just\nis just barely noticeable at 0.2\nmillimeters\nand it\u0026rsquo;s got a slightly\nlarger regular font instead of the\ntypical smaller light font\nonce all of this is done we can just see\nnavigation work and appear on the map as\nexpected\u003c/p\u003e","title":"23. Plotting the Route On the Map - Completion"},{"content":" Module 12: Creating an Uber Clone\nTranscript now that we have a path on the map we can move forward to the hailing process the hailing process is relatively simple we tint the ui show a beacon and during that time we ask the server for a call we can start by adding an event handler to the black button from the enter navigation mode method we are effectively coloring the pin layer to create the tint effect we added a new blink dot class to implement the pausing blue dot effect another new api the hail ride method in location service allows us to hail a ride notice i don\u0026rsquo;t show anything when the ride is hailed i\u0026rsquo;ll add that workflow with the driver app later there is one uid we need to cover here and it\u0026rsquo;s the searching dialog ui id technically this ui element isn\u0026rsquo;t a dialog it is a label but it looks like a dialog padding is pretty standard for label we have some margin on the sides to space it out from the edges most uii of this ui id is pretty standard except for the use of the special mode of the round wrecked border the top only mode allows only the top portion to be rounded and the bottom appears square usually we use it to combine two borders together with different colours or ui ids in this case we give the component a feel of peaking from the bottom of the form the font is the standard font just like any other label the blinker.class is pretty trivial i could have used an animated gif but instead i just did this this is mostly for transparency we don\u0026rsquo;t really use the uid here i use low level animations here so the best practice is to register remove with init component slash the initialize the motion class represents a timed motion between values which allows us to animate a value from point x to point y in this case i\u0026rsquo;m just growing the circle using the value notice only the animate method mutates values as the paint method can be invoked more than once per cycle in theory the drawing logic is mostly hard-coded i would have used the shape api to get a more refined effect but it would have made things more complicated\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/061-24-hailing-in-the-client-showing-a-beacon/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/qEgDZHZJEYo?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003enow that we have a path on the map\nwe can move forward to the hailing\nprocess\nthe hailing process is relatively simple\nwe tint the ui show a beacon and during\nthat time we ask the server for a call\nwe can start by adding an event handler\nto the black button from the enter\nnavigation mode method\nwe are effectively coloring the pin\nlayer to create the tint effect\nwe added a new blink dot class\nto implement the pausing blue dot effect\nanother new api\nthe hail ride method in location service\nallows us to hail a ride\nnotice i don\u0026rsquo;t show anything when the\nride is hailed i\u0026rsquo;ll add that workflow\nwith the driver app later\nthere is one uid we need to cover here\nand it\u0026rsquo;s the searching dialog ui id\ntechnically this ui element isn\u0026rsquo;t a\ndialog it is a label\nbut it looks like a dialog\npadding is pretty standard for label\nwe have some margin on the sides to\nspace it out from the edges\nmost uii of this ui id is pretty\nstandard except for the use of the\nspecial mode of the round wrecked border\nthe top only mode allows only the top\nportion to be rounded and the bottom\nappears square\nusually we use it to combine two borders\ntogether\nwith different colours or ui ids\nin this case\nwe give the component a feel of peaking\nfrom the bottom of the form\nthe font is the standard font just like\nany other label\nthe blinker.class is pretty trivial\ni could have used an animated gif but\ninstead i just did this\nthis is mostly for transparency we don\u0026rsquo;t\nreally use\nthe uid here\ni use\nlow level animations here\nso the best practice is to register\nremove\nwith init component\nslash the initialize\nthe motion class represents a timed\nmotion\nbetween values which allows us to\nanimate a value from point x to point y\nin this case i\u0026rsquo;m just growing the circle\nusing the value\nnotice\nonly the animate method mutates values\nas the paint method can be invoked more\nthan once per cycle\nin theory\nthe drawing logic is mostly hard-coded\ni would have used the shape api to get a\nmore refined effect\nbut it would have made things more\ncomplicated\u003c/p\u003e","title":"24. Hailing in the Client - Showing a Beacon"},{"content":" Module 12: Creating an Uber Clone\nTranscript next we\u0026rsquo;ll go into the underlying business logic portion of the hailing process on the client up until now i kept hailing as a vague process i think uber probably has a far more elaborate system than the one i developed in an hour but this should work fine for most cases healing includes the following phases we mark what we are interested that we are interested in hailing in the location service websocket code the server checks which drivers are available in the area and returns to us their push keys we send push notifications to the available drivers as time moves on we expand the circle of search for drivers in order to do this i had to make some changes to the websocket protocol in the location service class but first we need some additional variables in the globals class i\u0026rsquo;ll go into more details on those values in the next chapter but for now we need the variables only all of these apis require developer keys which you can obtain from their respective websites i\u0026rsquo;ve edited the globals class to include these new keys required by the three apis right now we can leave these all blank and get to them later let\u0026rsquo;s move to the location service class and the variables i had to add when a driver accepts our hail the server sends a special message indicating that the hail was accepted previously we had two modes for polling the server for searching and not searching i added a third mode that allows us to disable hailing i\u0026rsquo;ve made the location service into a singleton this these represent whether we are hailing and if so to what radius we use a motion object to get a growing radius that will stretch over time to encapsulate a wider region for hailing our source and destination values which we need to broadcast a hail when we send a push notification to a car we need to make sure we didn\u0026rsquo;t already notify it the unique id of the driver we\u0026rsquo;ve found this is the callback we invoke when a driver is found now that these are out of the way let\u0026rsquo;s look at the other things that need doing we changed the way we handle communication protocol by and we added some additional details first we need to ignore location changes when doing hailing which we can do by adding that condition next we need to change the protocol a little bit this was previously limited to 0 only and now we check if we are in hailing mode during hailing mode the radius of search grows over time we send the from two values as utf-8 encoded strings which allows us to communicate locale specific locations when we turn off healing in the server it\u0026rsquo;s a one-time thing after it\u0026rsquo;s off we can go back to the regular mode this isn\u0026rsquo;t likely as this is a ram based stream we also need to handle message reception code this is a new special case that provides us with details on the driver that picked up the right we are provided with the driver id card and name notice we need the final user variable since car might change and the value that can change can\u0026rsquo;t be passed to an inner class or lambda in java this is a list of push keys who we should not notify i added a push token to the driver details so we can send a push message to a specific driver if the car wasn\u0026rsquo;t notified yet add it to the list of cars that we should notify we send the push message in a batch to speed this up we send push type 3 which includes a data payload the first section and a visual payload which you can see after the semicolon before we can compile that code we need to add a push token attribute to the user class finally we have the hail ride method which is relatively simple there isn\u0026rsquo;t much we need to cover here it just initializes the variables and starts the motion object for the expanding radius this should conclude the client side of the hailing process and now we need to address the server side\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/062-25-hailing-in-the-client-networking-and-sending-push-messages/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/54POZ4PFFBw?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003enext we\u0026rsquo;ll go into the underlying\nbusiness logic portion\nof the hailing process on the client\nup until now i kept hailing as a vague\nprocess\ni think uber probably has a far more\nelaborate system than the one i\ndeveloped in an hour\nbut this should work fine for most cases\nhealing includes the following phases\nwe mark what we are interested\nthat we are interested in hailing in the\nlocation service websocket code\nthe server checks which drivers are\navailable in the area and returns to us\ntheir push keys\nwe send push notifications to the\navailable drivers\nas time moves on we expand the circle of\nsearch for drivers\nin order to do this i had to make some\nchanges to the websocket protocol\nin the location service class\nbut first we need some additional\nvariables in the globals class\ni\u0026rsquo;ll go into more details on those\nvalues in the next chapter\nbut for now we need the variables only\nall of these apis require developer keys\nwhich you can obtain from their\nrespective websites\ni\u0026rsquo;ve edited the globals class to include\nthese new keys required by the three\napis\nright now we can leave these all blank\nand get to them\nlater\nlet\u0026rsquo;s move to the location service class\nand the variables i had to add\nwhen a driver accepts our hail\nthe server sends a special message\nindicating that the hail was accepted\npreviously we had two modes for polling\nthe server for searching and not\nsearching\ni added a third mode that allows us to\ndisable hailing\ni\u0026rsquo;ve made the location service into a\nsingleton\nthis these represent whether we are\nhailing\nand if so to what radius\nwe use a motion object to get a growing\nradius that will stretch over time to\nencapsulate a wider region for hailing\nour source and destination values which\nwe need to broadcast a hail\nwhen we send a push notification to a\ncar we need to make sure we didn\u0026rsquo;t\nalready notify it\nthe unique id of the driver we\u0026rsquo;ve found\nthis is the callback we invoke when a\ndriver is found\nnow that these are out of the way let\u0026rsquo;s\nlook at the other things that need doing\nwe changed the way we handle\ncommunication protocol by and we added\nsome additional details\nfirst we need to ignore location changes\nwhen doing hailing\nwhich we can do by adding that condition\nnext we need to change the protocol a\nlittle bit\nthis was previously limited to 0 only\nand now we check if we are in hailing\nmode\nduring hailing mode the radius of search\ngrows over time\nwe send the from two values as utf-8\nencoded strings\nwhich allows us to communicate locale\nspecific locations\nwhen we turn off healing in the server\nit\u0026rsquo;s a one-time thing after it\u0026rsquo;s off we\ncan go back to the regular mode\nthis isn\u0026rsquo;t likely as this is a ram based\nstream\nwe also need to handle\nmessage reception code\nthis is a new special case that provides\nus with details on the driver that\npicked up the right\nwe are provided with the driver id card\nand name\nnotice we need the final user variable\nsince car might change and the value\nthat can change\ncan\u0026rsquo;t be passed to an inner class or\nlambda in java\nthis is a list of push keys\nwho we should not notify\ni added a push token to the driver\ndetails so we can send a push message to\na specific driver\nif the car wasn\u0026rsquo;t notified yet\nadd it to the list of cars\nthat we should notify\nwe send the push message\nin a batch to speed this up\nwe send push type 3 which includes a\ndata payload the first section\nand a visual payload which you can see\nafter the semicolon\nbefore we can compile that code we need\nto add a push token attribute to the\nuser class\nfinally we have the hail ride method\nwhich is relatively simple\nthere isn\u0026rsquo;t much we need to cover here\nit just initializes the variables and\nstarts the motion object for the\nexpanding radius\nthis should conclude the client side of\nthe hailing process\nand now we need to address the server\nside\u003c/p\u003e","title":"25. Hailing in the Client - Networking and Sending Push Messages"},{"content":" Module 12: Creating an Uber Clone\nTranscript before we proceed into the actual driver app work and push notification we need to implement all the infrastructure in the server side i also need to implement some changes we need in the protocol start by looking at the uber class i had to add three new fields and modify slash add some methods hailing from and healing 2 allows us to communicate our trip details with the driver community i need the push token of drivers so we can hail them directly from the app i\u0026rsquo;ll discuss the ride dao class soon it allows us to send the details about the trip to drivers not much of a change but i added the push token to the user dao factory method ride isn\u0026rsquo;t as simple as rydao despite their common name it contains far more information currently we don\u0026rsquo;t use all of that but the fact that it\u0026rsquo;s logged will let you provide all of that information within the app or a management app easily the right class is a jpa entity similar to the user class i used an auto increment value for the id instead of a random string i wanted to keep things simple but notice this can expose a security vulnerability of scanning for rides the passenger and driver are relational database references to the respective database object representing each one of them the route itself is a set of waypoints sorted by the time associated with the given waypoint we\u0026rsquo;ll discuss waypoints soon enough but technically it\u0026rsquo;s just a set of coordinates i really oversimplified the cost field it should work for some and currency but it\u0026rsquo;s usually not as simple as that it\u0026rsquo;s important to use something like big decimal and not double when dealing with financial numbers as double is built for scientific usage and has rounding errors we have two balloon flags a ride is started once a passenger is picked up it\u0026rsquo;s finished once he is dropped off or if the ride was cancelled the companion crude ride repository is pretty standard with one big exception i added a special case finder that lets us locate the user that is currently hailing a call notice the syntax b dot driver dot id equals question mark 1 which points through the relation to the driver object the waypoint entity referenced from the right entity is pretty trivial notice we still need a unique id for a waypoint even if we don\u0026rsquo;t actually use it in code the interesting part here is the time value which is the value of system current time melees this allows us to build a path based on the time sequence it will also allow us to reconstruct a trip and generate additional details such as speed cost if we wish to do that in the future notice that there is also a waypoint repository interface i\u0026rsquo;m skipping it as it contains no actual code the right service class serves the same purpose as the user service class focusing on rides and driver related features i could have just stuck all of this logic into one huge class but separating functionality to different service classes based on logic makes sense we manipulate both the rides and users crude objects from this class healing is a transactional method this means that all operations within the method will either succeed or fail depending on the outcome this is important to prevent an inconsistent state in the database this method can be invoked to start and stop hailing in this case we use the assigned user property to detect if a driver accepted the ride if so we return the driver data to the client when a driver gets a notification of a ride he invokes this method to get back the data about the ride if the driver wishes to accept the ride he invokes this transactional method the method accepts the token from the driver and the id of the user hailing the right it creates a new write entity and returns its id from this point on we need to refer to the right id and not the user id or token start ride and finish ride are invoked by the driver when he picks up the passenger and when he drops him off normally finish ride should also handle elements like billing etc but i won\u0026rsquo;t go into that now the next step is bringing this to the user through a web service the ride web service class exposes the ride service call almost verb team to the client the get call fetches the right dial for the given user id start and finish rides are again very simple with only one argument which is the ride id we also have to add some minor changes to the uber service and location service classes let\u0026rsquo;s start with the user service class drivers need a push token so we can hail them this is always set outside of the user creation code for two reasons the first time around the user is created but the push key isn\u0026rsquo;t there yet it arrives asynchronously push is re-registered in every launch and refreshed so there is no reason to update the entire object for that the user web service class needs to mirror these changes obviously there isn\u0026rsquo;t much here we just added a new set push token url and we accept this update the location service needs a bit more work every time we update a user\u0026rsquo;s location we check if he\u0026rsquo;s a driver on a ride assuming we have a ride object we check if this is currently an ongoing ride that wasn\u0026rsquo;t finished if so we add a waypoint to the ride and update it so we can later on inspect the path of the ride this pretty much tracks rides seamlessly if we wanted to be really smart we could detect the driver and use a position to detect them traveling together and automatically handle the ride there are obvious problems with this as it means a user can\u0026rsquo;t order a cab for someone else but it might be an interesting feature since we have two close data points\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/063-26-driver-app-server/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/KckMUmmSzd4?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ebefore we proceed into the actual driver\napp work and push notification\nwe need to implement all the\ninfrastructure in the server side\ni also need to implement some changes we\nneed in the protocol\nstart by looking at the uber class\ni had to add three new fields and modify\nslash add some methods\nhailing from and healing 2 allows us to\ncommunicate our trip details with the\ndriver community\ni need the push token of drivers so we\ncan hail them directly from the app\ni\u0026rsquo;ll discuss the ride dao class soon it\nallows us to send the details about the\ntrip to drivers\nnot much of a change\nbut i added the push token to the user\ndao factory method\nride isn\u0026rsquo;t as simple as rydao despite\ntheir common name\nit contains far more information\ncurrently we don\u0026rsquo;t use all of that but\nthe fact that it\u0026rsquo;s logged will let you\nprovide all of that information within\nthe app or a management app easily\nthe right class is a jpa entity similar\nto the user class\ni used an auto increment value for the\nid instead of a random string\ni wanted to keep things simple\nbut notice this can expose a security\nvulnerability\nof scanning for rides\nthe passenger and driver are relational\ndatabase references to the respective\ndatabase object representing each one of\nthem\nthe route itself is a set of waypoints\nsorted by the time associated with the\ngiven waypoint\nwe\u0026rsquo;ll discuss waypoints soon enough but\ntechnically\nit\u0026rsquo;s just a set of coordinates\ni really oversimplified the cost field\nit should work for some and currency\nbut it\u0026rsquo;s usually not as simple as that\nit\u0026rsquo;s important to use something like big\ndecimal and not double when dealing with\nfinancial numbers\nas double is built for scientific usage\nand has rounding errors\nwe have two balloon flags a ride is\nstarted once a passenger is picked up\nit\u0026rsquo;s finished once he is dropped off or\nif the ride was cancelled\nthe companion crude ride repository\nis pretty standard with one big\nexception\ni added a special case finder that lets\nus locate the user that is currently\nhailing a call\nnotice the syntax b dot driver dot id\nequals\nquestion mark 1\nwhich points through the relation to the\ndriver object\nthe waypoint entity referenced from the\nright entity is pretty trivial\nnotice we still need a unique id for a\nwaypoint even if we don\u0026rsquo;t actually use\nit in code\nthe interesting part here\nis the time value\nwhich is the value of system current\ntime melees\nthis allows us to build a path based on\nthe time sequence\nit will also allow us to reconstruct a\ntrip and generate additional details\nsuch as speed cost\nif we wish to do that in the future\nnotice that there is also a waypoint\nrepository interface i\u0026rsquo;m skipping it as\nit contains no actual code\nthe right service class serves the same\npurpose as the user service class\nfocusing on rides and driver related\nfeatures\ni could have just stuck all of this\nlogic into one huge class\nbut separating functionality to\ndifferent service classes based on logic\nmakes sense\nwe manipulate both the rides and users\ncrude objects from this class\nhealing is a transactional method\nthis means that all operations within\nthe method will either succeed or fail\ndepending on the outcome this is\nimportant to prevent an inconsistent\nstate in the database\nthis method\ncan be invoked to start and stop hailing\nin this case we use the assigned user\nproperty to detect if a driver accepted\nthe ride\nif so we return the driver data to the\nclient\nwhen a driver gets a notification of a\nride he invokes this method\nto get back the data about the ride\nif the driver wishes to accept the ride\nhe invokes this transactional method\nthe method accepts the token from the\ndriver and the id of the user hailing\nthe right\nit creates a new write entity and\nreturns its id\nfrom this point on we need to refer to\nthe right id and not the user id or\ntoken\nstart ride and finish ride are invoked\nby the driver when he picks up the\npassenger and when he drops him off\nnormally\nfinish ride should also handle elements\nlike billing etc\nbut i won\u0026rsquo;t go into that now\nthe next step is bringing this to the\nuser through a web service\nthe ride web service class\nexposes the ride service call almost\nverb team to the client\nthe get call\nfetches the right dial\nfor the given user\nid start and finish rides are again very\nsimple with only one argument which is\nthe ride id\nwe also have to add some minor changes\nto the uber service and location service\nclasses\nlet\u0026rsquo;s start with the user service class\ndrivers need a push token so we can hail\nthem\nthis is always set outside of the user\ncreation code for two reasons\nthe first time around the user is\ncreated but the push key isn\u0026rsquo;t there yet\nit arrives asynchronously\npush is re-registered in every launch\nand refreshed so there is no reason to\nupdate the entire object for that\nthe user web service class needs to\nmirror these changes obviously\nthere isn\u0026rsquo;t much here we just added a\nnew set push token url\nand we accept this update\nthe location service\nneeds a bit more work\nevery time we update a user\u0026rsquo;s location\nwe check if he\u0026rsquo;s a driver on a ride\nassuming we have a ride object we check\nif this is currently an ongoing ride\nthat wasn\u0026rsquo;t finished\nif so\nwe add a waypoint to the ride and update\nit\nso we can later on inspect the path of\nthe ride\nthis pretty much tracks rides seamlessly\nif we wanted to be really smart we could\ndetect the driver and use a position to\ndetect them traveling together and\nautomatically handle the ride\nthere are obvious problems with this as\nit means a user can\u0026rsquo;t order a cab for\nsomeone else\nbut it might be an interesting feature\nsince we have two close data points\u003c/p\u003e","title":"26. Driver App Server"},{"content":" Module 12: Creating an Uber Clone\nTranscript the code for morph transitions broke another thing it broke the facebook or google login form which looks awful going in now because morph is generally designed for a specific form i want to use the vertical cover effect which is common on ios and looks pretty decent on android 2. cover slides the form on top of the existing form from the bottom it\u0026rsquo;s usually combined with uncover which slides the form out in the reverse way because of this unique semantic the cover transition uses both the in and out transition flags however this can pose a problem with the default out transition of the form that we are leaving in this case you would see the out animation of the login form which in this case is morph followed by the incoming cover animation the solution is to remove the out animation from the outgoing form and restore it to the original value when we get back we do that within the remove transition temporarily method which we call here from the facebook or google login form we need to remove both the in and out transitions as we might show a cover transition on top of another cover transition form when we return to the original form we restore its transitions to their original values we remove the show listener to prevent a memory leak and multiple restore calls when going back and forth\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/064-27-driver-app-server-websocket-portion/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/IaalGP1UDeU?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ethe code for morph transitions\nbroke another thing\nit broke the facebook or google login\nform\nwhich looks awful going in now because\nmorph is generally designed for a\nspecific form\ni want to use the vertical cover effect\nwhich is common on ios and looks pretty\ndecent on android 2.\ncover slides the form on top of the\nexisting form from the bottom\nit\u0026rsquo;s usually combined with uncover\nwhich slides the form out in the reverse\nway\nbecause of this unique semantic the\ncover transition uses both the in and\nout transition flags\nhowever this can pose a problem\nwith the default out transition of the\nform that we are leaving\nin this case you would see the out\nanimation of the login form\nwhich in this case is morph\nfollowed by the incoming cover animation\nthe solution is to remove the out\nanimation from the outgoing form\nand restore it to the original value\nwhen we get back\nwe do that within the remove transition\ntemporarily method\nwhich we call here from the facebook or\ngoogle login form\nwe need to remove both the in and out\ntransitions\nas we might show a cover transition\non top of another cover transition form\nwhen we return to the original form we\nrestore its transitions to their\noriginal values\nwe remove the show listener to prevent a\nmemory leak\nand multiple restore calls when going\nback and forth\u003c/p\u003e","title":"27. Driver App Server - WebSocket Portion"},{"content":" Module 12: Creating an Uber Clone\nTranscript when i started on this road i didn\u0026rsquo;t want to create a driver app and wanted to focus only on the client app unfortunately a driver app is unavoidable as the main app is useless without it unlike the main uber app i don\u0026rsquo;t want to clone the driver app as this would throw the whole course out of focus i decided to hack the existing app to implement driver specific features there and as a result we use a whole lot of code this means the driver app can reuse sign up map networking code etc this is important as code reuse breeds stability and maturity unfortunately it also means the app isn\u0026rsquo;t as well made as the main app since it was designed for end users with driver mode tacked on top Use Cases we often build one app and sell it to multiple customers after all most customers ask for similar things with minor changes for example if i build a restaurant app and then sell it to one establishment i can then resell it to another one with almost no change at all another common use case is the demo or free version of a paid app you want to use as much of the work as possible without maintaining two code bases another case which is relevant what i\u0026rsquo;m building today is two target audiences of roughly the same functionality for instance in this case the driver app has many common elements with the passenger app so why not build the same app with minor modifications the first thing we need to understand is how the app store identifies your application pretty much all apps use a unique identifier a string that is similar to package names which we map to which we map the main application package name so the trick is to add a new package for the new app Creating a New Package the basic hello driver would be something like this notice i chose to override the methods but i didn\u0026rsquo;t have to i could have just derived the main class and that would have been enough but i prefer overriding the lifecycle methods for clarity in this case this isn\u0026rsquo;t enough though the codename one settings properties file contains all of the internal configuration details about project i copied it aside and renamed it to codename one settings user properties i then edited the file to use the driver details and copied that into codename one settings driver properties notice i snipped most of the text here and there are several other locations where the values are mentioned Updating the App it\u0026rsquo;s important to update the app id to use your apple developer account prefix and package name this is automatically generated when you run the signing wizard to create ios developer certificates these certificates should be the same between the driver and the user app however provisioning profiles should be generated for both when you build an ios version of your app update codename1 dot main name to match the class name update codename 1 package name to match the package name other than certificates there are many nuances you would probably want to customize in this file such as the app name and the icon once this is all done you would have a separate app that does the exact same thing Driver Detection it\u0026rsquo;s really easy for us to detect the driver app and write custom code for it first let\u0026rsquo;s change the uber clone class to add driver detection this introduces a public is driver mode method into the uber clone class it would always return false unless we made one tiny change to driver app this is a block within driver app class we can now invoke his driver on the uber clone class and get the right result Push Notification i\u0026rsquo;ve discussed push notification before in the beginner course please make sure to follow the registration instructions there and update the values in the globals class once those are in place we can integrate push into the driver app we need to register for push every time the app loads the logic is that the push key might change so we need to keep it up to date we send a type 3 push which will invoke this code twice the first time around will receive a hash symbol followed by a numeric id the second time will receive a the display value when we receive the display value we can show a notification to the driver and if he clicks this notification we can show him the details of the ride ideally we would also have a rides menu item in the side menu but for now i\u0026rsquo;m compromising on the driver app to move forward when register succeeds this method is invoked the main use case is sending the push key to the server so it can trigger push messages notice that the device id is not equal to the push dot get key value device id is the historic native device key and shouldn\u0026rsquo;t be used also notice i send this every time even if the value didn\u0026rsquo;t change it\u0026rsquo;s not a big deal in terms of overhead so i ignored that small bit of overhead\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/065-28-the-driver-app-2-apps-in-one-project/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/91BrBoia4nM?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ewhen i started on this road i didn\u0026rsquo;t\nwant to create a driver app\nand wanted to focus only on the client\napp\nunfortunately a driver app is\nunavoidable as the main app is useless\nwithout it\nunlike the main uber app i don\u0026rsquo;t want to\nclone the driver app as this would throw\nthe whole course out of focus\ni decided to hack the existing app to\nimplement driver specific features there\nand as a result we use a whole lot of\ncode\nthis means the driver app can reuse sign\nup map networking code etc\nthis is important\nas code reuse breeds stability and\nmaturity\nunfortunately it also means the app\nisn\u0026rsquo;t as well made\nas the main app\nsince it was designed for end users with\ndriver mode tacked on top\nUse Cases\nwe often build one app and sell it to\nmultiple customers\nafter all\nmost customers ask for similar things\nwith minor changes\nfor example if i build a restaurant app\nand then sell it to one establishment i\ncan then resell it to another one with\nalmost no change at\nall another common use case is the demo\nor free version of a paid app\nyou want to use as much of the work as\npossible without maintaining two code\nbases\nanother case which is relevant what i\u0026rsquo;m\nbuilding today\nis two target audiences of roughly the\nsame functionality\nfor instance in this case the driver app\nhas many common elements with the\npassenger app\nso why not build the same app with minor\nmodifications\nthe first thing we need to understand is\nhow the app store identifies your\napplication\npretty much\nall apps use a unique identifier\na\nstring that is similar to package names\nwhich we map to which we map the main\napplication package name so the trick is\nto add a new package for the new app\nCreating a New Package\nthe basic hello driver\nwould be something like this\nnotice i chose to override the methods\nbut i didn\u0026rsquo;t have to\ni could have just derived the main class\nand that would have been enough\nbut i prefer overriding the lifecycle\nmethods for clarity in this case\nthis isn\u0026rsquo;t enough though\nthe codename one settings properties\nfile contains all of the internal\nconfiguration details about project\ni copied it aside and renamed it to\ncodename one settings user properties\ni then edited the file to use the driver\ndetails and copied that into codename\none settings driver properties\nnotice i snipped most of the text here\nand there are several other locations\nwhere the values\nare mentioned\nUpdating the App\nit\u0026rsquo;s important to update the app id\nto use your apple developer account\nprefix and package name\nthis is automatically generated when you\nrun the signing wizard to create ios\ndeveloper certificates\nthese certificates should be the same\nbetween the driver and the user app\nhowever provisioning profiles should be\ngenerated\nfor both when you build an ios version\nof your app\nupdate codename1 dot main name to match\nthe class name\nupdate codename 1 package name to match\nthe package name\nother than certificates there are many\nnuances you would probably want to\ncustomize in this file such as\nthe app name and the icon\nonce this is all done\nyou would have a separate app\nthat does the exact same thing\nDriver Detection\nit\u0026rsquo;s really easy for us to detect the\ndriver app and write custom code for it\nfirst let\u0026rsquo;s change the uber clone class\nto add driver detection\nthis introduces a public is driver mode\nmethod into the uber clone class\nit would always return false unless we\nmade one tiny change\nto driver app\nthis\nis a block within driver app class\nwe can now invoke his driver on the uber\nclone class and get the right result\nPush Notification\ni\u0026rsquo;ve discussed push notification before\nin the\nbeginner course\nplease make sure to follow the\nregistration instructions there and\nupdate the values in the globals class\nonce those are in place we can integrate\npush into the driver app\nwe need to register for push every time\nthe app loads\nthe logic is that the push key might\nchange so we need to keep it up to date\nwe send a type 3 push which will invoke\nthis code twice\nthe first time around will receive a\nhash symbol followed by a numeric id\nthe second time will receive a the\ndisplay value\nwhen we receive the display value we can\nshow a notification to the driver\nand if he clicks this notification\nwe can show him the details of the ride\nideally we would also have a rides menu\nitem in the side menu but for now i\u0026rsquo;m\ncompromising on the driver app to move\nforward\nwhen register succeeds this method is\ninvoked\nthe main use case is sending the push\nkey to the server\nso it can trigger\npush messages\nnotice that the device id\nis not equal to the push dot get key\nvalue\ndevice id is the historic native device\nkey\nand shouldn\u0026rsquo;t be used\nalso notice i send this every time even\nif the value didn\u0026rsquo;t change\nit\u0026rsquo;s not a big deal in terms of overhead\nso i ignored that small bit of overhead\u003c/p\u003e","title":"28. The Driver App - 2 Apps in One Project"},{"content":" Module 12: Creating an Uber Clone\nTranscript before we go into the big ui changes let\u0026rsquo;s go over some of the networking level level changes in the code in order to encapsulate the new ride json object from the server i added an equivalent properties object locally the class is practically identical to the server side ride dao class but uses the properties syntax instead of the standard pojo syntax the driver service class is a static representation of the driver specific server api this field represents the id of the current ride from this driver here we have the standard get method i mentioned earlier to retrieve the ride details and return them via a callback we use accept to indicate a driver is accepting a user\u0026rsquo;s healing if he doesn\u0026rsquo;t we don\u0026rsquo;t care once accepted he gets a reference to the id of the newly created ride object and the server notice that failure is indeed a possibility for example if the user canceled the ride or a different driver accepted first when we invoke start ride and finish ride we use current ride id unlike the user id which we used to create the ride in search service we had to add support for geocoding before this we only had the reverse geocoding which we used to locate the from slash 2 points on the map we need this api since the driver only gets the two slash from location names and we want to plot them on the map there isn\u0026rsquo;t all that much to say about this method it just searches the google geocode api for a location with the given name and returns the coordinates of that location there were many small changes in the user service class most of them relate to the way identity is managed in the app one of the big problems in having two applications with one project is that both projects share the same data in the simulator so if i want to launch the project twice once to run the user version and once for the driver version i will have a problem both will inspect the same storage information and use the same user identity they might collide notice that this is purely a simulator problem the simulator doesn\u0026rsquo;t currently isolate separate applications ideally this is something to improve in the simulator and might not be an issue in the future the solution is simple though we can just save the data to different locations or keys if we are in the driver app let\u0026rsquo;s review the changes this is illustrated perfectly in the first change in this class we use a different token to determine if the user is logged in for the case of a driver notice we replaced the invocations of preferences dot get token that were all over the code with this method call the preferences bind api lets us set a different prefix for the driver object that will be prepended to the properties in the preferences this is a cool little trick that allows me to debug with a fake number i used the is simulator method to log the verification code on the simulator and can just type it in even if the twilio code failed to send a message sends the push notificati token to the server right now we don\u0026rsquo;t need to do anything in the event callback this is invoked on registration success and allows the server to send driver push keys to the client after the first activation of the driver app we need to register for push notice i\u0026rsquo;m using the version of this method from the cn class with static import but the callback will go as expected into the driver app class\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/066-29-separating-the-driver-app-and-push-notification/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/gmqFd2bU_fM?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ebefore we go into the big ui changes\nlet\u0026rsquo;s go over some of the networking\nlevel level changes in the code\nin order to encapsulate the new ride\njson object from the server i added an\nequivalent properties object locally\nthe class is practically identical to\nthe server side ride dao class\nbut uses the properties syntax instead\nof the standard pojo syntax\nthe driver service class is a static\nrepresentation of the driver specific\nserver api\nthis field represents the id of the\ncurrent ride from this driver\nhere we have the standard get method\ni mentioned earlier to retrieve the ride\ndetails and return them via a callback\nwe use accept to indicate a driver is\naccepting a user\u0026rsquo;s healing\nif he doesn\u0026rsquo;t we don\u0026rsquo;t care\nonce accepted he gets a reference to the\nid of the newly created ride object and\nthe server\nnotice that\nfailure\nis indeed a possibility for example if\nthe user canceled the ride or a\ndifferent driver accepted first\nwhen we invoke start ride and finish\nride we use current ride id\nunlike the user id which we used to\ncreate the ride\nin search service we had to add support\nfor geocoding\nbefore this we only had the reverse\ngeocoding which we used to locate the\nfrom slash 2 points on the map\nwe need this api since the driver only\ngets the two slash from location names\nand we want to plot them on the map\nthere isn\u0026rsquo;t all that much to say about\nthis method it just searches the google\ngeocode api for a location with the\ngiven name and returns the coordinates\nof that location\nthere were many small changes\nin the user service class\nmost of them relate to the way identity\nis managed in the app\none of the big problems in having two\napplications with one project\nis that both projects share the same\ndata in the simulator\nso if i want to launch the project twice\nonce to run the user version and once\nfor the driver version i will have a\nproblem\nboth will inspect the same storage\ninformation and use the same user\nidentity\nthey might collide\nnotice that this is purely a simulator\nproblem\nthe simulator doesn\u0026rsquo;t currently isolate\nseparate applications\nideally this is something to improve in\nthe simulator\nand might not be an issue in the future\nthe solution is simple though\nwe can just save the data to different\nlocations or keys\nif we are in the driver app\nlet\u0026rsquo;s review the changes\nthis is illustrated perfectly in the\nfirst change in this class\nwe use a different token to determine if\nthe user is logged in\nfor the case of a driver\nnotice we replaced the invocations of\npreferences dot get token\nthat were all over the code with this\nmethod call\nthe preferences bind api\nlets us set a different prefix for the\ndriver object that will be prepended to\nthe properties in the preferences\nthis is a cool little trick that allows\nme to debug with a fake number\ni used the is simulator method to log\nthe verification code on the simulator\nand can just type it in\neven if the twilio code failed to send a\nmessage\nsends the push notificati token to the\nserver\nright now we don\u0026rsquo;t need to do anything\nin the event callback\nthis is invoked on registration success\nand allows the server to send driver\npush keys to the client\nafter the first activation of the driver\napp\nwe need to register for push\nnotice i\u0026rsquo;m using the version of this\nmethod from the cn class\nwith static import\nbut the callback will go as expected\ninto the driver app class\u003c/p\u003e","title":"29. Separating the Driver App and Push Notification"},{"content":" Module 12: Creating an Uber Clone\nTranscript the last two big ticket items are billing and social login i won\u0026rsquo;t implement them with adherence to the way they are were implemented with by uber i want to keep both of these features simple as they are both very volatile features and requirements within both of these apis can change literally overnight i will implement billing as a request before the write starts i\u0026rsquo;ll use braintree to do this mostly because it\u0026rsquo;s already implemented in codename one the original implementation in uber checks whether a billing method already exists this is possible to do in braintree but it would require some extra work to keep billing simple i\u0026rsquo;ll just charge one dollar per minute and do the charge in the server side in-app purchase is one of the big ticket features in mobile apps we support this rather well in codename one but we can\u0026rsquo;t use enough purchase for this case in-app purchase was devised as a tool to buy virtual goods inside an application this reduces friction as no credit card is needed google slash apple already have it and makes purchases more fluid the definition of virtual goods has some gray areas but generally the idea is that a good or service sold would be something that has no immediate physical cost good examples of virtual goods would be in-game item upgrade of software functionality app subscription etc however physical items and services are explicitly prohibited from using in-app purchase this isn\u0026rsquo;t a bad thing in-app purchase takes a hefty commission of 30 percent which isn\u0026rsquo;t viable for most physical goods sold braintree is a part of paypal and provides an easy to integrate mobile payment sdk for selling physical goods and services in theory we could just collect a credit card and call it a day but that\u0026rsquo;s naive securing online transactions is a nuanced task by using a trusted third party a great deal of the risk and liability is transferred to them one of the core concepts when working with the braintree is opacity the developer doesn\u0026rsquo;t get access to the credit card or billing information instead a nonce and token are passed between the client and the server even if a security flaw exists in the app a hacker wouldn\u0026rsquo;t gain access to any valuable information as the values expire this diagram covers the process of purchasing via braintree let\u0026rsquo;s dig into the pieces within it the client the client code our mobile app asks our server for a token the server generates a token with the braintree server code and returns it a client token is a signed data blob that includes configuration and authorization information needed by braintree to associate the transaction correctly it can\u0026rsquo;t be reused and should be hard to spoof in an attack the mobile app invokes the braintree ui with the token that ui lets the user pick a credit card or other payment option for instance paypal android pay apple pay etc then communicates with braintree\u0026rsquo;s server the result of all this is a nonce which is a unique key that allows you to charge this payment method our app now sends our nonce to our spring boot server the server uses the server side braintree api and the nonce to charge an amount amount to the payment method notice that the amount charged is completely up to the server and isn\u0026rsquo;t part of the client-side ui the braintree sdk for java is pretty easy to use we already have it in maven but just in case you skipped those lines this needs to be in the pom file next we add a braintree service class which is remarkably simple these values should be updated from braintree and sandbox should be updated to production once everything is working this is the client token that we use to identify the transaction notice we generate a new one for every request we save the nonce into the ride object this assumes payment authorization happens before the ride is completed once the rod is finished the nonce is instantly available to do to perform the charge before we proceed further the obvious next step is the web service to match it\u0026rsquo;s mostly trivial but i\u0026rsquo;d like to point out a small nuance pay isn\u0026rsquo;t mapped we invoke pay in the server so we don\u0026rsquo;t need to expose it to the client side that code requires some unexpected changes which i will get to shortly the first change was pretty predictable though we just had to add a non-field to the right class here\u0026rsquo;s the part i didn\u0026rsquo;t expect i needed to add the right id to the user object a driver has a reference to the right object which is why we didn\u0026rsquo;t need this up until now however when the user tries to pay he can\u0026rsquo;t set this anywhere else unfortunately there is no other place where the nonce would fit since it\u0026rsquo;s transient we can\u0026rsquo;t add it to the user as we\u0026rsquo;d want some logging the ride object is the right place for the nonce to get this to work i had to make a few changes to the accept ride method i added the right reference to both the driver and passenger for future reference i moved these lines downward because the rider id will only be available after the ride\u0026rsquo;s save call since payment is handled on the server side we can go directly to it even before we do the client side i\u0026rsquo;ve decided to do this in the finish ride method a ride that was finished before it was started is effectively cancelled a ride without a nonce can\u0026rsquo;t be charged at all i use the route which is ordered based on time to find the start time of the ride i then go to the last element and find the end time of the ride assuming the ride has more than one waypoint otherwise end time would be -1 we can just charge one usd per 60 seconds and payment is effectively done on the server again i oversimplified a lot and ignored basic complexities like the driver forgetting to press finish\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/067-30-driver-and-user-hailing-process/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/sBAiPOnjX6o?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ethe last two big ticket items are\nbilling and social login\ni won\u0026rsquo;t implement them with adherence to\nthe way they are were implemented with\nby uber\ni want to keep both of these features\nsimple as they are both very volatile\nfeatures and requirements within both of\nthese apis can change\nliterally overnight\ni will implement billing as a request\nbefore the write starts\ni\u0026rsquo;ll use braintree to do this mostly\nbecause it\u0026rsquo;s already implemented in\ncodename one\nthe original implementation in uber\nchecks whether a billing method already\nexists this is possible to do in\nbraintree but it would require some\nextra work to keep billing simple i\u0026rsquo;ll\njust charge one dollar per minute and do\nthe charge in the server side\nin-app purchase is one of the big ticket\nfeatures in mobile apps\nwe support this rather well in codename\none\nbut we can\u0026rsquo;t use enough purchase for\nthis case\nin-app purchase was devised as a tool to\nbuy virtual goods inside an application\nthis reduces friction as no credit card\nis needed google slash apple already\nhave it\nand makes purchases more fluid\nthe definition of virtual goods has some\ngray areas but generally the idea is\nthat a good or service sold\nwould be something that has no immediate\nphysical cost\ngood examples of virtual goods would be\nin-game item\nupgrade of software functionality app\nsubscription etc\nhowever\nphysical items and services are\nexplicitly prohibited\nfrom using in-app purchase\nthis isn\u0026rsquo;t a bad thing in-app purchase\ntakes a hefty commission of 30 percent\nwhich isn\u0026rsquo;t viable for most physical\ngoods sold\nbraintree is a part of paypal and\nprovides an easy to integrate mobile\npayment sdk for selling physical goods\nand services\nin theory we could just collect a credit\ncard and call it a day\nbut that\u0026rsquo;s naive\nsecuring online transactions is a\nnuanced task\nby using a trusted third party a great\ndeal of the risk and liability is\ntransferred to them\none of the core concepts when working\nwith the braintree is opacity\nthe developer doesn\u0026rsquo;t get access to the\ncredit card\nor\nbilling\ninformation instead a nonce and token\nare passed between the client and the\nserver\neven if a security flaw exists in the\napp a hacker wouldn\u0026rsquo;t gain access to any\nvaluable information\nas the values expire\nthis diagram\ncovers the process of purchasing\nvia braintree\nlet\u0026rsquo;s dig into the pieces within it\nthe client the client code our mobile\napp\nasks our server for a token\nthe server generates a token with the\nbraintree server code and returns it\na client token is a signed data blob\nthat includes configuration and\nauthorization information needed by\nbraintree to associate the transaction\ncorrectly\nit can\u0026rsquo;t be reused and should be hard to\nspoof in an attack\nthe mobile app invokes the braintree ui\nwith the token\nthat ui lets the user\npick a credit card or other payment\noption\nfor instance paypal android pay apple\npay etc then communicates with\nbraintree\u0026rsquo;s server\nthe result of all this is a nonce\nwhich is a unique key that allows you to\ncharge this payment method\nour app\nnow sends our nonce\nto our spring boot server\nthe server uses the server side\nbraintree api\nand the nonce to charge an amount amount\nto the payment method\nnotice that the amount charged is\ncompletely up to the server\nand isn\u0026rsquo;t part of the client-side ui\nthe braintree sdk for java is pretty\neasy to use we already have it in maven\nbut just in case you skipped those lines\nthis needs to be in the pom file\nnext we add a braintree service class\nwhich is remarkably simple\nthese values should be updated from\nbraintree and sandbox should be updated\nto production once everything is working\nthis is the client token that we use to\nidentify the transaction\nnotice we generate a new one for every\nrequest\nwe save the nonce into the ride object\nthis assumes payment authorization\nhappens before the ride is completed\nonce the rod is finished the nonce is\ninstantly available\nto do\nto perform the charge\nbefore we proceed further the obvious\nnext step\nis the web service to match\nit\u0026rsquo;s mostly trivial but i\u0026rsquo;d like to\npoint out a small\nnuance\npay isn\u0026rsquo;t mapped\nwe invoke pay in the server so we don\u0026rsquo;t\nneed to expose it to the client side\nthat code requires some unexpected\nchanges which i will get to shortly the\nfirst change was pretty predictable\nthough we just had to add a non-field to\nthe right\nclass\nhere\u0026rsquo;s the part i didn\u0026rsquo;t expect i needed\nto add the right id to the user object\na driver has a reference to the right\nobject which is why we didn\u0026rsquo;t need this\nup until now\nhowever when the user tries to pay he\ncan\u0026rsquo;t set this anywhere else\nunfortunately there is no other place\nwhere the nonce would fit\nsince it\u0026rsquo;s transient we can\u0026rsquo;t add it to\nthe user as we\u0026rsquo;d want some logging\nthe ride object is the right place for\nthe nonce\nto get this to work i had to make a few\nchanges to the accept ride method\ni added the right reference to both the\ndriver and passenger for future\nreference\ni moved these lines downward because the\nrider id will only be available after\nthe ride\u0026rsquo;s save\ncall since payment is handled on the\nserver side we can go directly to it\neven before we do the client side i\u0026rsquo;ve\ndecided to do this in the finish ride\nmethod\na ride that was finished before it was\nstarted is effectively cancelled a ride\nwithout a nonce can\u0026rsquo;t be charged\nat all\ni use the route which is\nordered based on time to find the start\ntime of the ride\ni then go to the last element and find\nthe end time of the ride\nassuming the ride has more than one\nwaypoint otherwise end time would be -1\nwe can just charge one usd per 60\nseconds and payment is effectively done\non the server again i oversimplified a\nlot and ignored basic complexities like\nthe driver forgetting to press finish\u003c/p\u003e","title":"30. Driver and User Hailing Process"},{"content":" Module 12: Creating an Uber Clone\nTranscript the last two big ticket items are billing and social login i won\u0026rsquo;t implement them with adherence to the way they are were implemented with by uber i want to keep both of these features simple as they are both very volatile features and requirements within both of these apis can change literally overnight i will implement billing as a request before the write starts i\u0026rsquo;ll use braintree to do this mostly because it\u0026rsquo;s already implemented in codename one the original implementation in uber checks whether a billing method already exists this is possible to do in braintree but it would require some extra work to keep billing simple i\u0026rsquo;ll just charge one dollar per minute and do the charge in the server side in-app purchase is one of the big ticket features in mobile apps we support this rather well in codename one but we can\u0026rsquo;t use enough purchase for this case in-app purchase was devised as a tool to buy virtual goods inside an application this reduces friction as no credit card is needed google slash apple already have it and makes purchases more fluid the definition of virtual goods has some gray areas but generally the idea is that a good or service sold would be something that has no immediate physical cost good examples of virtual goods would be in-game item upgrade of software functionality app subscription etc however physical items and services are explicitly prohibited from using in-app purchase this isn\u0026rsquo;t a bad thing in-app purchase takes a hefty commission of 30 percent which isn\u0026rsquo;t viable for most physical goods sold braintree is a part of paypal and provides an easy to integrate mobile payment sdk for selling physical goods and services in theory we could just collect a credit card and call it a day but that\u0026rsquo;s naive securing online transactions is a nuanced task by using a trusted third party a great deal of the risk and liability is transferred to them one of the core concepts when working with the braintree is opacity the developer doesn\u0026rsquo;t get access to the credit card or billing information instead a nonce and token are passed between the client and the server even if a security flaw exists in the app a hacker wouldn\u0026rsquo;t gain access to any valuable information as the values expire this diagram covers the process of purchasing via braintree let\u0026rsquo;s dig into the pieces within it the client the client code our mobile app asks our server for a token the server generates a token with the braintree server code and returns it a client token is a signed data blob that includes configuration and authorization information needed by braintree to associate the transaction correctly it can\u0026rsquo;t be reused and should be hard to spoof in an attack the mobile app invokes the braintree ui with the token that ui lets the user pick a credit card or other payment option for instance paypal android pay apple pay etc then communicates with braintree\u0026rsquo;s server the result of all this is a nonce which is a unique key that allows you to charge this payment method our app now sends our nonce to our spring boot server the server uses the server side braintree api and the nonce to charge an amount amount to the payment method notice that the amount charged is completely up to the server and isn\u0026rsquo;t part of the client-side ui the braintree sdk for java is pretty easy to use we already have it in maven but just in case you skipped those lines this needs to be in the pom file next we add a braintree service class which is remarkably simple these values should be updated from braintree and sandbox should be updated to production once everything is working this is the client token that we use to identify the transaction notice we generate a new one for every request we save the nonce into the ride object this assumes payment authorization happens before the ride is completed once the rod is finished the nonce is instantly available to do to perform the charge before we proceed further the obvious next step is the web service to match it\u0026rsquo;s mostly trivial but i\u0026rsquo;d like to point out a small nuance pay isn\u0026rsquo;t mapped we invoke pay in the server so we don\u0026rsquo;t need to expose it to the client side that code requires some unexpected changes which i will get to shortly the first change was pretty predictable though we just had to add a non-field to the right class here\u0026rsquo;s the part i didn\u0026rsquo;t expect i needed to add the right id to the user object a driver has a reference to the right object which is why we didn\u0026rsquo;t need this up until now however when the user tries to pay he can\u0026rsquo;t set this anywhere else unfortunately there is no other place where the nonce would fit since it\u0026rsquo;s transient we can\u0026rsquo;t add it to the user as we\u0026rsquo;d want some logging the ride object is the right place for the nonce to get this to work i had to make a few changes to the accept ride method i added the right reference to both the driver and passenger for future reference i moved these lines downward because the rider id will only be available after the ride\u0026rsquo;s save call since payment is handled on the server side we can go directly to it even before we do the client side i\u0026rsquo;ve decided to do this in the finish ride method a ride that was finished before it was started is effectively cancelled a ride without a nonce can\u0026rsquo;t be charged at all i use the route which is ordered based on time to find the start time of the ride i then go to the last element and find the end time of the ride assuming the ride has more than one waypoint otherwise end time would be -1 we can just charge one usd per 60 seconds and payment is effectively done on the server again i oversimplified a lot and ignored basic complexities like the driver forgetting to press finish\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/068-31-billing-with-braintree-flow-explained-and-server-side/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/sBAiPOnjX6o?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ethe last two big ticket items are\nbilling and social login\ni won\u0026rsquo;t implement them with adherence to\nthe way they are were implemented with\nby uber\ni want to keep both of these features\nsimple as they are both very volatile\nfeatures and requirements within both of\nthese apis can change\nliterally overnight\ni will implement billing as a request\nbefore the write starts\ni\u0026rsquo;ll use braintree to do this mostly\nbecause it\u0026rsquo;s already implemented in\ncodename one\nthe original implementation in uber\nchecks whether a billing method already\nexists this is possible to do in\nbraintree but it would require some\nextra work to keep billing simple i\u0026rsquo;ll\njust charge one dollar per minute and do\nthe charge in the server side\nin-app purchase is one of the big ticket\nfeatures in mobile apps\nwe support this rather well in codename\none\nbut we can\u0026rsquo;t use enough purchase for\nthis case\nin-app purchase was devised as a tool to\nbuy virtual goods inside an application\nthis reduces friction as no credit card\nis needed google slash apple already\nhave it\nand makes purchases more fluid\nthe definition of virtual goods has some\ngray areas but generally the idea is\nthat a good or service sold\nwould be something that has no immediate\nphysical cost\ngood examples of virtual goods would be\nin-game item\nupgrade of software functionality app\nsubscription etc\nhowever\nphysical items and services are\nexplicitly prohibited\nfrom using in-app purchase\nthis isn\u0026rsquo;t a bad thing in-app purchase\ntakes a hefty commission of 30 percent\nwhich isn\u0026rsquo;t viable for most physical\ngoods sold\nbraintree is a part of paypal and\nprovides an easy to integrate mobile\npayment sdk for selling physical goods\nand services\nin theory we could just collect a credit\ncard and call it a day\nbut that\u0026rsquo;s naive\nsecuring online transactions is a\nnuanced task\nby using a trusted third party a great\ndeal of the risk and liability is\ntransferred to them\none of the core concepts when working\nwith the braintree is opacity\nthe developer doesn\u0026rsquo;t get access to the\ncredit card\nor\nbilling\ninformation instead a nonce and token\nare passed between the client and the\nserver\neven if a security flaw exists in the\napp a hacker wouldn\u0026rsquo;t gain access to any\nvaluable information\nas the values expire\nthis diagram\ncovers the process of purchasing\nvia braintree\nlet\u0026rsquo;s dig into the pieces within it\nthe client the client code our mobile\napp\nasks our server for a token\nthe server generates a token with the\nbraintree server code and returns it\na client token is a signed data blob\nthat includes configuration and\nauthorization information needed by\nbraintree to associate the transaction\ncorrectly\nit can\u0026rsquo;t be reused and should be hard to\nspoof in an attack\nthe mobile app invokes the braintree ui\nwith the token\nthat ui lets the user\npick a credit card or other payment\noption\nfor instance paypal android pay apple\npay etc then communicates with\nbraintree\u0026rsquo;s server\nthe result of all this is a nonce\nwhich is a unique key that allows you to\ncharge this payment method\nour app\nnow sends our nonce\nto our spring boot server\nthe server uses the server side\nbraintree api\nand the nonce to charge an amount amount\nto the payment method\nnotice that the amount charged is\ncompletely up to the server\nand isn\u0026rsquo;t part of the client-side ui\nthe braintree sdk for java is pretty\neasy to use we already have it in maven\nbut just in case you skipped those lines\nthis needs to be in the pom file\nnext we add a braintree service class\nwhich is remarkably simple\nthese values should be updated from\nbraintree and sandbox should be updated\nto production once everything is working\nthis is the client token that we use to\nidentify the transaction\nnotice we generate a new one for every\nrequest\nwe save the nonce into the ride object\nthis assumes payment authorization\nhappens before the ride is completed\nonce the rod is finished the nonce is\ninstantly available\nto do\nto perform the charge\nbefore we proceed further the obvious\nnext step\nis the web service to match\nit\u0026rsquo;s mostly trivial but i\u0026rsquo;d like to\npoint out a small\nnuance\npay isn\u0026rsquo;t mapped\nwe invoke pay in the server so we don\u0026rsquo;t\nneed to expose it to the client side\nthat code requires some unexpected\nchanges which i will get to shortly the\nfirst change was pretty predictable\nthough we just had to add a non-field to\nthe right\nclass\nhere\u0026rsquo;s the part i didn\u0026rsquo;t expect i needed\nto add the right id to the user object\na driver has a reference to the right\nobject which is why we didn\u0026rsquo;t need this\nup until now\nhowever when the user tries to pay he\ncan\u0026rsquo;t set this anywhere else\nunfortunately there is no other place\nwhere the nonce would fit\nsince it\u0026rsquo;s transient we can\u0026rsquo;t add it to\nthe user as we\u0026rsquo;d want some logging\nthe ride object is the right place for\nthe nonce\nto get this to work i had to make a few\nchanges to the accept ride method\ni added the right reference to both the\ndriver and passenger for future\nreference\ni moved these lines downward because the\nrider id will only be available after\nthe ride\u0026rsquo;s save\ncall since payment is handled on the\nserver side we can go directly to it\neven before we do the client side i\u0026rsquo;ve\ndecided to do this in the finish ride\nmethod\na ride that was finished before it was\nstarted is effectively cancelled a ride\nwithout a nonce can\u0026rsquo;t be charged\nat all\ni use the route which is\nordered based on time to find the start\ntime of the ride\ni then go to the last element and find\nthe end time of the ride\nassuming the ride has more than one\nwaypoint otherwise end time would be -1\nwe can just charge one usd per 60\nseconds and payment is effectively done\non the server again i oversimplified a\nlot and ignored basic complexities like\nthe driver forgetting to press finish\u003c/p\u003e","title":"31. Billing with Braintree - Flow explained and Server Side"},{"content":" Module 12: Creating an Uber Clone\nTranscript next we\u0026rsquo;ll address the client side of the payment process before we begin we need to download the braintree cn1 lib from the extension manager right click the project and select refresh libs we\u0026rsquo;ll start the client side with the payment service class which encapsulates the web service aspects payment service has a private constructor so it can\u0026rsquo;t be instantiated by other classes we use the instance of this class to get callback events from the client side purchase api using the purchase callback interface notice that we need a ride id in the object instance so we can communicate purchase results to the server correctly this is literally the entire purchase api process we just invoke the native purchase ui and provide the callback instance for the native code on purchase success is the first callback from the callback interface it occurs when a purchase succeeded and produced a nonce we can then send the nonce to the server with the ride id on purchase fail or console aren\u0026rsquo;t very interesting in this use case i chose to ignore them but you might need them to know whether that the charge ui should be shown again notice the only way to verify purchase success is on the server fetchtoken is a callback method in the callback interface it\u0026rsquo;s invoked internally by the on purchase process to fetch the server token value that initializes the purchase process this is pretty much everything the only remaining piece is binding this into the ui i\u0026rsquo;ve changed the ok button to pay with cash and added an option to pay with credit which essentially maps to the braintree api this implements the four payment process integration including credit card verification and everything involved once this is done payments should now work both in the client and the server the user is presented with an option to pay or use cash which just dismisses the dialogue\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/069-32-braintree-client-side-integration/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/RBYGdCllnww?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003enext we\u0026rsquo;ll address the client side of\nthe payment process\nbefore we begin we need to download the\nbraintree cn1 lib from the extension\nmanager right click the project and\nselect refresh libs\nwe\u0026rsquo;ll start the client side with the\npayment service class which encapsulates\nthe web service aspects\npayment service has a private\nconstructor so it can\u0026rsquo;t be instantiated\nby other classes\nwe use the instance of\nthis class to get callback events from\nthe client side purchase api\nusing the purchase callback interface\nnotice that we need\na ride id in the object instance so we\ncan communicate purchase results to the\nserver correctly\nthis is literally the entire purchase\napi process\nwe just invoke the native purchase ui\nand provide the callback instance for\nthe native code\non purchase success is the first\ncallback from the callback interface\nit occurs when a purchase succeeded\nand produced a nonce\nwe can then send the nonce to the server\nwith the ride id\non purchase fail or console\naren\u0026rsquo;t very interesting in this use case\ni chose to ignore them but you might\nneed them to know whether that\nthe charge ui should be shown again\nnotice the only way to verify purchase\nsuccess is on the server\nfetchtoken is a callback method\nin the callback interface\nit\u0026rsquo;s invoked internally by the on\npurchase process to fetch the server\ntoken value\nthat initializes the purchase process\nthis is pretty much everything\nthe only remaining piece is binding this\ninto the ui i\u0026rsquo;ve changed the ok button\nto pay with cash\nand added an option to pay with credit\nwhich essentially maps to the braintree\napi\nthis implements the four payment process\nintegration\nincluding credit card verification and\neverything involved\nonce this is done payments should now\nwork both in the client and the server\nthe user is presented with an option to\npay or use cash\nwhich\njust dismisses the dialogue\u003c/p\u003e","title":"32. Braintree - Client Side Integration"},{"content":" Module 12: Creating an Uber Clone\nTranscript we already prepared a lot of the groundwork for social login on the server but didn\u0026rsquo;t finish all the pieces so before i step into the client side changes needed for social login let\u0026rsquo;s discuss some of the required server side work i had to include support for the exists functionality that works based on a social token i also had to include a similar call in the user web service class i also have a similar subtitle change to the regular exists method the argument name was phone and is now v which means i can invoke all three web services with very similar code on the client side that\u0026rsquo;s it pretty much everything else was already done social login lets us authenticate a user without getting into the username password complexity this is usually almost seamless on devices where we the pre-installed social app is invoked explicitly and the user just needs to approve the permission this is defined as a low friction approach to authenticate the user and is often superior to phone number activation in codename one this is pretty trivial to accomplish especially for google and facebook login both of which are built into codename one and to android slash ios respectively connection to social networks and codename one has several common concepts if the device has native support or social app installed this native integration will perform a login if it doesn\u0026rsquo;t but we are on the device the native sdk will show a web based login if we are on the simulator we will fall back to an oauth based login this leads to a situation where login might work on one device but fail on a simulator or fail on a different device type it also makes the configuration process a bit more tedious to be fair the native configuration is much harder and involves more code since the driver app is physically a separate app we\u0026rsquo;ll need to redo some of the steps and effectively go through everything twice a core concept of the login process in facebook is the app which is a facebook internal term unrelated to your actual app facebook\u0026rsquo;s view of an app is anything that uses the facebook graph api and authentication in this case we need to create a new app and should name it like we do our actual app so the user will be able to identify it the steps are pretty easy we navigate to developer.facebook.com apps and press the add a new app button next we need to select the product we are trying to use and we need to select facebook login once there we are presented with a wizard containing multiple steps to set up your app you need to run through the wizard twice once for ios and once for android the content of the wizard changes but the gist is the same we don\u0026rsquo;t really need much information and can skip almost everything the first step is download and install the facebook sdk for ios this is obviously unnecessary for us so we can just press next the second step is add login kit to your xcode project again there is no need to do anything and we can press next the third step is add your bundle identifier it\u0026rsquo;s more interesting we need to enter the project package name here and press save then we are effectively done with ios as everything else is more of the same the android wizard has one task that is a bit challenging but other than that it should be trivial before we begin we need to generate key hashes for facebook which need to be done on your development machine to do that you will need a command line with the jdks bin directory in your path you will also need the path to the android key store you use for signing you can find this file in the android signing section in codename one settings if there is no certificate file there make sure to generate it once all this is in place you can use this command line for linux mac this will provide the sha1 key you will need in the android wizard similarly on windows the command follows a similar structure but uses windows command line conventions now that this is out of the way let\u0026rsquo;s go over the android wizard steps the first step is download the facebook sdk for android this is obviously unnecessary for us so we can just press next the next step is import the facebook sdk again there is no need to do anything and we can press next the next step is tell us about your android project we need to specify the package name for the application which in our case is com codename1.app.uberclone we also need to specify the main class which is ubercn1 stub the main class is effectively the main class name with the word stub with an uppercase s appended at the end we can then press next after i press next i got this warning because the app isn\u0026rsquo;t in the store yet facebook thinks i might have typed the package incorrectly and provides this warning which we can ignore and finally we are at the add your development and release key hashes here we need to add the hash we got before and press next the rest of the wizard isn\u0026rsquo;t important before we proceed we need to enter the facebook dashboard and copy two values the app id and app secret which we will need when we set up the code\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/070-33-social-login-basics-and-facebook-app/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/qKc1hZyw360?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ewe already prepared a lot of the\ngroundwork for social login on the\nserver\nbut didn\u0026rsquo;t finish all the pieces so\nbefore i step into the client side\nchanges needed for social login let\u0026rsquo;s\ndiscuss some of the required server side\nwork\ni had to include support for the exists\nfunctionality that works based on a\nsocial token\ni also had to include a similar call in\nthe user web service class\ni also have a similar subtitle change\nto the regular exists method\nthe argument name was phone and is now v\nwhich means i can invoke all three web\nservices with very similar code on the\nclient side\nthat\u0026rsquo;s it pretty much everything else\nwas already done\nsocial login lets us authenticate a user\nwithout getting into the\nusername password complexity\nthis is usually almost seamless on\ndevices where we\nthe pre-installed social app is invoked\nexplicitly and the user just needs to\napprove the permission\nthis is defined as a low friction\napproach to authenticate the user\nand is often superior to phone number\nactivation\nin codename one this is pretty trivial\nto accomplish especially for\ngoogle and facebook login both of which\nare built into codename one and to\nandroid slash ios respectively\nconnection to social networks and\ncodename one has several common concepts\nif the device has native support or\nsocial app installed this native\nintegration will perform a login\nif it doesn\u0026rsquo;t but we are on the device\nthe native sdk will show a web based\nlogin\nif we are on the simulator we will fall\nback to an oauth based login this leads\nto a situation where login might work on\none device but fail on a simulator or\nfail on a different device type\nit also makes the configuration process\na bit more tedious\nto be fair the native configuration is\nmuch harder and involves more code\nsince the driver app is physically a\nseparate app\nwe\u0026rsquo;ll need to redo some of the steps and\neffectively go through everything\ntwice\na core concept of the login process\nin facebook is the app\nwhich is a facebook internal term\nunrelated to your actual app\nfacebook\u0026rsquo;s view of an app\nis anything that uses the facebook graph\napi and authentication\nin this case we need to create a new app\nand should name it like we do our actual\napp so the user will be able to identify\nit\nthe steps are pretty easy we navigate to\ndeveloper.facebook.com\napps\nand press the add a new app button\nnext we need to select the product we\nare trying to use and we need to select\nfacebook login\nonce there we are presented with a\nwizard containing multiple steps\nto set up your app\nyou need to run through the wizard twice\nonce for ios and once for android\nthe content of the wizard\nchanges but the gist is the same\nwe don\u0026rsquo;t really need much information\nand can skip almost everything\nthe first step is download and install\nthe facebook sdk for ios\nthis is obviously unnecessary for us so\nwe can just press\nnext\nthe second step is add login kit to your\nxcode project again there is no need to\ndo anything and we can press next\nthe third step is add your bundle\nidentifier\nit\u0026rsquo;s more interesting we need to enter\nthe project package name here and\npress save\nthen we are effectively done with ios as\neverything else is more of the same\nthe android wizard has one task that is\na bit challenging but other than that it\nshould be trivial\nbefore we begin we need to generate key\nhashes for facebook which need to be\ndone on your development machine\nto do that you will need a command line\nwith the jdks bin directory in your path\nyou will also need the path to the\nandroid key store you use for signing\nyou can find this file in the android\nsigning section in codename one settings\nif there is no certificate file there\nmake sure to generate it\nonce all this\nis in place you can use this command\nline for linux mac\nthis will provide the sha1 key you will\nneed in the android wizard\nsimilarly on windows the command\nfollows a similar structure but uses\nwindows command line conventions\nnow that this is out of the way\nlet\u0026rsquo;s go over the android wizard steps\nthe first step is download the facebook\nsdk for android this is obviously\nunnecessary for us so we can just press\nnext\nthe next step is import the facebook sdk\nagain there is no need to do anything\nand we can press next\nthe next step is tell us about your\nandroid project we need to specify the\npackage name for the application\nwhich in our case is com\ncodename1.app.uberclone\nwe also need to specify the main class\nwhich is ubercn1 stub\nthe main class is effectively the main\nclass name with the word stub with an\nuppercase s appended at the end we can\nthen press next\nafter i press next i got this warning\nbecause the app isn\u0026rsquo;t in the store yet\nfacebook thinks i might have typed the\npackage incorrectly and provides this\nwarning which we can ignore\nand finally\nwe are at the add your development and\nrelease key hashes here we need to add\nthe hash we got before and press next\nthe rest of the wizard isn\u0026rsquo;t important\nbefore we proceed we need to enter the\nfacebook dashboard and copy two values\nthe app id\nand app secret which we will need when\nwe set up the code\u003c/p\u003e","title":"33. Social Login - Basics and Facebook App"},{"content":" Module 12: Creating an Uber Clone\nTranscript next we\u0026rsquo;ll integrate the facebook login process into the code to get the native login working we only need one step add the build hint facebook.app id equals the app id app id is the id from the dashboard on the facebook app page this will make facebook work on the devices almost seamlessly notice that since we have effectively two apps we\u0026rsquo;ll need to add an app id to the user app and the driver app to get login working on the simulator we\u0026rsquo;ll need a bit more we\u0026rsquo;ll also need to write code that supports the login process within the facebook or google login form class facebook connect is a subclass of the login class that lets us login into facebook and request publish permissions if necessary the client id and secret aren\u0026rsquo;t used on devices these are hair strictly for the benefit of the simulator if you don\u0026rsquo;t need to debug on the simulator the lines until set callback are redundant notice that we have two versions of these values for the uber app and the driver app the callback is invoked upon login success failure if the login is successful we get the token from facebook which is an authorization token this token allows us to access information within the facebook graph api to query facts about the user notice that we have a new constructor for enter password form which i will discuss soon this triggers the actual login but the method is asynchronous and login will only actually succeed or fail when the callback is reached before we go to the google login support let\u0026rsquo;s look at the additional changes we need to get both facebook and google working i already discussed the changes to enter password form so let\u0026rsquo;s start there the constructor accepts one of the three options the other two should be null in this case i also updated the user service method accordingly i\u0026rsquo;ll get into that shortly notice i snapped some code below here to keep the entire block in one page but it\u0026rsquo;s still there the login method now accepts the google facebook credentials as an optional argument two of the three values for identification will be null so we can set all of them and only one will have a value next let\u0026rsquo;s see the changes to the user service class this is the main method we use which we broke up for the other types the generic implementation demonstrates why i chose to change the argument names from phone to v so it can now suit all permutations of this method login is almost identical to the original code i added the new values to the mix if they are null the arguments won\u0026rsquo;t be sent and everything will work as expected once this is done facebook login should work on the device and simulator\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/071-34-facebook-and-google-login-code/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/UwdI_tMqYgU?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003enext we\u0026rsquo;ll integrate the facebook login\nprocess into the code\nto get the native login working we only\nneed one step\nadd the build hint\nfacebook.app id\nequals\nthe app id\napp id is the id from the dashboard on\nthe facebook app page this will make\nfacebook work on the devices almost\nseamlessly\nnotice that since we have effectively\ntwo apps we\u0026rsquo;ll need to add an app id to\nthe user app and the driver app\nto get login working on the simulator\nwe\u0026rsquo;ll need a bit more we\u0026rsquo;ll also need to\nwrite code that supports the login\nprocess within the facebook or google\nlogin form class\nfacebook connect is a subclass of the\nlogin class that lets us login into\nfacebook and request publish permissions\nif necessary\nthe client id and secret aren\u0026rsquo;t used on\ndevices\nthese are hair strictly for the benefit\nof the simulator\nif you don\u0026rsquo;t need to debug on the\nsimulator the lines until set callback\nare redundant\nnotice that we have two versions of\nthese values for the uber app and the\ndriver app\nthe callback is invoked upon login\nsuccess failure\nif the login is successful we get the\ntoken from facebook which is an\nauthorization token this token allows us\nto access information within the\nfacebook graph api to query facts about\nthe user\nnotice that we have a new constructor\nfor enter password form which i will\ndiscuss soon\nthis triggers the actual login\nbut the method is asynchronous and login\nwill only actually succeed or fail\nwhen the callback is reached\nbefore we go to the google login support\nlet\u0026rsquo;s look at the additional changes we\nneed to get\nboth facebook and google working\ni already discussed the changes to enter\npassword form\nso let\u0026rsquo;s start there\nthe constructor accepts\none of the three options the other two\nshould be null in this case\ni also updated the user service method\naccordingly i\u0026rsquo;ll get into that shortly\nnotice i snapped some code below here\nto keep the entire block in one page\nbut it\u0026rsquo;s still there\nthe login method now accepts the google\nfacebook credentials as an optional\nargument\ntwo of the three values for\nidentification will be null so we can\nset all of them\nand only one will have a value\nnext let\u0026rsquo;s see the changes to the user\nservice class\nthis is the main method we use\nwhich we broke up for the other types\nthe generic implementation demonstrates\nwhy i chose to change\nthe argument names from phone to v\nso it can now suit all permutations of\nthis method\nlogin is almost identical to the\noriginal code\ni added the new values to the mix if\nthey are null the arguments won\u0026rsquo;t be\nsent\nand everything will work as expected\nonce this is done facebook login should\nwork on the device and simulator\u003c/p\u003e","title":"34. Facebook and Google Login Code"},{"content":" Module 12: Creating an Uber Clone\nTranscript the last piece is the google login support which we almost finished as the code we did for facebook is nearly identical google again went through some back and forth originally it was mapped to google plus functionality as google phased out google plus we switched to use the new google login authentication the process for google is pretty similar to the one we had with facebook first we need to go to the google developer portal at developers.google.com mobile slash ad and follow the steps to create an app for google sign-in notice we need to run through the process four times once for android and once for ios and again for the driver app the ios version requires the app name and bundle id which map to the app name and package name in codename one next select the google sign-in option and click the generate button once we enable google sign-in we can generate the configuration files then we can download and the configuration file which should be named googleserviceinfo.plist place this file in your project root under the native ios directory the process for android is nearly identical with one big difference we need to provide an sha1 key for this to work since i discussed the process of generating an sha1 key for your certificate earlier i won\u0026rsquo;t repeat it again check out the facebook section for the details on that process once we finish this step we will receive a file named googleservices.json we should place this file under the native slash android directory in order to work in the simulator we\u0026rsquo;ll need some additional credentials from console.cloud.google.com apis in the top portion of the browser make sure the correct app name is selected select the credentials menu find the web client entry and click it you should see the client id and client secret values there we will need them in the code soon in the authorize redirect uri section you will need to enter the url of the page that the user will be sent to after a successful login this page will only appear in the simulator for a split second as codename one\u0026rsquo;s browser component will intercept this request to obtain the access token upon successful login you can use any url you like here but it must match the value you give to google connect dot set redirect url in the code once all of this is in place we can add the code to handle google login process you\u0026rsquo;ll notice that the code is almost identical to the facebook login code in fact both google connect and facebook connect derive the login class which means we can write very generic login code at least in theory\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/072-35-google-login-process/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/JWLsSbbo4N4?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ethe last piece is the google login\nsupport which we almost finished as the\ncode we did for facebook is nearly\nidentical\ngoogle again went through some back and\nforth originally it was mapped to google\nplus functionality\nas google phased out google plus we\nswitched to use the new google login\nauthentication\nthe process for google is pretty similar\nto the one we had with facebook\nfirst we need to go to the google\ndeveloper portal at\ndevelopers.google.com\nmobile slash ad\nand follow the steps to create an app\nfor google sign-in\nnotice we need to run through the\nprocess four times once for android and\nonce for ios and again for the driver\napp\nthe ios version requires the app name\nand bundle id which map to the app name\nand\npackage name in codename one\nnext select the google sign-in option\nand click the generate button\nonce we enable google sign-in\nwe can generate the configuration files\nthen we can download and the\nconfiguration file which should be named\ngoogleserviceinfo.plist\nplace this file in your project root\nunder the native ios directory\nthe process for android is nearly\nidentical with one big difference we\nneed to provide an sha1 key for this to\nwork\nsince i discussed the process of\ngenerating an sha1 key for your\ncertificate earlier i won\u0026rsquo;t repeat it\nagain\ncheck out the facebook section for the\ndetails on that process\nonce we finish this step\nwe will receive a file named\ngoogleservices.json\nwe should place this file under the\nnative slash android directory\nin order to work in the simulator we\u0026rsquo;ll\nneed some additional credentials from\nconsole.cloud.google.com\napis\nin the top portion of the browser make\nsure the correct app name is selected\nselect the credentials menu\nfind the web client entry and click it\nyou should see the client id and client\nsecret values there\nwe will need them in the code soon\nin the authorize redirect uri section\nyou will need to enter the url of the\npage that the user will be sent to after\na successful login\nthis page will only appear in the\nsimulator for a split second as codename\none\u0026rsquo;s browser component will intercept\nthis request to obtain the access token\nupon successful login\nyou can use any url you like here\nbut it must match the value you give to\ngoogle connect dot set redirect url\nin the code\nonce all of this is in place we can add\nthe code to handle google login process\nyou\u0026rsquo;ll notice that the code is almost\nidentical to the facebook login code in\nfact both google connect and facebook\nconnect\nderive the login class which means we\ncan write very generic login code at\nleast in theory\u003c/p\u003e","title":"35. Google Login Process"},{"content":" Module 12: Creating an Uber Clone\nTranscript i kept most of the default transitions and did a few animations along the way but i didn\u0026rsquo;t spend too much time on either one of those by default codename one uses the slide or slide fade transitions these should look decent for the most part but i wanted to demonstrate and discuss some of the nuanced transitions in the uber app [Music] in the native uber app transitions look a bit different between ios and android i didn\u0026rsquo;t go there because i don\u0026rsquo;t think this was done on purpose in android\u0026rsquo;s material design a common transition pattern is one where we move an element from one view to the next and indeed this is what we have between the login form and the enter mobile number form as you can see the enter your mobile number and flag elements animate to the place in the next form while other elements fade in out respectively this transition repeats itself in reverse when we press back there are a couple of things that might not be immediately obvious when you look at this the background pattern instantly disappears instead of fading this might be on purpose but it doesn\u0026rsquo;t look good this is a bit hard to see as it happens relatively quickly but the back arrow slides in from the left codename one has a morph transition which doesn\u0026rsquo;t include the slide in out option for some elements only the fade in out of these elements so we\u0026rsquo;ll pass on that aspect i chose to fade the background pattern in out as it looks much better i\u0026rsquo;m not sure why uber chose not to do that notice that this works for us despite the fact that the background is constantly rotating when we get back to the main form and this isn\u0026rsquo;t supported in the native android app transitions are decoupled from the forms or components that they transition this allows us to define a transition regardless of the contents of a form in order to use the morph transition we need to communicate to it the components we would like to animate but they might not be instantiated at this time yet so we need to use component names if the components on both forms have the same name we can make the code even shorter we can perform the transition using this code in login form we will obviously need the corresponding code in enter mobile number form notice we set the names to the identical values we could have used different names and then just specified those different names in the morph method we would also want morph to run in reverse when going back so the obvious thing to do is define a morph transition in the back command but there are a couple of nuances notice i used strings instead of get name as the back command is defined before the components in the full code listing this is one of those things that you only see on the device the virtual keyboard opens when we enter the mobile number form so when we go back it looks a bit weird on android i stop editing to fold it first and then use the callback to detect when the keyboard actually finished closing otherwise the transition will run before the form had time to adjust the problem is that if you run this code it will fail badly the background animation tries to repaint while the transition is in progress the solution for that is a small simple change to login form painter i\u0026rsquo;m effectively blocking animation of the background during transition which would also make the transition smoother as a result\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/073-36-morph-transition-animating-elements-between-forms/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/9T8MBBuWBDs?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ei kept most of the default transitions\nand did a few animations along the way\nbut i didn\u0026rsquo;t spend too much time on\neither one of those\nby default codename one uses the slide\nor slide fade transitions\nthese should look decent for the most\npart but i wanted to demonstrate and\ndiscuss\nsome of the nuanced transitions in the\nuber app\n[Music]\nin the native uber app transitions look\na bit different between ios and android\ni didn\u0026rsquo;t go there because i don\u0026rsquo;t think\nthis was done on purpose\nin android\u0026rsquo;s material design a common\ntransition pattern\nis one where we move an element from one\nview to the next and indeed\nthis is what we have between the login\nform and the enter mobile number form\nas you can see the enter your mobile\nnumber and flag elements animate to the\nplace in the next form while other\nelements fade in out respectively\nthis transition repeats itself in\nreverse\nwhen we press back\nthere are a couple of things that might\nnot be immediately obvious when you look\nat this\nthe background pattern\ninstantly disappears\ninstead of fading\nthis might be on purpose but it doesn\u0026rsquo;t\nlook good\nthis is a bit hard to see as it happens\nrelatively quickly but the back arrow\nslides in from the left\ncodename one has a morph transition\nwhich doesn\u0026rsquo;t include the slide in out\noption\nfor some elements\nonly the fade in out of these elements\nso we\u0026rsquo;ll pass on that aspect i chose to\nfade the background pattern in out as it\nlooks much better\ni\u0026rsquo;m not sure why uber chose not to do\nthat\nnotice that this works for us despite\nthe fact that the background is\nconstantly rotating\nwhen we get back to the main form\nand this isn\u0026rsquo;t supported in the native\nandroid app\ntransitions are decoupled from the forms\nor components that they transition\nthis allows us to define a transition\nregardless of the contents of a form in\norder to use the morph transition\nwe need to communicate to it the\ncomponents we would like to animate\nbut they might not be instantiated at\nthis time yet\nso we need to use component names\nif the components on both forms have the\nsame name\nwe can make the code even shorter\nwe can perform the transition using this\ncode in login form\nwe will obviously need the corresponding\ncode in enter mobile number form\nnotice we set the names to the identical\nvalues\nwe could have used different names and\nthen just specified those different\nnames in the morph method\nwe would also want morph to run in\nreverse when going back\nso the obvious thing to do\nis define a morph transition in the back\ncommand\nbut there are a couple of nuances\nnotice i used strings instead of get\nname as the back command is defined\nbefore the components in the full code\nlisting\nthis is one of those things that you\nonly see on the device the virtual\nkeyboard opens when we enter the mobile\nnumber form\nso when we go back it looks a bit weird\non android\ni stop editing to fold it first\nand then use the callback to detect when\nthe keyboard actually finished closing\notherwise the transition will run before\nthe form had time to adjust\nthe problem is that if you run this code\nit will fail badly\nthe background animation tries to\nrepaint while the transition is in\nprogress\nthe solution for that is a small simple\nchange to login form painter\ni\u0026rsquo;m effectively blocking animation of\nthe background during transition which\nwould also make the transition smoother\nas a result\u003c/p\u003e","title":"36. Morph Transition - Animating Elements Between Forms"},{"content":" Module 12: Creating an Uber Clone\nTranscript the code for morph transitions broke another thing it broke the facebook or google login form which looks awful going in now because morph is generally designed for a specific form i want to use the vertical cover effect which is common on ios and looks pretty decent on android 2. cover slides the form on top of the existing form from the bottom it\u0026rsquo;s usually combined with uncover which slides the form out in the reverse way because of this unique semantic the cover transition uses both the in and out transition flags however this can pose a problem with the default out transition of the form that we are leaving in this case you would see the out animation of the login form which in this case is morph followed by the incoming cover animation the solution is to remove the out animation from the outgoing form and restore it to the original value when we get back we do that within the remove transition temporarily method which we call here from the facebook or google login form we need to remove both the in and out transitions as we might show a cover transition on top of another cover transition form when we return to the original form we restore its transitions to their original values we remove the show listener to prevent a memory leak and multiple restore calls when going back and forth\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/074-37-cover-transition-conditionally-showing-a-form-transition/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/IaalGP1UDeU?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ethe code for morph transitions\nbroke another thing\nit broke the facebook or google login\nform\nwhich looks awful going in now because\nmorph is generally designed for a\nspecific form\ni want to use the vertical cover effect\nwhich is common on ios and looks pretty\ndecent on android 2.\ncover slides the form on top of the\nexisting form from the bottom\nit\u0026rsquo;s usually combined with uncover\nwhich slides the form out in the reverse\nway\nbecause of this unique semantic the\ncover transition uses both the in and\nout transition flags\nhowever this can pose a problem\nwith the default out transition of the\nform that we are leaving\nin this case you would see the out\nanimation of the login form\nwhich in this case is morph\nfollowed by the incoming cover animation\nthe solution is to remove the out\nanimation from the outgoing form\nand restore it to the original value\nwhen we get back\nwe do that within the remove transition\ntemporarily method\nwhich we call here from the facebook or\ngoogle login form\nwe need to remove both the in and out\ntransitions\nas we might show a cover transition\non top of another cover transition form\nwhen we return to the original form we\nrestore its transitions to their\noriginal values\nwe remove the show listener to prevent a\nmemory leak\nand multiple restore calls when going\nback and forth\u003c/p\u003e","title":"37. Cover Transition - Conditionally Showing a Form Transition"},{"content":" Module 12: Creating an Uber Clone\nSome animations are worth keeping product-specific. This lesson is a good example. The circular highlight around the floating action button is not a general-purpose UI pattern you would add to every app. It is a small piece of branding and feedback that fits the ride-hailing experience the course is cloning.\nThe useful idea here is not really the Uber imitation itself. It is the decision to build a focused animation for one concrete interaction instead of trying to solve “all progress indication” with one giant generic component.\nThe implementation works by styling the floating action button directly and animating the stroke of its round border. That keeps the effect local. The button keeps its identity, but it gains a sense of motion and ongoing work while the app is waiting for the next step.\nThe lesson also uses a UI timer rather than a plain background timer. That is the right choice for a visual effect that updates component styles because the callbacks need to run on the EDT. A progress effect that quietly hops across threads is exactly the kind of thing that becomes glitchy for no good reason.\nAnother good detail is the cleanup step. The animation stores its instance in a client property and restores the original UIID when it stops. That matters because a temporary visual effect should leave the component exactly as it found it. If an animation modifies style state but never restores it properly, the UI gradually becomes harder to reason about.\nThis lesson sits in a good middle ground between high-level animation APIs and fully custom rendering. It is custom enough to feel specific to the product, but still simple enough that the code stays understandable.\nFurther Reading Transitions Layout Animations Animation Manager, Style Animations and Low Level Animations Enter Password Form ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/075-38-circular-floating-action-button-animation/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/YE7OQFQE0yA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eSome animations are worth keeping product-specific. This lesson is a good example. The circular highlight around the floating action button is not a general-purpose UI pattern you would add to every app. It is a small piece of branding and feedback that fits the ride-hailing experience the course is cloning.\u003c/p\u003e","title":"38. Circular Floating Action Button Animation"},{"content":" Module 12: Creating an Uber Clone\nUp to this point the Uber clone mostly proves that the core ride flow works. This lesson starts turning the surrounding app chrome into something more believable by making the side menu lead to real account-oriented screens.\nThat shift matters because a convincing application is not just its flagship interaction. Once a user can open settings or tap their avatar, the app starts feeling like a complete product instead of a narrow demo.\nThe settings form itself is mostly straightforward UI work, but the more interesting part of the lesson is avatar loading. Fetching a user image sounds simple until you care about round masking, correct sizing, local caching, and the fact that the client is the only place that really knows how large the final image needs to be.\nThat last point is still the right way to think about it. The server should not hard-code every display size the client might need. The client decides how the image will appear, and the client can then cache the processed result so future loads are fast.\nThe lesson updates the avatar API so the image can be delivered asynchronously through a callback. That is a natural fit for remote image loading because the UI can continue rendering while the image is fetched from storage or downloaded from the server. If the image is already cached locally, the callback can complete quickly without making the app feel network-bound.\nThis is one of those small service-layer improvements that pays off all over the UI. Once avatar loading is centralized and cache-aware, the app can reuse it for settings, side-menu identity, profile editing, and eventually any place where another user’s image should appear.\nFurther Reading 40. Edit User - UI Binding and Multipart Image Upload Client Side UserService Storage, Filesystem and SQL How Do I Fetch an Image from the Resource File / Add a MultiImage ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/076-39-settings-form-and-fetching-the-avatar-image/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/tBBtpdz-JJg?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eUp to this point the Uber clone mostly proves that the core ride flow works. This lesson starts turning the surrounding app chrome into something more believable by making the side menu lead to real account-oriented screens.\u003c/p\u003e\n\u003cp\u003eThat shift matters because a convincing application is not just its flagship interaction. Once a user can open settings or tap their avatar, the app starts feeling like a complete product instead of a narrow demo.\u003c/p\u003e","title":"39. Settings Form and Fetching the Avatar Image"},{"content":" Module 12: Creating an Uber Clone\nEditing account details is one of those places where a lot of apps make the user work harder than necessary. The lesson starts by calling out Uber’s more segmented editing flow and then chooses a flatter, more direct alternative: bind text fields straight to the user object and save only when the user leaves the form.\nThat is a good tradeoff for this app. The screen stays simple, the code stays short, and the user can edit several values naturally instead of drilling through one tiny form at a time.\nThe binding API does most of the heavy lifting here. Once the user object is bound to the text fields, the form can populate itself from the model and keep the model updated as the user types. That is exactly the kind of repetitive plumbing worth automating.\nThe lesson is also careful about when data is actually sent to the server. Binding the UI to the model does not mean every keystroke should become a network request. Saving on exit keeps the experience responsive and avoids unnecessary traffic. The comparison against the original object state is a simple but effective way to decide whether anything changed.\nThe avatar upload flow extends the same idea. The app lets the user capture a new image, resizes it on the client so the upload stays within sensible limits, updates the local UI immediately, and then sends the file to the server using a multipart request. That sequencing feels good because the user sees the result right away even while the server-side update is still in flight.\nThe warning about unbinding is also important. Once bindings are attached to a global model object, forgetting to release them can keep entire form hierarchies alive longer than intended. This is exactly the kind of subtle memory problem that is easy to create and hard to notice unless you think about object lifetimes deliberately.\nFurther Reading 39. Settings Form and Fetching the Avatar Image Properties Are Amazing Storage, Filesystem and SQL How Do I Take a Picture with the Camera ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/077-40-edit-user-ui-binding-and-multipart-image-upload/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 12: Creating an Uber Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/S1SHZLXQxSI?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eEditing account details is one of those places where a lot of apps make the user work harder than necessary. The lesson starts by calling out Uber’s more segmented editing flow and then chooses a flatter, more direct alternative: bind text fields straight to the user object and save only when the user leaves the form.\u003c/p\u003e","title":"40. Edit User - UI Binding and Multipart Image Upload"},{"content":" Module 13: Creating a Facebook Clone\nBefore writing code, this module does something the course does well when it is at its best: it studies the product being cloned instead of charging straight into implementation.\nThat matters because the point is not to reproduce Facebook pixel for pixel. The point is to understand which product decisions are worth copying, which ones are inconsistent or awkward, and which ones can teach useful lessons about building a large data-heavy mobile app.\nThe login and signup flow is a good place to start because it immediately exposes several design tensions. Deep wizard-style flows are easier to understand and adapt well to different screen sizes, but they are also more tedious when users only need to edit one thing. Flatter forms are more efficient, but they can become harder to scan and harder to adapt cleanly across phones and tablets.\nThat tradeoff is more valuable than the specific Facebook screens shown in the video. The lesson is really about learning how to think through UI depth, progressive disclosure, platform conventions, and the relationship between data complexity and screen structure.\nThe module also makes a smart scope decision. Facebook is enormous. A useful clone needs to choose which capabilities are interesting enough to implement and which ones would mostly add volume without teaching much. That kind of discipline matters in real projects too. A clone is only educational if it stays focused.\nThe architectural hint near the end is also important: a social app carries a huge amount of structured data, and Codename One properties are a natural fit for that. Once the app starts dealing with posts, users, friends, comments, privacy flags, and media, the benefit of declarative structured data becomes very obvious.\nFurther Reading 2. Creating the Project and CSS Overview and Basic Model Properties Are Amazing Adapting a UI Design ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/078-1-introduction/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/S5pAGkV4h4w?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eBefore writing code, this module does something the course does well when it is at its best: it studies the product being cloned instead of charging straight into implementation.\u003c/p\u003e\n\u003cp\u003eThat matters because the point is not to reproduce Facebook pixel for pixel. The point is to understand which product decisions are worth copying, which ones are inconsistent or awkward, and which ones can teach useful lessons about building a large data-heavy mobile app.\u003c/p\u003e","title":"1. Introduction"},{"content":" Module 13: Creating a Facebook Clone\nWith the product direction defined, the next step is to create a project that can actually support it. This lesson is less about raw project generation and more about choosing the right styling and structural foundation for an app that will grow quickly.\nThe video contrasts Facebook and Uber in a useful way. One app leans into a more native platform look, the other uses a more unified cross-platform visual style. The goal of this clone is not blind accuracy. It is to take inspiration from Facebook’s flow while still making architectural choices that age well.\nThat is why CSS is such an important decision here. The video talks about CSS as something new and in transition, which was true at the time. Today that part is out of date. CSS is the recommended styling path for new Codename One work, and this is exactly the kind of project where it pays off. A large app with many screens, repeated patterns, and evolving visual rules is much easier to maintain when styling lives in CSS instead of in older designer-driven workflows.\nThe icon-font setup is also a practical choice. A social app needs many small symbolic elements, and icon fonts remain a simple way to keep those assets scalable, lightweight, and easy to recolor. The lesson’s Fontello-based workflow is one way to build that bundle of icons, but the broader idea is the important one: gather the symbols the app will need early and make them part of the styling system instead of scattering image files everywhere.\nThe CSS details in the lesson are the beginning of a theme system, not just a few cosmetic tweaks. Constants, default gaps, transparent backgrounds, icon fonts, and base styling decisions all become easier to manage once they are centralized. That gives the rest of the clone a cleaner starting point as the UI expands.\nFurther Reading 1. Introduction Working with CSS CSS CSS Changes ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/079-2-creating-the-project-and-css/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/3rLf9A9RYPY?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eWith the product direction defined, the next step is to create a project that can actually support it. This lesson is less about raw project generation and more about choosing the right styling and structural foundation for an app that will grow quickly.\u003c/p\u003e","title":"2. Creating the Project and CSS"},{"content":" Module 13: Creating a Facebook Clone\nSplash screens are easy to overthink. The point is not to hide all startup work behind branding. The point is to make the first moment of the app feel intentional instead of abrupt.\nThis lesson uses a splash screen for a practical reason. The Facebook-style login experience looks very different from the rest of the app, so dropping the user immediately into an unrelated partially loaded screen would feel messy. A simple transition screen gives the app a more coherent starting point.\nThe old video spends time on iOS screenshot generation and older native splash mechanics. That part is historical now and should not be treated as the main lesson. The lasting idea is that startup needs a dedicated entry point. Instead of letting the default generated form dictate the experience, the app introduces a UI controller that owns the initial navigation flow.\nThat controller is the more important architectural move. Once the app has a single place that decides whether to show the splash screen, login flow, or some later authenticated screen, startup logic stops being scattered across individual forms.\nThe morph from the splash logo into the next screen’s logo is also a good example of animation serving a real purpose. It visually connects the temporary startup state to the application state that follows it, which makes the change feel continuous rather than arbitrary.\nFurther Reading 2. Creating the Project and CSS Transitions Animation Manager, Style Animations and Low Level Animations Creating a Hello World App ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/080-3-splash-screen/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/Rat-FDqDCTU?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eSplash screens are easy to overthink. The point is not to hide all startup work behind branding. The point is to make the first moment of the app feel intentional instead of abrupt.\u003c/p\u003e\n\u003cp\u003eThis lesson uses a splash screen for a practical reason. The Facebook-style login experience looks very different from the rest of the app, so dropping the user immediately into an unrelated partially loaded screen would feel messy. A simple transition screen gives the app a more coherent starting point.\u003c/p\u003e","title":"3. Splash Screen"},{"content":" Module 13: Creating a Facebook Clone\nThe login screen is the first place where the Facebook clone stops being an abstract styling exercise and starts making real product decisions. Facebook’s native login UI is inconsistent across platforms, and the video handles that honestly by taking inspiration rather than trying to reproduce every awkward choice exactly.\nThat is the right instinct. A good clone should learn from the source product, not inherit every mistake. This lesson keeps the broad shape of the Facebook login flow while making clearer decisions about tablets, landscape mode, and how much the interface should diverge between iOS and Android.\nOne useful Codename One detail here is ComponentGroup. On iOS, grouped fields are a familiar pattern and the native theme already knows how to style first, middle, and last grouped entries. On Android, that same container can degrade gracefully into a more ordinary stacked layout without forcing the whole screen into an iOS look. That makes it a good example of using native theme behavior as an asset instead of trying to flatten every platform into one visual language.\nThe landscape treatment is also worth noticing. The lesson is not just making the same login form wider. It is changing the balance of the layout so the screen still feels intentional when the device rotates. That is much better than letting the form expand passively and hoping it still looks good.\nThe logo transition from the splash screen matters for the same reason. Naming the logo component so the morph transition can connect startup to login gives the first seconds of the app a sense of continuity, which is exactly the kind of polish users notice without consciously naming it.\nThe CSS work in this lesson is more than ornament. It defines which buttons should follow Android’s uppercase convention, which containers should carry platform-specific spacing, and how the login screen should hold together visually across form factors. This is where the earlier decision to use CSS starts paying off.\nFurther Reading 3. Splash Screen 5. Rich Text View and Signup Form Working with CSS Adapting a UI Design ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/081-4-login-form/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/vdFr815Dhpg?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe login screen is the first place where the Facebook clone stops being an abstract styling exercise and starts making real product decisions. Facebook’s native login UI is inconsistent across platforms, and the video handles that honestly by taking inspiration rather than trying to reproduce every awkward choice exactly.\u003c/p\u003e","title":"4. Login Form"},{"content":" Module 13: Creating a Facebook Clone\nOnce the login screen exists, the next challenge is the signup flow. This lesson makes two important architectural moves before building more screens: it creates a reusable form shell for the signup wizard, and it introduces a lightweight rich-text component for short formatted text with links.\nThat second piece is especially useful. Full HTML rendering is often more power than you actually want for tightly controlled UI copy. For this case the goal is modest: allow short blocks of text with line breaks, emphasis, and clickable links while keeping the component visually integrated with the rest of the app.\nThe custom rich-text view is therefore a good example of choosing the right level of abstraction. Instead of embedding a browser component just because HTML is involved, the lesson builds a small renderer for a constrained subset of markup. That keeps styling, layout, and event handling under application control.\nThe signup form abstraction is the other big win. Multiple signup stages share the same general structure: a title area, content in the middle, fixed controls near the bottom, and slightly different back behavior depending on platform conventions. Capturing that once makes the later signup screens much easier to build and much easier to keep visually consistent.\nThis is the kind of reusable UI infrastructure that is worth writing. It is close to the needs of the app, clearly justified by repetition, and still small enough that it does not turn into a second framework inside the project.\nFurther Reading 6. Signup Form - Terms and Conditions Working with CSS Layout Basics How Do I Handle Events/Navigation in the GUI Builder \u0026amp; Populate the Form from Code ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/082-5-rich-text-view-and-signup-form/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/UhLFHJj8qnM?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the login screen exists, the next challenge is the signup flow. This lesson makes two important architectural moves before building more screens: it creates a reusable form shell for the signup wizard, and it introduces a lightweight rich-text component for short formatted text with links.\u003c/p\u003e","title":"5. Rich Text View and Signup Form"},{"content":" Module 13: Creating a Facebook Clone\nThe first real signup screen is intentionally simple, and that is exactly why it matters. This is where the reusable signup shell proves itself and where the rest of the wizard’s visual language starts becoming concrete.\nThe form itself is mostly content and framing: a clear title, explanatory text, a prominent next action, and supporting links below. Because the structure was abstracted in the previous lesson, the screen-specific code can stay focused on meaning rather than layout plumbing.\nThe rich-text component earns its place here by rendering highlighted legal and explanatory copy without dragging in a heavier HTML solution. That makes this lesson a good checkpoint for the earlier architectural decision. The app now has a custom text component that feels native to the design rather than bolted on from outside.\nThe CSS additions are also important because they define the vocabulary for the rest of the signup wizard: toolbar spacing, title sizing, back-command behavior, off-white backgrounds, and the visual identity of the “next” action. Once those rules exist, later stages can reuse them instead of negotiating their visual hierarchy from scratch.\nThis is one of those lessons where the code is not flashy, but the payoff is large. A clean first step in a wizard sets expectations for every step that follows.\nFurther Reading 5. Rich Text View and Signup Form 7. Signup Form - Name, Birthday and Gender Working with CSS CSS Changes ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/083-6-signup-form-terms-and-conditions/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/xLa5yeeVsE8?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe first real signup screen is intentionally simple, and that is exactly why it matters. This is where the reusable signup shell proves itself and where the rest of the wizard’s visual language starts becoming concrete.\u003c/p\u003e\n\u003cp\u003eThe form itself is mostly content and framing: a clear title, explanatory text, a prominent next action, and supporting links below. Because the structure was abstracted in the previous lesson, the screen-specific code can stay focused on meaning rather than layout plumbing.\u003c/p\u003e","title":"6. Signup Form - Terms and Conditions"},{"content":" Module 13: Creating a Facebook Clone\nThese middle signup stages are where the wizard starts feeling like a real product instead of a static mockup. The screens are still simple, but they exercise a wider range of input patterns: paired text entry, date selection, and mutually exclusive choices with visual emphasis.\nThe name form is a good showcase for TextComponent and TextModeLayout. Together they give the app a way to describe input fields at a higher level while still letting the underlying platform shape how those fields feel. On Android, that means the material-style animated labels. On iOS, it means a more grouped presentation. The lesson uses that flexibility well instead of hard-coding one platform’s style everywhere.\nThe birthday form is deliberately plain, and that honesty is useful. Not every part of a product needs to become a design showcase. If the platform’s date-picking UI already solves the interaction well, it is often better to use it than to invent a more fragile custom control.\nThe gender step then adds a different kind of UI problem: choosing between visually equivalent options where the selection itself needs to be obvious. Radio-button semantics with stronger visual styling are a clean fit here. The lesson’s use of grouped toggle-style buttons backed by one-button selection rules is straightforward and easy to reason about.\nTaken together, these screens show a good principle for signup flows: keep the structure stable, but let each input type use the most appropriate interaction model available.\nFurther Reading 8. Signup Form - Phone, Email, Password and Confirmation Properties Are Amazing Layout Basics How Do I Position Components Using Layout Managers ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/084-7-signup-form-name-birthday-and-gender/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/Nv_0NVgCbSk?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThese middle signup stages are where the wizard starts feeling like a real product instead of a static mockup. The screens are still simple, but they exercise a wider range of input patterns: paired text entry, date selection, and mutually exclusive choices with visual emphasis.\u003c/p\u003e","title":"7. Signup Form - Name, Birthday and Gender"},{"content":" Module 13: Creating a Facebook Clone\nThe final signup stages are less about new UI ideas and more about keeping the flow coherent as the user approaches completion. That makes this lesson mostly a test of whether the earlier abstractions were worth building.\nThe answer is yes. Phone-number and email entry are almost the same screen, and the code treats them that way without forcing them into a confusing generic abstraction. This is a good example of restraint. Similar screens can share a helper without erasing the fact that they represent slightly different decisions in the flow.\nThe key detail here is navigation between alternatives. The user can move from phone to email or back again without the wizard feeling like it split into two unrelated branches. That continuity matters more than the individual input fields themselves.\nThe password and confirmation stages are then intentionally minimal. By this point the wizard has already done most of its real work, so the final screens should feel like progress, not like the app suddenly discovered a new set of demands. The lesson handles that correctly by keeping the screens short, contextual, and clearly connected to what the user just entered.\nThe final wiring into the UI controller is also important. A wizard is not complete until the rest of the app can actually route into it and out of it cleanly. This lesson closes that loop so the signup flow stops being a pile of isolated forms and becomes a real branch of application navigation.\nFurther Reading 7. Signup Form - Name, Birthday and Gender 9. The Main Form Threading and the EDT Creating a Hello World App ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/085-8-signup-form-phone-email-password-and-confirmation/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/v-kJ_nIYq3I?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe final signup stages are less about new UI ideas and more about keeping the flow coherent as the user approaches completion. That makes this lesson mostly a test of whether the earlier abstractions were worth building.\u003c/p\u003e\n\u003cp\u003eThe answer is yes. Phone-number and email entry are almost the same screen, and the code treats them that way without forcing them into a confusing generic abstraction. This is a good example of restraint. Similar screens can share a helper without erasing the fact that they represent slightly different decisions in the flow.\u003c/p\u003e","title":"8. Signup Form - Phone, Email, Password and Confirmation"},{"content":" Module 13: Creating a Facebook Clone\nOnce the signup flow is in place, the app finally needs a home. This lesson builds that shell: the tabbed main form that holds the news feed, friends, notifications, and “more” sections together.\nThat shell is more important than it first appears. A social app is mostly movement between adjacent sections of one large experience. If the outer navigation structure feels wrong, the whole app feels fragmented no matter how good the individual screens are.\nThe tab design in the lesson takes platform differences seriously. Tabs belong in different places on different platforms, and Codename One makes it possible to respect that expectation without duplicating the whole app structure. That is exactly the kind of platform-aware decision that improves a clone without making the code unmanageable.\nThe lesson also makes a useful styling decision by turning the search affordance into something that looks like a field while still behaving like a navigation trigger. That matches the product’s intent: the main form is not trying to host a full search experience yet, but it still needs to make search feel present and ready.\nAt this stage, the individual containers behind the tabs are still mostly placeholders, and that is fine. The job of this lesson is to define the application frame and make it possible for the later feature work to land in the right places.\nFurther Reading 10. Client Data Model - User, Post and Comment 12. The Newsfeed Container Friends Container How Do I Create Gorgeous SideMenu ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/086-9-the-main-form/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/q4YjUClRHBk?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the signup flow is in place, the app finally needs a home. This lesson builds that shell: the tabbed main form that holds the news feed, friends, notifications, and “more” sections together.\u003c/p\u003e\n\u003cp\u003eThat shell is more important than it first appears. A social app is mostly movement between adjacent sections of one large experience. If the outer navigation structure feels wrong, the whole app feels fragmented no matter how good the individual screens are.\u003c/p\u003e","title":"9. The Main Form"},{"content":" Module 13: Creating a Facebook Clone\nThere is a moment in every UI-heavy project when the mockup stops being “just screens” and starts forcing you to define the underlying data. This is that moment for the Facebook clone.\nThe lesson introduces User, Post, and Comment as property-based business objects, and that is the right direction for this app. A social product is full of structured data that needs to move between storage, server communication, caching, and UI. Codename One properties fit that problem well because they reduce a lot of repetitive plumbing.\nThe User model comes first because so much of the app depends on it: signup, identity, profile images, social connections, and display names. The avatar handling is especially useful because it treats the image not as a dumb URL but as something the client can fetch, cache, resize, and shape into the exact visual form the UI needs.\nThat is a recurring pattern throughout this course. The raw data is not always the same thing as the UI-ready data. Sometimes the business object should help bridge that gap directly when the transformation is common and predictable.\nThe Post and Comment models then complete the minimum vocabulary needed for a social feed. Visibility, likes, comments, author identity, timestamps, and content styling all show up here because the feed UI is about to demand them. This is a good example of building the model close to the product rather than designing a grand universal schema first.\nThe nested-comment support hinted at in the Comment model is also a good sign of foresight. Even before the threaded UI exists, the model is being shaped so the app will not need to undo basic decisions later.\nFurther Reading 11. ServerAPI Abstraction Mockup 12. The Newsfeed Container Properties Are Amazing Overview and Basic Model ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/087-10-client-data-model-user-post-and-comment/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/PHb5YO77OQk?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThere is a moment in every UI-heavy project when the mockup stops being “just screens” and starts forcing you to define the underlying data. This is that moment for the Facebook clone.\u003c/p\u003e\n\u003cp\u003eThe lesson introduces \u003ccode\u003eUser\u003c/code\u003e, \u003ccode\u003ePost\u003c/code\u003e, and \u003ccode\u003eComment\u003c/code\u003e as property-based business objects, and that is the right direction for this app. A social product is full of structured data that needs to move between storage, server communication, caching, and UI. Codename One properties fit that problem well because they reduce a lot of repetitive plumbing.\u003c/p\u003e","title":"10. Client Data Model - User, Post and Comment"},{"content":" Module 13: Creating a Facebook Clone\nOnce the client data model exists, the next architectural step is to stop letting the UI imagine that data comes from nowhere. Even if the real backend is not ready yet, the app should already talk to an abstraction that looks like a server boundary.\nThat is what this lesson gets right. The mock ServerAPI is not just fake data for convenience. It is a way to force the UI to depend on application-level operations instead of hard-coded inline sample objects.\nThat decision pays off later because the UI can be written once against methods such as “fetch timeline posts” or “get current user,” and the implementation behind those methods can later switch from mock data to real network calls without rewriting every screen.\nThe mock data itself is also more intentional than a typical placeholder. It includes realistic users, timestamps, avatars, and simple relationships such as friends and suggestions. That makes the upcoming feed and friends UI feel like they are attached to a real product even before the server work is done.\nThe utility methods added alongside this abstraction are part of the same story. Formatting “just now” style timestamps and creating reusable separators may feel small, but they keep repeated UI logic out of the container classes where it would otherwise start to pile up.\nThis is exactly the right stage to introduce a server boundary. The app is complex enough to need one, but still small enough that putting it in place now will simplify everything that follows.\nFurther Reading 10. Client Data Model - User, Post and Comment 12. The Newsfeed Container 17. Spring Boot Server Architecture and the User Entity Connecting to a Web Service ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/088-11-serverapi-abstraction-mockup/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/PERdJq3I-As?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the client data model exists, the next architectural step is to stop letting the UI imagine that data comes from nowhere. Even if the real backend is not ready yet, the app should already talk to an abstraction that looks like a server boundary.\u003c/p\u003e","title":"11. ServerAPI Abstraction Mockup"},{"content":" Module 13: Creating a Facebook Clone\nThis is the lesson where the Facebook clone starts feeling alive. The news feed is the first screen in the app that combines real scrolling content, structured models, reusable view fragments, and a data source that looks like a real server.\nUsing InfiniteContainer is a natural fit here. A feed is exactly the kind of UI that should not pretend it knows all of its content up front. The container can ask for more entries as the user scrolls and can also support pull-to-refresh without requiring a completely different architecture for reloading.\nThe lesson handles that well by separating the feed into small pieces. There is a top “what’s on your mind” style post bar, a title/header area for each post, a stats area, and then a final method that assembles those parts into one feed item. That keeps the code readable and makes it much easier to evolve the rendering later.\nThe time-formatting helper from the previous lesson also pays off here. Social feeds always need human-readable time, and handling that in a utility layer instead of repeating it in every view method is exactly the kind of small discipline that keeps UI code healthy as the app grows.\nThe feed item assembly code also shows good layout judgment. Buttons that should align are placed in a grid. Repeated structural spacing is centralized in reusable UIIDs. Rich text is used where post content needs it. The lesson is not just rendering data. It is turning several reusable visual rules into one coherent feed entry.\nFurther Reading 10. Client Data Model - User, Post and Comment 11. ServerAPI Abstraction Mockup 13. Friends Container How Do I Create a List of Items the Easy Way ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/089-12-the-newsfeed-container/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/B4QCJRFpG-k?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThis is the lesson where the Facebook clone starts feeling alive. The news feed is the first screen in the app that combines real scrolling content, structured models, reusable view fragments, and a data source that looks like a real server.\u003c/p\u003e","title":"12. The Newsfeed Container"},{"content":" Module 13: Creating a Facebook Clone\nAfter the feed, the friends screen feels almost relaxing. It is a simpler UI, but it still has enough moving parts to show how the same data and styling ideas can support a different kind of social surface.\nThe lesson makes a sensible choice by using a regular scrollable container instead of InfiniteContainer. Not every list in an app needs infinite loading just because one important screen does. Friend requests and suggestions are finite enough here that a simpler structure keeps the code easier to understand.\nThe screen itself is built from two kinds of sections: requests that need action and suggestions that invite exploration. That split is useful because it gives the UI a little product logic instead of flattening all relationships into one undifferentiated list.\nThe avatar handling is also a good example of being flexible about presentation. The feed used circular identity images because that matched the product language there. This screen uses square images because the visual reference calls for them. The underlying user identity is the same, but the rendering can still adapt to the needs of the specific screen.\nThe confirm/delete controls then finish the pattern. The screen is not just decorative. It expresses clear actions, and the CSS gives those actions distinct visual weight without needing a large amount of custom code.\nFurther Reading 12. The Newsfeed Container 39. Settings Form and Fetching the Avatar Image Client Side UserService How Do I Create a List of Items the Easy Way ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/090-13-friends-container/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/LZ_ydua__gY?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eAfter the feed, the friends screen feels almost relaxing. It is a simpler UI, but it still has enough moving parts to show how the same data and styling ideas can support a different kind of social surface.\u003c/p\u003e\n\u003cp\u003eThe lesson makes a sensible choice by using a regular scrollable container instead of \u003ccode\u003eInfiniteContainer\u003c/code\u003e. Not every list in an app needs infinite loading just because one important screen does. Friend requests and suggestions are finite enough here that a simpler structure keeps the code easier to understand.\u003c/p\u003e","title":"13. Friends Container"},{"content":" Module 13: Creating a Facebook Clone\nNotifications are one of the places where a social app starts feeling reactive instead of static. This lesson adds that layer without overcomplicating it. The notification screen is basically a specialized feed: timestamped items, user identity, a short action summary, and a visual reaction marker that hints at why the notification happened.\nThat makes the design choice in this lesson straightforward and correct. Use the same incremental-loading model as the news feed, but simplify the rendering because notifications do not need the full structure of a post.\nThe new notification business object is also a good example of the client/server contract staying focused. The server decides the text, icon semantics, and background accent for the reaction. The client’s job is to render those values consistently, not to recalculate their meaning locally.\nThe layered avatar-plus-reaction treatment is the nicest UI detail here. It uses familiar identity imagery as the base and then overlays the event type in a way users can scan quickly. That is exactly the sort of small visual system that helps a dense app stay readable.\nThis lesson also demonstrates that not every feed-style screen needs a long chain of helper methods. The news feed needed more decomposition because posts are complex. Notifications are simpler, so the screen can stay lighter without becoming messy.\nFurther Reading 12. The Newsfeed Container 23. NotificationService and MediaService 39. Settings Form and Fetching the Avatar Image Push Notifications ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/091-14-notifications-container/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/FczBAgUIb1c?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eNotifications are one of the places where a social app starts feeling reactive instead of static. This lesson adds that layer without overcomplicating it. The notification screen is basically a specialized feed: timestamped items, user identity, a short action summary, and a visual reaction marker that hints at why the notification happened.\u003c/p\u003e","title":"14. Notifications Container"},{"content":" Module 13: Creating a Facebook Clone\nThe “more” tab is where large apps often reveal whether they still have any structural discipline. It can either become a dumping ground for leftovers or a clean overflow area for features that do not deserve top-level navigation.\nThis lesson takes the second path. The screen is intentionally simple, but it still treats the section as a real part of the app by giving entries consistent icon treatment, spacing, and text hierarchy. That is enough to make the area feel deliberate even before most of its destinations are implemented.\nThe use of MultiButton is a good fit here. These entries are really structured menu rows: primary label, optional secondary text, icon treatment, and clear tap behavior. A higher-level component makes more sense than rebuilding that row structure manually for every entry.\nThe lesson also shows a healthy willingness to handle a small styling gap in code when the CSS support of the time was not sufficient. That part is historical, but the underlying principle still holds: use CSS as the default, and fill the rare gaps pragmatically instead of distorting the whole design to avoid one line of code.\nWhat matters most is that the app now has a place for user-adjacent functions such as settings without forcing them into the main feed tabs. That keeps the primary navigation focused while still leaving room for the app to grow.\nFurther Reading 39. Settings Form and Fetching the Avatar Image 9. The Main Form How Do I Create Gorgeous SideMenu Working with CSS ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/092-15-the-more-container/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/kfKsVAx659s?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe “more” tab is where large apps often reveal whether they still have any structural discipline. It can either become a dumping ground for leftovers or a clean overflow area for features that do not deserve top-level navigation.\u003c/p\u003e\n\u003cp\u003eThis lesson takes the second path. The screen is intentionally simple, but it still treats the section as a real part of the app by giving entries consistent icon treatment, spacing, and text hierarchy. That is enough to make the area feel deliberate even before most of its destinations are implemented.\u003c/p\u003e","title":"15. The More Container"},{"content":" Module 13: Creating a Facebook Clone\nThe post composer is where the Facebook clone stops being a read-mostly app and becomes participatory. Even in this first simplified version, that changes the feel of the whole product.\nThe form is intentionally scoped to text-first posting, and that is the right call. Images, video, and richer media behavior can come later. The important step here is establishing the composer as its own screen with clear identity, visibility controls, and a way to preview different post styles.\nThe style picker at the bottom is the most interesting part of the lesson. Instead of treating post styling as a bag of unrelated options, the UI presents a small set of named visual modes. That makes the experience fast and tactile. The user is not editing raw styling properties. They are choosing among recognizable post treatments.\nThe use of radio-style selection for those styles is a good fit because only one visual mode should be active at a time. The composer can then translate that choice into a combination of UIIDs and content treatment without exposing that machinery to the user.\nThis lesson also shows a useful boundary between content and presentation. The post text stays the same, but the surrounding style changes. That separation matters later when the app needs to store style choices alongside the post rather than flattening them into one opaque blob of rendered content.\nFurther Reading 12. The Newsfeed Container 10. Client Data Model - User, Post and Comment Working with CSS Style Customization 1 - Introduction and Basics ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/093-16-the-new-post-form/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/0a6mPI412C4?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe post composer is where the Facebook clone stops being a read-mostly app and becomes participatory. Even in this first simplified version, that changes the feel of the whole product.\u003c/p\u003e\n\u003cp\u003eThe form is intentionally scoped to text-first posting, and that is the right call. Images, video, and richer media behavior can come later. The important step here is establishing the composer as its own screen with clear identity, visibility controls, and a way to preview different post styles.\u003c/p\u003e","title":"16. The 'New Post' Form"},{"content":" Module 13: Creating a Facebook Clone\nUp to this point the Facebook clone has been living on a mock server boundary. This lesson starts building the real backend behind that boundary, and it does so in the right order: architecture first, then the first entity.\nThe four-layer split in the lesson is still a strong way to explain the backend: web-service endpoints at the edge, service classes for business logic, DAO objects for transport, and JPA entities plus repositories for persistence. Even if the exact Spring stack evolves, that separation of concerns remains valuable because it keeps storage, transport, and business rules from collapsing into one class.\nThe best part of this approach is that it leaves room for change. A service method can later be exposed through a different transport without rewriting the business logic. A storage mechanism can later be swapped without forcing the client contract to change at the same rate. That is the real payoff of the structure, not just aesthetic cleanliness.\nThe User entity is the right place to begin because almost every feature built so far depends on it. Signup, login, profile rendering, friendships, avatars, and notifications all become easier to reason about once the server has a proper user model.\nThe discussion of IDs is also one of the more useful backend design points in the course. Exposing sequential numeric primary keys to the client is convenient at first, but it creates obvious problems. UUID-style external IDs make much more sense for a public-facing system where client-visible identifiers should not invite trivial enumeration.\nThe client and server user models are deliberately similar, and that is good. They represent the same domain concept. The server version can still carry extra concerns such as password hashing and security token handling, but the basic overlap is a strength, not a problem.\nFurther Reading 21. Service Layer and UserService 10. Client Data Model - User, Post and Comment Introduction to Spring Boot Connecting to a Web Service ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/094-17-spring-boot-server-architecture-and-the-user-entity/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/iCY64ThCleI?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eUp to this point the Facebook clone has been living on a mock server boundary. This lesson starts building the real backend behind that boundary, and it does so in the right order: architecture first, then the first entity.\u003c/p\u003e","title":"17. Spring Boot Server Architecture and the User Entity"},{"content":" Module 13: Creating a Facebook Clone\nA social app quickly runs into the question of where media should live. This lesson answers that by introducing a dedicated media entity instead of burying file data inside unrelated objects.\nThat is the right first step regardless of whether the actual bytes stay in the database forever. Separating media into its own entity means the application can reason about uploads, ownership, visibility, and purpose independently from the records that reference them.\nThe lesson is also honest about the tradeoff. Storing blobs in a database can be convenient, especially in a simple deployment or clustered environment, but it is not always the final answer. The more durable architectural lesson is that the app should already have a media abstraction, so moving later to object storage or another file service does not require redesigning the whole domain model.\nFields such as filename, timestamp, role, visibility, and owner are doing real work here. They turn the media record from “just bytes” into something the rest of the application can reason about. An avatar image is not the same thing as a post attachment, and visibility rules matter long before the app has every UI feature built.\nThe DAO stays intentionally simple, which is also a good sign. Media transport should be explicit and predictable rather than full of hidden side effects.\nFurther Reading 19. Post and Comment Entities 23. NotificationService and MediaService 39. Settings Form and Fetching the Avatar Image 40. Edit User - UI Binding and Multipart Image Upload ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/095-18-media-entity/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/W_1S2Rzgff8?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eA social app quickly runs into the question of where media should live. This lesson answers that by introducing a dedicated media entity instead of burying file data inside unrelated objects.\u003c/p\u003e\n\u003cp\u003eThat is the right first step regardless of whether the actual bytes stay in the database forever. Separating media into its own entity means the application can reason about uploads, ownership, visibility, and purpose independently from the records that reference them.\u003c/p\u003e","title":"18. Media Entity"},{"content":" Module 13: Creating a Facebook Clone\nOnce users and media exist on the server, posts and comments are the next unavoidable step. These are the entities that turn the app from a profile system into a real social product.\nThe lesson follows a sound pattern by keeping the server-side models close to the client-side ones while still allowing the server versions to carry extra persistence and relationship detail. That overlap is a feature, not a flaw. Both sides are describing the same social concepts.\nThe Post entity brings together authorship, timing, content, visibility, styling, comments, and likes. That is a lot of responsibility, but it is the right bundle because those features are what the feed needs to display and what the backend needs to query.\nThe choice to store individual likes rather than only a count is especially important. Counts are convenient for rendering, but a social app usually needs to know who liked something, not just how many people did. Once that requirement exists, the model has to reflect it.\nThe Comment entity then rounds out the conversation layer. Supporting a parent comment reference early is a good move because it leaves room for nested threads later even if the first client UI stays simpler.\nThe repository discussion is also useful because this is where paging starts to matter. Social content is exactly the kind of data that should not be loaded all at once. Building pageable queries into the persistence layer early keeps later service code cleaner and keeps the app aligned with the feed-style UX it already has on the client.\nFurther Reading 20. Notification, Newsfeed and ShadowUser Entities 21. Service Layer and UserService 10. Client Data Model - User, Post and Comment 12. The Newsfeed Container ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/096-19-post-and-comment-entities/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/tjgyigzxo5U?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce users and media exist on the server, posts and comments are the next unavoidable step. These are the entities that turn the app from a profile system into a real social product.\u003c/p\u003e\n\u003cp\u003eThe lesson follows a sound pattern by keeping the server-side models close to the client-side ones while still allowing the server versions to carry extra persistence and relationship detail. That overlap is a feature, not a flaw. Both sides are describing the same social concepts.\u003c/p\u003e","title":"19. Post and Comment Entities"},{"content":" Module 13: Creating a Facebook Clone\nThis lesson is where the server model becomes recognizably social. Notifications are the obvious missing piece, but the more interesting work is the introduction of two server-only concepts: a materialized newsfeed entity and the shadow-user model behind “people you may know.”\nThe notification entity is straightforward and intentionally mirrors the client model closely. That makes sense because notifications are already being rendered on the device and mostly need a clean transport path plus some server-side persistence.\nThe Newsfeed entity is the more ambitious idea. Instead of treating the feed as a fresh query over posts every time, the lesson frames it as something that can be assembled, ranked, stored, and served as its own dataset. That is a stronger design for a real social product because feed ordering is not just raw chronology. It is the result of ranking rules, personalization, and the need for some consistency over time.\nEven in this simplified implementation, that architectural move is important. It gives the backend a place to evolve ranking logic without forcing every client request to recompute the whole feed from scratch.\nThe ShadowUser entity is the most revealing social-graph concept in the module. It models information the system knows about people who may not yet be full users, typically because someone uploaded contacts or other identifying data. That is what allows the app to make friend suggestions with more context than the visible user table alone would provide.\nEven though the implementation here is intentionally simplified, the lesson is useful because it makes an often invisible product mechanism explicit. Suggestions in social apps do not come from magic. They come from graph-building work and stored relationship hints, and that requires its own model.\nFurther Reading 14. Notifications Container 21. Service Layer and UserService 22. UserService Part II 13. Friends Container ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/097-20-notification-newsfeed-and-shadowuser-entities/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/Otujb_KyofA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThis lesson is where the server model becomes recognizably social. Notifications are the obvious missing piece, but the more interesting work is the introduction of two server-only concepts: a materialized newsfeed entity and the shadow-user model behind “people you may know.”\u003c/p\u003e","title":"20. Notification, Newsfeed and ShadowUser Entities"},{"content":" Module 13: Creating a Facebook Clone\nThe entity layer stores information. The service layer is where the application starts making decisions. That distinction matters, and this lesson is the first place in the Facebook backend where the system begins to feel like more than a database with endpoints attached to it.\nUserService is the natural place to start because signup, login, activation, and identity all flow through it. Those are not just persistence operations. They involve validation, password handling, token creation, activation workflows, and relationship bootstrapping.\nThe login path is a good example of service-layer value. The repositories can find candidate users by email or phone, but the service is the right place to enforce expectations such as uniqueness and password verification. The service is also the right place to convert failure into a meaningful application-level error instead of leaking raw persistence concerns outward.\nSignup is more interesting because it touches almost every part of the surrounding architecture. It needs to reject duplicate accounts, absorb information from shadow-user records, hash the password, mint an auth token, generate an activation code, and then send that code through an external delivery mechanism. That is exactly the kind of workflow that belongs in a service class and nowhere else.\nThe lesson’s setProps helper is also a useful reminder that not every field should be updated just because it exists on the entity. A service method should decide explicitly which properties are safe to copy from client input and which ones require special handling.\nThe sections on Twilio and Mailgun are partly about tooling, but the more durable architectural lesson is that delivery integrations should be driven from the service layer and configured from outside source control. API keys, sender identities, and environment-specific credentials belong in configuration, not hard-coded into business logic.\nFurther Reading 22. UserService Part II 17. Spring Boot Server Architecture and the User Entity 20. Notification, Newsfeed and ShadowUser Entities Push 3 - The Server Side and Build Logic ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/098-21-service-layer-and-userservice/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/QY7josfVbdg?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe entity layer stores information. The service layer is where the application starts making decisions. That distinction matters, and this lesson is the first place in the Facebook backend where the system begins to feel like more than a database with endpoints attached to it.\u003c/p\u003e","title":"21. Service Layer and UserService"},{"content":" Module 13: Creating a Facebook Clone\nIf the first half of UserService is about identity, the second half is about relationships. This is where the service starts earning its place as the social core of the app rather than just the entry point for account creation.\nAvatar retrieval and upload are a good warm-up because they clearly separate public and authenticated behavior. Anyone who knows a user’s public identity can fetch the avatar. Only the authenticated owner should be able to replace it. That is exactly the sort of permission distinction the service layer should make explicit.\nFriend requests raise the stakes a little more because they mutate two users’ relationship state and also trigger notifications. That is a strong reminder that many social operations are not local edits to one record. They are workflows that span multiple entities and often require side effects in other parts of the system.\nThe acceptance path is especially important because it has to verify that the underlying request actually exists. Social operations are full of these asymmetry problems: one user can request, the other can accept, and the system has to make sure those actions line up instead of trusting the client blindly.\nThe contact-upload logic then moves even deeper into social-graph construction. Once users can upload contact information, the service can start reconciling that data against known users and shadow-user records to improve the “people you may know” suggestions. The implementation here is intentionally simpler than a production social graph would be, but the architectural idea is sound: relationship-building often starts from imported hints rather than explicit in-app actions.\nThis lesson also quietly reinforces a pattern that matters across the whole backend: batch operations such as saveAll() are often worth using when the service is processing a lot of related data. Social features can create large cascades of small updates, and the service layer is where you get to decide whether those updates happen efficiently.\nFurther Reading 21. Service Layer and UserService 20. Notification, Newsfeed and ShadowUser Entities 23. NotificationService and MediaService 13. Friends Container ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/099-22-userservice-part-ii/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/JZvrsZzdays?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eIf the first half of \u003ccode\u003eUserService\u003c/code\u003e is about identity, the second half is about relationships. This is where the service starts earning its place as the social core of the app rather than just the entry point for account creation.\u003c/p\u003e","title":"22. UserService Part II"},{"content":" Module 13: Creating a Facebook Clone\nThese two services are simpler than UserService, but they matter because they isolate two concerns that would otherwise spread across the rest of the backend: event delivery and file handling.\nNotificationService is small on purpose. Right now it persists notifications and serves paged results back to the client. That may not look dramatic, but the separation is valuable because notifications are exactly the kind of feature that tends to accumulate extra delivery mechanisms over time. By giving them their own service now, the app already has the right place to add push, WebSocket fanout, or other delivery channels later.\nThat is why the send-notification method is more important than it first appears. Even if it currently just writes a record, it defines the one place where “something happened and the user should hear about it” enters the backend.\nMediaService plays a similar role for uploads and access control. It owns the rule that media creation is authenticated, that timestamps come from the server rather than the client, and that visibility checks determine who can retrieve a given file.\nThe visibility logic is especially important in a social app. Public media is easy. Friend-only media is where the service layer has to translate social relationships into authorization decisions. That should not be left to the client, and it should not be scattered across controller code.\nThe little permission and visibility helpers in this lesson may feel unremarkable, but they are the sort of infrastructure that prevents the backend from drifting into a pile of ad hoc access checks.\nFurther Reading 14. Notifications Container 18. Media Entity 19. Post and Comment Entities Push 3 - The Server Side and Build Logic ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/100-23-notificationservice-and-mediaservice/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/zJ7L5fi60H8?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThese two services are simpler than \u003ccode\u003eUserService\u003c/code\u003e, but they matter because they isolate two concerns that would otherwise spread across the rest of the backend: event delivery and file handling.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eNotificationService\u003c/code\u003e is small on purpose. Right now it persists notifications and serves paged results back to the client. That may not look dramatic, but the separation is valuable because notifications are exactly the kind of feature that tends to accumulate extra delivery mechanisms over time. By giving them their own service now, the app already has the right place to add push, WebSocket fanout, or other delivery channels later.\u003c/p\u003e","title":"23. NotificationService and MediaService"},{"content":" Module 13: Creating a Facebook Clone\nPostService is where the social app starts acting like a social app instead of a collection of account features. This service owns the operations that make the feed move: creating posts, inserting them into newsfeeds, adding comments, and tracking likes.\nThe first useful distinction in the lesson is between a user’s own posts and the newsfeed they consume. Those are not the same thing. A profile post list can often be queried directly from posts. A feed is more contextual. It blends content from multiple sources and needs its own ordering rules.\nThat is why the separate Newsfeed entity introduced earlier matters so much here. PostService can write newly created posts into the right feed records when the post is created instead of trying to reconstruct the whole ranking story every time the client asks for page one again.\nThe posting path is also a good example of service-layer responsibility. A new post is not just one database save. It creates the post record, decides who should see it, inserts it into the author’s feed, inserts it into friends’ feeds where appropriate, and returns the information the client needs to keep going.\nComments and likes follow the same pattern. These are not just property changes on one row. They are social events with permission checks, relationship checks, and notification side effects. The lesson keeps them in one service, which is the right place because this is where the rules about who can interact with what actually belong.\nThe simplifications are also sensible. There is no full reactions model yet, and unlike is omitted even though it would be easy to add later. That restraint keeps the service focused on the core feed interactions instead of widening the scope unnecessarily.\nFurther Reading 20. Notification, Newsfeed and ShadowUser Entities 23. NotificationService and MediaService 29. Newsfeed and Posts From Server 12. The Newsfeed Container ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/101-24-postservice/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/UxATbrfWveU?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003e\u003ccode\u003ePostService\u003c/code\u003e is where the social app starts acting like a social app instead of a collection of account features. This service owns the operations that make the feed move: creating posts, inserting them into newsfeeds, adding comments, and tracking likes.\u003c/p\u003e","title":"24. PostService"},{"content":" Module 13: Creating a Facebook Clone\nOnce the service layer exists, the web-service layer should be boring. That is not a criticism. It is a sign that the architecture is doing its job.\nThis lesson demonstrates that well. UserWebService is mostly a translation layer. It defines URLs, request shapes, headers, and response behavior, then hands the real work off to the service classes underneath. That is exactly what controllers should look like in a healthy backend.\nThe exception-to-error-DAO mapping is one of the most important parts here. It gives the client a predictable error contract instead of exposing raw Java exceptions or framework defaults. Even simple apps benefit from that discipline because it keeps client-side error handling from becoming guesswork.\nThe avatar endpoints are a good example of the controller layer adding protocol-specific behavior without swallowing business logic. They return image content with the right response metadata, turn missing avatars into 404 semantics, and still leave the real authorization and data retrieval rules to the service layer.\nThe lesson also makes a pragmatic choice in a few places by using GET operations for state changes when the mobile client benefits from simpler calling code. That is not something I would present as ideal REST design today. It works here because the client is controlled, but the general rule should still be to avoid using GET for operations that mutate state.\nSo the right takeaway is not “copy these HTTP verbs literally.” It is “keep the controller thin, explicit, and responsible only for transport concerns.”\nFurther Reading 26. PostWebService and MediaWebService 21. Service Layer and UserService 22. UserService Part II Connecting to a Web Service ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/102-25-webservice-layer-and-userwebservice/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/rjIQqfrFvbI?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the service layer exists, the web-service layer should be boring. That is not a criticism. It is a sign that the architecture is doing its job.\u003c/p\u003e\n\u003cp\u003eThis lesson demonstrates that well. \u003ccode\u003eUserWebService\u003c/code\u003e is mostly a translation layer. It defines URLs, request shapes, headers, and response behavior, then hands the real work off to the service classes underneath. That is exactly what controllers should look like in a healthy backend.\u003c/p\u003e","title":"25. WebService Layer and UserWebService"},{"content":" Module 13: Creating a Facebook Clone\nWith the user-facing endpoints in place, the rest of the web-service layer becomes mostly a matter of exposing the remaining service operations cleanly. This lesson closes that gap for posts and media.\nPostWebService is intentionally direct, and that is a strength. The controller methods closely mirror the service methods for listing posts, loading feed pages, adding new posts, adding comments, and registering likes. That one-to-one mapping is a good sign that the service layer already holds the real application logic.\nThe media side is slightly more subtle because file retrieval and upload bring protocol details with them. MIME types, binary responses, multipart uploads, and visibility-aware retrieval all belong in this layer because they are transport concerns. The controller has to know how to expose them over HTTP even though the service layer decides who is allowed to see what.\nThe multipart upload support is still the right general approach for client-file uploads. The exact Spring APIs and wrappers may evolve, but the design idea is stable: the client submits the file and metadata in one structured request, and the server turns that into a media record plus an uploaded payload.\nThe main thing to notice about this lesson is how uneventful it feels. That is exactly what you want. By this point the backend is structured well enough that finishing the endpoint layer mostly means declaratively exposing operations that already exist.\nFurther Reading 25. WebService Layer and UserWebService 24. PostService 23. NotificationService and MediaService 18. Media Entity ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/103-26-postwebservice-and-mediawebservice/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/h-I62aFYBNA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eWith the user-facing endpoints in place, the rest of the web-service layer becomes mostly a matter of exposing the remaining service operations cleanly. This lesson closes that gap for posts and media.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003ePostWebService\u003c/code\u003e is intentionally direct, and that is a strength. The controller methods closely mirror the service methods for listing posts, loading feed pages, adding new posts, adding comments, and registering likes. That one-to-one mapping is a good sign that the service layer already holds the real application logic.\u003c/p\u003e","title":"26. PostWebService and MediaWebService"},{"content":" Module 13: Creating a Facebook Clone\nThis is where the clone stops pretending. The mock ServerAPI that made UI work possible earlier now gets replaced with a real network-backed implementation, and the payoff of introducing that abstraction early becomes obvious immediately.\nBecause the UI was already written against an application-level API rather than against inline sample data, most of the work here is glue code rather than a client-side rewrite. That is exactly what good abstraction buys you.\nThe helper methods for GET and POST requests are simple, but they matter. They centralize the base URL, authorization token, JSON headers, and common request behavior. Once those pieces live in one place, the rest of the client API stops repeating protocol noise.\nThe login/signup path is also a useful demonstration of client-side state handling. Successful auth responses hydrate the user model, persist it into storage as JSON, and keep the token separately for convenient authorization headers later. That design is still reasonable. It gives the app a durable local session story without making startup logic depend on a fresh login every time.\nThe media-upload path is the most protocol-heavy part of the lesson, but even there the client code stays relatively clean because Codename One already provides a usable multipart abstraction. The important thing is that the callback threading is handled correctly. If the network work finishes off the EDT, the success path has to return to the EDT before it mutates UI state.\nThe contact-upload logic is also a good reminder that “client API” sometimes means real translation work. Native contact data does not arrive in the exact shape the server wants, so the client adapter has to transform it into the application’s transport format.\nFurther Reading 28. Client/Server Signup Process 29. Newsfeed and Posts From Server 25. WebService Layer and UserWebService Connecting to a Web Service ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/104-27-client-side-serverapi/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/yamsuV5Airc?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThis is where the clone stops pretending. The mock \u003ccode\u003eServerAPI\u003c/code\u003e that made UI work possible earlier now gets replaced with a real network-backed implementation, and the payoff of introducing that abstraction early becomes obvious immediately.\u003c/p\u003e\n\u003cp\u003eBecause the UI was already written against an application-level API rather than against inline sample data, most of the work here is glue code rather than a client-side rewrite. That is exactly what good abstraction buys you.\u003c/p\u003e","title":"27. Client Side ServerAPI"},{"content":" Module 13: Creating a Facebook Clone\nThe sensible first end-to-end integration point is authentication, and this lesson makes that explicit. Once login and signup talk to the real backend, the app stops being a UI prototype and starts becoming a working product.\nThe login wiring is intentionally modest, which is good. The screen collects the fields it already owns, builds the request object, shows a progress indicator while the network request is in flight, and then either enters the main UI or displays an error. That is the whole story, and it should be.\nSignup is more interesting because it forces the multi-step wizard to start producing real data instead of just navigating from screen to screen. The binding approach introduced earlier pays off here. As the user moves through the wizard, the bound user object accumulates the entered values until the final request can be sent to the server.\nThat is a clean way to connect a wizard to a backend. The UI does not need to manually copy every field at the end because each stage has already been working against the same evolving object.\nThe confirmation step also becomes meaningful here. Instead of being a final mockup screen, it now sits on top of the real activation flow triggered by the backend’s SMS or email delivery. That makes the whole signup branch feel much more grounded.\nThe last change to the UI controller is small but important: startup now depends on whether a session already exists. That is one of the first places where the app behaves like a real installed client instead of a demo that always begins from the same blank state.\nFurther Reading 27. Client Side ServerAPI 21. Service Layer and UserService 22. UserService Part II 4. Login Form ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/105-28-client-server-signup-process/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/8WER-8R0WqA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe sensible first end-to-end integration point is authentication, and this lesson makes that explicit. Once login and signup talk to the real backend, the app stops being a UI prototype and starts becoming a working product.\u003c/p\u003e\n\u003cp\u003eThe login wiring is intentionally modest, which is good. The screen collects the fields it already owns, builds the request object, shows a progress indicator while the network request is in flight, and then either enters the main UI or displays an error. That is the whole story, and it should be.\u003c/p\u003e","title":"28. Client/Server Signup Process"},{"content":" Module 13: Creating a Facebook Clone\nThis lesson is where the feed finally becomes real. The UI was already structured as though it were loading actual data; now that assumption becomes true.\nThe key simplification is that paging no longer has to be faked on the client. Once the server defines the paging strategy, the client can stop inventing its own timestamp-based workaround and just request the next page. That is a good example of the architecture improving both sides at once: the server owns feed delivery rules, and the client becomes simpler because of it.\nThe new-post form also crosses an important line here. Posting is no longer just a visual action that returns to the previous screen. It now creates a real Post object, sends it to the server, and relies on the backend to add it into the feed. That is the right separation of responsibilities. The client describes what the user wants to publish. The server decides how that content enters the social graph.\nThe note about refresh is also honest and useful. At this stage the feed will not update magically after a new post unless the user refreshes. That is acceptable for now, and it sets up the later discussion about push and more reactive update paths.\nThe friend-list refresh change follows the same pattern. Once user state is cached locally, the app needs a way to refresh it when relationship data changes. Pull-to-refresh becomes the practical bridge between cached identity state and server-side truth.\nFurther Reading 12. The Newsfeed Container 16. The \u0026lsquo;New Post\u0026rsquo; Form 24. PostService 27. Client Side ServerAPI ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/106-29-newsfeed-and-posts-from-server/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/AIsD5MXEK-c?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThis lesson is where the feed finally becomes real. The UI was already structured as though it were loading actual data; now that assumption becomes true.\u003c/p\u003e\n\u003cp\u003eThe key simplification is that paging no longer has to be faked on the client. Once the server defines the paging strategy, the client can stop inventing its own timestamp-based workaround and just request the next page. That is a good example of the architecture improving both sides at once: the server owns feed delivery rules, and the client becomes simpler because of it.\u003c/p\u003e","title":"29. Newsfeed and Posts From Server"},{"content":" Module 13: Creating a Facebook Clone\nThe friends screen becomes much more convincing once it can do something beyond rendering static suggestions. This lesson gives it that capability by wiring contact upload, friend-request actions, and notification refresh into the real backend.\nThe floating action button for contact upload is the most interesting UI move here. Because the friends screen lives inside a tabbed container rather than as a standalone form, adding a FAB is not just a one-line decoration. The lesson has to deal with how Codename One actually wraps containers to place a floating button above them.\nThat is a good example of a recurring theme in the course: when a high-level feature feels awkward, it is often because the underlying container model matters more than it first appeared. Understanding that model lets the app get the exact result it wants without resorting to hacks that would be harder to maintain later.\nThe contact-upload path then turns into real graph growth. By pulling contacts from the device, asking for the minimum useful fields, and sending them to the backend, the app gives the server enough information to improve suggestions and relationship discovery.\nThe accept/remove request flows are also properly tied to UI mutation. Once the server confirms the action, the relevant container is removed and the layout animates into place. That keeps the interface feeling responsive rather than forcing a full-screen reload after every decision.\nThe lesson’s mention of notifications is important too. Once friendship actions can happen for real, notification loading stops being decorative and starts representing actual state changes in the product.\nFurther Reading 13. Friends Container 22. UserService Part II 14. Notifications Container How Do I Use Push Notification / Send Server Push Messages ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/107-30-friends-calendar-synchronization-accept-reject-requests/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/-aTpqxDa1Ag?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe friends screen becomes much more convincing once it can do something beyond rendering static suggestions. This lesson gives it that capability by wiring contact upload, friend-request actions, and notification refresh into the real backend.\u003c/p\u003e\n\u003cp\u003eThe floating action button for contact upload is the most interesting UI move here. Because the friends screen lives inside a tabbed container rather than as a standalone form, adding a FAB is not just a one-line decoration. The lesson has to deal with how Codename One actually wraps containers to place a floating button above them.\u003c/p\u003e","title":"30. Friends - Calendar Synchronization, Accept/Reject Requests"},{"content":" Module 13: Creating a Facebook Clone\nSearch feels like it should be enormous, but a lot of the complexity is hidden if you choose the right backend tooling. This lesson leans on Hibernate Search to add basic full-text capabilities without turning the whole app into a hand-built indexing engine.\nThe most important design decision here is not the library choice. It is deciding what should and should not be searchable. That is a product and privacy decision before it is a technical one.\nThe lesson handles that correctly by indexing only the fields that make sense for public-facing search, such as user names and post text. That is a much healthier default than treating every stored field as fair game just because the search engine can technically index it.\nThe search service then stays relatively small because the heavy lifting is delegated to the indexing layer. Query building, fuzzy matching, and pageable result retrieval become configuration and API choices rather than hand-written SQL gymnastics.\nThat does not mean search is trivial. It means the complexity has moved to a layer designed to absorb it. This is exactly the kind of feature where a framework-backed solution is worth using instead of inventing something clever in application code.\nThe one-time index build is also a useful operational reminder. Search is not just a query problem. It is an indexing lifecycle problem. The system needs a story for the first build and for staying up to date as entities change.\nFurther Reading 32. Search: WebService and Client Code 33. Search: Client Side UI - SearchForm 17. Spring Boot Server Architecture and the User Entity Search Results UI - UserForm and PostForm ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/108-31-search-server-side-with-spring-boot-and-hibernate/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/tWMVUDScyfQ?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eSearch feels like it should be enormous, but a lot of the complexity is hidden if you choose the right backend tooling. This lesson leans on Hibernate Search to add basic full-text capabilities without turning the whole app into a hand-built indexing engine.\u003c/p\u003e","title":"31. Search: Server Side with Spring Boot and Hibernate"},{"content":" Module 13: Creating a Facebook Clone\nOnce the search service exists, the next step is mostly adaptation work: expose it over HTTP, then teach the client API how to consume it without turning search into a special snowflake.\nThat is the best part of this lesson. Search is mapped into the same overall client/server architecture as everything else. It gets endpoints on the server, thin client methods in ServerAPI, and simple pagination rules that match the rest of the app’s data-loading story.\nThe rebuild-search-database endpoint shown in the video is clearly a setup convenience rather than something you would want to expose casually in a production system. The important thing is not the exact hack. It is the operational need it addresses: search sometimes needs an explicit initialization path.\nOn the client side, the generic search method is a nice demonstration of reusing one pattern for several result types. People and posts are different business objects, but from the perspective of transport they are both just paged result lists that need to be converted from JSON into app models.\nThe note about generic erasure is also useful context here. Java generics feel expressive in application code, but at runtime the client often needs an explicit class token or another concrete hint if it wants to instantiate the right object type safely.\nFurther Reading 31. Search: Server Side with Spring Boot and Hibernate 33. Search: Client Side UI - SearchForm 27. Client Side ServerAPI 11. ServerAPI Abstraction Mockup ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/109-32-search-webservice-and-client-code/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/_WKRuO0Izxg?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce the search service exists, the next step is mostly adaptation work: expose it over HTTP, then teach the client API how to consume it without turning search into a special snowflake.\u003c/p\u003e\n\u003cp\u003eThat is the best part of this lesson. Search is mapped into the same overall client/server architecture as everything else. It gets endpoints on the server, thin client methods in \u003ccode\u003eServerAPI\u003c/code\u003e, and simple pagination rules that match the rest of the app’s data-loading story.\u003c/p\u003e","title":"32. Search: WebService and Client Code"},{"content":" Module 13: Creating a Facebook Clone\nThe backend search pipeline is only useful once the UI can take advantage of it, and this lesson does that in the most practical way: a dedicated search form with debounced queries, a mode toggle, and paged results.\nThe debounce logic is the heart of the screen. Search-as-you-type feels great only if it avoids the trap of sending a request on every keystroke. The lesson solves that by tracking recent edits, using a short delay, and cancelling pending work when the user is clearly still typing.\nThat is the right tradeoff. The form remains responsive, the server is not spammed with pointless queries, and the user still experiences search as immediate.\nThe mode switch between people and posts is also handled cleanly. The screen does not need two unrelated search experiences. It needs one search form with a different result builder depending on the current target domain. That keeps the UI simple and keeps the code aligned with the generic search API from the previous lesson.\nUsing an InfiniteContainer for the results is a natural choice because search, like feeds, is a paged result stream. Once the query text and mode are stable, the result list can grow as needed without inventing a separate loading model.\nThe final touch is small but important: putting the editable search field directly in the title area and immediately entering edit mode makes the form feel like a search tool instead of a normal screen that happens to contain a text field.\nFurther Reading 32. Search: WebService and Client Code 34. Search Results UI - UserForm and PostForm 12. The Newsfeed Container Threading and the EDT ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/110-33-search-client-side-ui-searchform/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/sxCADu-SjpQ?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe backend search pipeline is only useful once the UI can take advantage of it, and this lesson does that in the most practical way: a dedicated search form with debounced queries, a mode toggle, and paged results.\u003c/p\u003e\n\u003cp\u003eThe debounce logic is the heart of the screen. Search-as-you-type feels great only if it avoids the trap of sending a request on every keystroke. The lesson solves that by tracking recent edits, using a short delay, and cancelling pending work when the user is clearly still typing.\u003c/p\u003e","title":"33. Search: Client Side UI - SearchForm"},{"content":" Module 13: Creating a Facebook Clone\nSearch is only complete once a result can take you somewhere meaningful. This lesson finishes that loop by giving people and posts their own destination screens.\nThe user result path is the more important one. Clicking a person in search should not just highlight the result or show a tiny detail popup. It should open a screen that behaves like a profile-centric timeline and loads that user’s posts from the backend. That turns search into real navigation instead of a disconnected feature.\nThe lesson wisely keeps the UI around that timeline fairly minimal. The value here is not in cloning every last detail of Facebook’s profile header. It is in proving that the search result can hand off to a live, data-backed screen with the correct feed semantics.\nThe post-result path is even simpler, and that simplicity is fine. A post result already contains most of the interesting content, so the destination screen mainly needs to frame it clearly instead of inventing unnecessary surrounding structure.\nThis is a good example of prioritizing functional completeness over ornamental completeness. A feature becomes credible when the main path works end to end, even if some decorative details are intentionally postponed.\nFurther Reading 33. Search: Client Side UI - SearchForm 29. Newsfeed and Posts From Server 12. The Newsfeed Container 31. Search: Server Side with Spring Boot and Hibernate ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/111-34-search-results-ui-userform-and-postform/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/Rt68rA2c6A8?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eSearch is only complete once a result can take you somewhere meaningful. This lesson finishes that loop by giving people and posts their own destination screens.\u003c/p\u003e\n\u003cp\u003eThe user result path is the more important one. Clicking a person in search should not just highlight the result or show a tiny detail popup. It should open a screen that behaves like a profile-centric timeline and loads that user’s posts from the backend. That turns search into real navigation instead of a disconnected feature.\u003c/p\u003e","title":"34. Search Results UI: UserForm and PostForm"},{"content":" Module 13: Creating a Facebook Clone\nComments are one of those features where technical possibility and product usability diverge quickly. The lesson handles that well by intentionally limiting nesting depth instead of chasing arbitrary thread depth just because the model can support it.\nThat is the right choice here. Infinite nesting looks powerful on paper, but on a phone it quickly becomes hard to read and harder to interact with. A single level of replies captures most of the conversational value without letting the UI collapse into ever-shrinking indentation.\nThe form structure is also sensible. Comments live in a scrollable center area, while the input field and send action stay fixed at the bottom. That keeps the interaction model familiar and lets replying feel immediate instead of hidden behind another screen.\nThe reply flow itself is lightweight: choose a parent comment, remember its ID, and send the new comment to the server with that relationship encoded. Once the response succeeds, the client inserts the new comment into the right place in the visible hierarchy and animates the layout back into a stable state.\nThis is another good example of the course finding the right level of product realism. The comment bubbles, reply action, avatar rendering, and like/comment wiring all make the feature feel real, but the implementation stays small enough that the design decisions are still easy to follow.\nFurther Reading 24. PostService 19. Post and Comment Entities 29. Newsfeed and Posts From Server Layout Animations ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/112-35-threaded-comments-ui-commentsform/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/OnZIaGXDZSo?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eComments are one of those features where technical possibility and product usability diverge quickly. The lesson handles that well by intentionally limiting nesting depth instead of chasing arbitrary thread depth just because the model can support it.\u003c/p\u003e\n\u003cp\u003eThat is the right choice here. Infinite nesting looks powerful on paper, but on a phone it quickly becomes hard to read and harder to interact with. A single level of replies captures most of the conversational value without letting the UI collapse into ever-shrinking indentation.\u003c/p\u003e","title":"35. Threaded Comments UI - CommentsForm"},{"content":" Module 13: Creating a Facebook Clone\nThe settings screen is where the Facebook clone starts feeling personal instead of anonymous. This lesson focuses on the two profile images users care about most: the avatar and the cover.\nThe dedicated ImagePicker helper is a good architectural move. The actual picking behavior is simple right now, but wrapping it in a small class means the metadata, chosen file, preview image, and eventual upload path can stay together. That keeps the settings form from absorbing low-level image-picking concerns directly.\nThe UI itself is mostly about layered composition. Cover image, avatar, and their change buttons need to overlap in a way that looks intentional rather than accidental. The layered-layout approach is a good fit because it lets the form place those controls relative to the images they actually modify.\nThe lesson also keeps a clear distinction between local and remote updates. When the user picks a new image, the UI updates immediately enough to feel responsive, but the backend still receives a real media upload and the user record is updated so the change persists.\nThis is one of the better examples in the course of progressive feature design. The screen does not try to solve every settings problem at once. It gets the most visible identity-editing actions working cleanly, then leaves room for the next lesson to handle more generic profile attributes.\nFurther Reading 37. Generic Settings using InstantUI - Automatic Dynamic UI Generation 39. ImagePicker - Video and Custom Support 40. Edit User - UI Binding and Multipart Image Upload 18. Media Entity ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/113-36-settingsform-cover-and-avatar/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/_JCsyyIH02E?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe settings screen is where the Facebook clone starts feeling personal instead of anonymous. This lesson focuses on the two profile images users care about most: the avatar and the cover.\u003c/p\u003e\n\u003cp\u003eThe dedicated \u003ccode\u003eImagePicker\u003c/code\u003e helper is a good architectural move. The actual picking behavior is simple right now, but wrapping it in a small class means the metadata, chosen file, preview image, and eventual upload path can stay together. That keeps the settings form from absorbing low-level image-picking concerns directly.\u003c/p\u003e","title":"36. SettingsForm - Cover and Avatar"},{"content":" Module 13: Creating a Facebook Clone\nOnce profile editing moves beyond a couple of images, hand-authoring every settings field quickly becomes tedious. This lesson solves that by leaning on InstantUI and property metadata to generate a large part of the editable profile form automatically.\nThat is a strong fit for this problem. User profiles tend to grow over time, and a manually curated form can easily become a maintenance bottleneck. If the underlying property model is already expressive, it makes sense to let the UI derive more from that model instead of forcing every field through handwritten boilerplate.\nThe lesson is also realistic about the limits of automatic UI generation. Some values fit naturally into generated editors. Others, such as birthdays stored in a long-based transport format or constrained choice fields such as gender, need metadata or companion properties so the generated form becomes usable instead of technically correct but awkward.\nThat balance is exactly the right way to think about InstantUI. It is not magic. It is a way to push repetitive form construction down into the model layer while still giving the application room to guide how tricky fields should appear.\nThe unbind-on-exit behavior is another good reminder that generated forms still participate in normal object lifecycles. Automation reduces boilerplate, but it does not remove the need to be explicit about binding scope, saving, and cleanup.\nFurther Reading 36. SettingsForm - Cover and Avatar Properties Are Amazing 21. Service Layer and UserService 40. Edit User - UI Binding and Multipart Image Upload ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/114-37-generic-settings-using-instantui-automatic-dynamic-ui-generation/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/hys6Rpkru50?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eOnce profile editing moves beyond a couple of images, hand-authoring every settings field quickly becomes tedious. This lesson solves that by leaning on InstantUI and property metadata to generate a large part of the editable profile form automatically.\u003c/p\u003e\n\u003cp\u003eThat is a strong fit for this problem. User profiles tend to grow over time, and a manually curated form can easily become a maintenance bottleneck. If the underlying property model is already expressive, it makes sense to let the UI derive more from that model instead of forcing every field through handwritten boilerplate.\u003c/p\u003e","title":"37. Generic Settings using InstantUI - Automatic Dynamic UI Generation"},{"content":" Module 13: Creating a Facebook Clone\nThis lesson takes the existing media and post infrastructure and connects them. That sounds small, but it is the step that turns uploads into actual social content.\nThe most important design choice is that posts do not embed raw media blobs directly. They reference media objects. That keeps the post model lighter, preserves reuse of the media service and entity model, and leaves room for richer attachment behavior later.\nRepresenting attachments to the client as a minimal map of media IDs and MIME types is also a sensible boundary. The client needs enough information to decide how to render or request the media, but it does not need the full internal server-side media object every time it sees a post.\nThe auth-transport compromise called out in the lesson is worth keeping as an architectural warning. Passing authorization as a query parameter can simplify certain client-side URL-based image-loading paths, but it also raises security risks if those URLs are ever logged, shared, or reused carelessly. The tutorial is right to flag that tradeoff instead of pretending it is harmless.\nThe more durable takeaway is that media delivery often forces you to choose between transport convenience and stricter security boundaries. Those tradeoffs should always be explicit.\nFurther Reading 18. Media Entity 23. NotificationService and MediaService 40. Post Media Attachments - Client Side Business Logic 42. Images, Videos and Styled Posts in the Newsfeed ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/115-38-server-side-post-media-attachment/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/Xrolmjg8Dr0?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThis lesson takes the existing media and post infrastructure and connects them. That sounds small, but it is the step that turns uploads into actual social content.\u003c/p\u003e\n\u003cp\u003eThe most important design choice is that posts do not embed raw media blobs directly. They reference media objects. That keeps the post model lighter, preserves reuse of the media service and entity model, and leaves room for richer attachment behavior later.\u003c/p\u003e","title":"38. Server Side Post Media Attachment"},{"content":" Module 13: Creating a Facebook Clone\nAs soon as post attachments stop being image-only, the picker stops being a trivial helper. This lesson expands it into something that can represent either images or videos while still keeping the rest of the app insulated from the exact source of the file.\nThat is the most valuable idea here. The rest of the app should not need one code path for gallery images, another for gallery videos, and yet another for low-level camera captures. A picker abstraction that can carry the chosen file, preview image when applicable, and enough metadata for upload is exactly the right seam.\nThe lesson also makes a pragmatic distinction between images and videos. Images benefit from being decoded, resized, previewed, and cached as UI-ready content. Videos are more transient and more expensive, so the picker mostly needs to preserve file access and enough metadata to upload or preview them sensibly.\nThe custom-factory methods are also useful. Once the app later introduces low-level camera capture, it will already have a way to create a picker-like object from an existing file or byte array without pretending the media came through the ordinary gallery selection path.\nThis is one of those small infrastructure lessons that pays off disproportionally later because it keeps every feature that touches media from reinventing file-source logic on its own.\nFurther Reading 40. Post Media Attachments - Client Side Business Logic 41. Post Image and Video from NewPostForm 43. Low Level Camera Integration How Do I Take a Picture with the Camera ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/116-39-imagepicker-video-and-custom-support/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/wp6gqYLD-XM?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eAs soon as post attachments stop being image-only, the picker stops being a trivial helper. This lesson expands it into something that can represent either images or videos while still keeping the rest of the app insulated from the exact source of the file.\u003c/p\u003e","title":"39. ImagePicker - Video and Custom Support"},{"content":" Module 13: Creating a Facebook Clone\nThis lesson is mostly infrastructure, but it is important infrastructure. Once posts can reference attachments, the client has to stop treating media upload as an invisible prelude and start managing it as a real step in the posting workflow.\nThe first part is straightforward: the post model gains an attachments field so the client can receive and send attachment metadata without special-case parsing.\nThe more important change is in the upload API. If attachments may be large or slow to upload, the client needs access to the underlying request object so it can show upload progress and coordinate posting behavior around that state. Returning a bare callback result is not enough anymore.\nThat is the correct direction. The upload process is no longer just a helper that vanishes into the background. It is now part of the user-visible experience, and the UI needs hooks for progress, enablement, and error handling.\nThe lesson also highlights a very practical detail: sometimes the app has raw bytes, and sometimes it only has a file path. The API layer should make room for both instead of forcing every caller to normalize the data in exactly the same way before it can upload anything.\nFurther Reading 41. Post Image and Video from NewPostForm 39. ImagePicker - Video and Custom Support 16. The \u0026lsquo;New Post\u0026rsquo; Form 18. Media Entity ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/117-40-post-media-attachments-client-side-business-logic/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/H7WW4GwXK8o?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThis lesson is mostly infrastructure, but it is important infrastructure. Once posts can reference attachments, the client has to stop treating media upload as an invisible prelude and start managing it as a real step in the posting workflow.\u003c/p\u003e","title":"40. Post Media Attachments - Client Side Business Logic"},{"content":" Module 13: Creating a Facebook Clone\nThis is where the post composer stops being text-only and starts behaving like a real social composer. That means it has to own more state: attachment ID, MIME type, upload progress, and whether the post action is currently safe to enable.\nThe lesson handles that by moving from one generic constructor to factory-style entry points for different composer modes. That is a good shift. Once the UI for image posts, video posts, and plain text posts begins to diverge, pretending they are all the same setup path just makes the form harder to reason about.\nDisabling the post action until the upload completes is one of the most important UX details here. Without that guard, the user could create references to media that has not actually finished uploading yet. The composer needs to make that state visible and enforce it, not just hope the timing works out.\nThe upload progress overlay is also well chosen. The user can see the attachment they are about to post, but the UI still makes it clear that something is happening before the post can be sent. That keeps the composer feeling responsive without lying about completion.\nThe lesson also calls out the orphan-media problem when a user abandons the form after uploading but before posting. That is a real systems concern, and it is good that the tutorial surfaces it instead of pretending uploads only succeed in neat end-to-end flows. The app still needs a cleanup story even if the lesson defers the implementation.\nFurther Reading 40. Post Media Attachments - Client Side Business Logic 42. Images, Videos and Styled Posts in the Newsfeed 39. ImagePicker - Video and Custom Support 16. The \u0026lsquo;New Post\u0026rsquo; Form ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/118-41-post-image-and-video-from-newpostform/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/U0Ms65vcVr4?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThis is where the post composer stops being text-only and starts behaving like a real social composer. That means it has to own more state: attachment ID, MIME type, upload progress, and whether the post action is currently safe to enable.\u003c/p\u003e","title":"41. Post Image and Video from NewPostForm"},{"content":" Module 13: Creating a Facebook Clone\nSupporting media in the composer is only half the story. The feed also needs to render those posts convincingly, otherwise the richer posting flow disappears as soon as the user returns to the timeline.\nThis lesson closes that gap by teaching NewsfeedContainer how to display images, videos, and the styled-text post variants that earlier lessons allowed users to create.\nThe media rendering path is pragmatic. Images are loaded through URL-based media retrieval, while videos are embedded with a size override so they remain visually usable in the feed regardless of the original media dimensions. That is exactly the sort of feed-specific presentation logic the timeline should own.\nThe lesson is also honest that proper media delivery is a much bigger subject. Real production systems usually transcode video, tailor formats by client capabilities, and optimize bandwidth more aggressively. The simplified approach here is acceptable as long as it is understood as a working foundation rather than a final media pipeline.\nThe styled-post fixes are just as important. Earlier in the module, style choices existed conceptually, but the feed had not fully respected them. Once rich text and UIID-aware styling are wired together properly, styled posts stop being just a composer novelty and become part of the visible product language.\nFurther Reading 41. Post Image and Video from NewPostForm 12. The Newsfeed Container 16. The \u0026lsquo;New Post\u0026rsquo; Form 18. Media Entity ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/119-42-images-videos-and-styled-posts-in-the-newsfeed/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/M518p4_Horg?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eSupporting media in the composer is only half the story. The feed also needs to render those posts convincingly, otherwise the richer posting flow disappears as soon as the user returns to the timeline.\u003c/p\u003e\n\u003cp\u003eThis lesson closes that gap by teaching \u003ccode\u003eNewsfeedContainer\u003c/code\u003e how to display images, videos, and the styled-text post variants that earlier lessons allowed users to create.\u003c/p\u003e","title":"42. Images, Videos and Styled Posts in the Newsfeed"},{"content":" Module 13: Creating a Facebook Clone\nCamera support is one of those features that can swallow an entire project if you let it. This lesson avoids that trap by aiming for a useful capture path rather than a complete camera application.\nThe structure is sensible. If the richer camera library is available, the app uses it. If not, it falls back to the simpler capture API. That gives the feature a wider operating range without forcing the rest of the app to care about which capture path was used on a given device.\nThe custom camera form is also kept intentionally narrow. It shows the viewport, allows image capture, and hands the result off to the existing media-posting flow. It does not try to solve video recording, flash control, zoom, or every nuance of device photography. That is the right scope for a lesson whose real purpose is integration, not camera-app design.\nWhat matters here is that capture now plugs into the same picker and new-post abstractions built in the previous lessons. The app is not branching into an entirely separate posting flow for camera-originated media. It is reusing the same upload and composer pipeline with a different acquisition source.\nThat is a strong finish to this feature arc. Gallery selection, media upload, feed rendering, and live capture all converge on one posting model instead of growing as disconnected special cases.\nFurther Reading 39. ImagePicker - Video and Custom Support 41. Post Image and Video from NewPostForm 42. Images, Videos and Styled Posts in the Newsfeed How Do I Take a Picture with the Camera ","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/120-43-low-level-camera-integration/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/cZiHmpw2FVI?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eCamera support is one of those features that can swallow an entire project if you let it. This lesson avoids that trap by aiming for a useful capture path rather than a complete camera application.\u003c/p\u003e\n\u003cp\u003eThe structure is sensible. If the richer camera library is available, the app uses it. If not, it falls back to the simpler capture API. That gives the feature a wider operating range without forcing the rest of the app to care about which capture path was used on a given device.\u003c/p\u003e","title":"43. Low Level Camera Integration"},{"content":" Module 13: Creating a Facebook Clone\nTranscript this is probably the easiest section in terms of materials but since push is always such a hassle it could possibly take you the most to complete i chose to use push for all the server originating communications which has its drawbacks a better strategy might have been combination of push and web sockets but in the interest of brevity i chose to go with push alone as i demonstrated web sockets enough and we\u0026rsquo;ll go back to them in the future push notification allows us to send notification to a device while the application might be in the background this is important both as a marketing tool and as a basic communications service polling the server seems like a sensible time proven strategy however there are many complexities related to that approach in mobile phones the biggest problem is that polling application will be killed by the os as it is sent to the background to conserve os resources while this might work in some os\u0026rsquo;s and some cases this isn\u0026rsquo;t something you can rely on for instance android 6 plus tightened the background process behavior significantly the other issue is battery life new os\u0026rsquo;s exposed battery wasting applications and as a result my trigger uninstalls this makes even foreground polling less appealing if you are new to mobile development then you heard a lot of the buzzwords and very little substance the problem is that ios and android have very different ideas of what push is and should be for android push is a communication system that the server can initiate for instance the cloud can send any packet of data and the device can process it in rather elaborate ways for ios pushes mostly a visual notification triggered by the server to draw attention to new information inside an app these don\u0026rsquo;t sound very different until you realize that in android you can receive slash process a push without the awareness of the end user in ios a push notification is displayed to the user but the app might be unaware of it this is important ios will only deliver the push notification to the app if it is running or if the user clicked the push notification pop-up codename one tries to make both os\u0026rsquo;s feel similar so background push calls act the same in ios and android as a result you shouldn\u0026rsquo;t push important data push is lossy and shouldn\u0026rsquo;t include a payload that must arrive instead use push as a flag to indicate that the server has additional data for the app to fetch for this case we use push to let the app know about an update it then performs a refresh to fetch the actual data with the usual web services before we proceed i think it\u0026rsquo;s a good time to discuss the various types of push messages zero or one is the default push type they work everywhere and present the string as the push alert to the user two is hidden non-visual push this won\u0026rsquo;t show any visual indicator on any os in android this will trigger the push string call with the message body in ios this will only happen if the application is in the foreground otherwise the push will be lost three allows combining a visual push with a non-visual portion expect a message in the form of this is what the user won\u0026rsquo;t see semicolon this is something he will see for instance you can bundle a special id or even a json string in the hidden part while including a friendly message in the visual part when active this will trigger the push string method twice once with the visual and once with the hidden data notice that if the push arrives when the app is in the background on ios and the user doesn\u0026rsquo;t tap the notification neither one of the messages will be received by the app 4 allows splitting the visual push request based on the format title uh semicolon body to provide better visual representation and some os\u0026rsquo;s five sends a regular push message but doesn\u0026rsquo;t play a sound when the push arrives 100 sets the number badge it\u0026rsquo;s applicable only to ios it allows setting a numeric badge on the icon to the given number the body of the message must be a number for instance unread count 101 is identical to 100 with an added message payload separated with a space for instance 30 space you have 30 unread messages we\u0026rsquo;ll set the badge to 30 and present the push notification text you have 30 unread messages this again is ios only we need some values from google and apple to fill fb clone keys properties these values help us send the push through the apple google servers we need the following keys in that properties file notice i will go into the process of obtaining each of those soon push.itunes production is true or false ios push calls target either the production or the development servers push itunes prod cert don\u0026rsquo;t confuse this with a certificate used for app signing this is a separate certificate used for authenticating against apple\u0026rsquo;s push servers you need to host it in the cloud we do that for you if you use the certificate wizard push dot itunes prod pass this is the password for push itunes prod cert certificate push itunes devcert just like with the code signing we have two certificates so this one is used when we are pushing in the sandbox during development this is used when push itunes production is set to false push token sorry push itunes dev pass this is the password for the push itunes dev cert certificate push token this is a secure token you can fetch from your codename one account in the settings tab push.gcm key this is the value you need to fetch from google developer tools console android push goes to google servers and to do that we need to register with google to get keys for the server usage you need one important value push.gcm key to generate this value follow these steps login to console.cloud.google.com select apis and services select library select developer tools select google cloud messaging click enable and follow the instructions the value we need is the api key which you can see under the credentials entry you will need to rerun the certificate wizard for the project for ios if you generated certificates before say no to the set step that asks you to revoke them and copy your existing credentials certificate p12 file and password to the new project make sure to check the include push flag in the wizard so the generated provisioning includes push data once this is done you should receive an email that includes the certificate details this will include urls for the push certificate we generated for you and the passwords for those certificates apple has two push servers sandbox use this during development production this will only work for shipping apps you need to toggle the push.itunes production flag so push messages go to the production version of the app now that we understood the theory let\u0026rsquo;s go into the practical terms of sending push notifications from the server the first step is in the user entity we need to access the device push key so we can send a push message to the user\u0026rsquo;s device that\u0026rsquo;s it well almost there are also getters and setters but i always ignore those anyway this isn\u0026rsquo;t in the dow so there is no boiler plate there the push key is private to the server it has no place in the dial so we leave it there here we do however need to add a method to the user repository interface we need this finder to remove out of date and expired push keys based on messages sent from the push server we need to expose the properties that we added to the fb clone keys properties file in the notification service bin my first intuition was to inject the user service into the notification service class this failed the reason it failed is circular references user service already references notification service so including user service there would mean spring boot would need to create user service create notification service to inject into user service create a user service to inject into the notification service etc thankfully it fails quickly with an error the solution itself is pretty simple though we add a new service that will handle this api keys we removed this code from user service as it is as is and placed it here these two helper methods remove the need to use api keys variables directly the next step is injecting this into both user service and notification service i\u0026rsquo;ll demonstrate this in the notification service but the change to user service is same i\u0026rsquo;ll get to the surrounding method soon but for now i just wanted to show how to use this new api to get the values from the properties file so all we need to do is replace every call to prop.getproperty with keys.get that\u0026rsquo;s also far more flexible and elegant in the future we can probably use a smarter system for configuration than a properties file now that it\u0026rsquo;s encapsulated\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/121-44-push-notification-theory-entity-and-service-layers/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/LFoSl_a2rs8?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ethis is probably the easiest section in\nterms of materials but since push is\nalways such a hassle it could possibly\ntake you the most to complete\ni chose to use push for all the server\noriginating communications which has its\ndrawbacks a better strategy might have\nbeen combination of push and web sockets\nbut in the interest of brevity i chose\nto go with push alone as i demonstrated\nweb sockets enough and we\u0026rsquo;ll go back to\nthem in the future\npush notification allows us to send\nnotification\nto a device while the application might\nbe in the background\nthis is important both as a marketing\ntool and as a basic communications\nservice\npolling the server seems like a sensible\ntime proven strategy\nhowever there are many complexities\nrelated to that approach in mobile\nphones\nthe biggest problem is that polling\napplication\nwill be killed by the os as it is sent\nto the background to conserve os\nresources\nwhile this might work in some os\u0026rsquo;s and\nsome cases this isn\u0026rsquo;t something you can\nrely on for instance android 6 plus\ntightened the background process\nbehavior significantly\nthe other issue\nis\nbattery life\nnew os\u0026rsquo;s exposed battery wasting\napplications and as a result my trigger\nuninstalls\nthis makes even foreground polling less\nappealing\nif you are new to mobile development\nthen you heard a lot of the buzzwords\nand very little substance\nthe problem is that ios and android have\nvery different ideas of what push is and\nshould be\nfor android push is a communication\nsystem that the server can initiate for\ninstance the cloud can send any packet\nof data and the device can process it\nin rather elaborate ways\nfor ios pushes mostly a visual\nnotification triggered by the server to\ndraw attention to new information inside\nan app\nthese don\u0026rsquo;t sound very different until\nyou realize that in android you can\nreceive slash process a push without the\nawareness of the end user\nin ios a push notification is displayed\nto the user but the app might be unaware\nof it\nthis is important ios will only deliver\nthe push notification to the app\nif it is running or if the user clicked\nthe push notification pop-up\ncodename one tries to make both os\u0026rsquo;s\nfeel similar so background push calls\nact the same in ios and android as a\nresult\nyou shouldn\u0026rsquo;t push important data\npush is lossy\nand shouldn\u0026rsquo;t include a payload that\nmust arrive\ninstead use push as a flag to indicate\nthat the server has additional data\nfor the app to fetch\nfor this case we use push to let the app\nknow about an update\nit then performs a refresh to fetch the\nactual data with the usual web services\nbefore we proceed i think it\u0026rsquo;s a good\ntime to discuss the various types of\npush messages\nzero or one\nis the default push type\nthey work everywhere and present the\nstring as the push alert to the user\ntwo is hidden non-visual push\nthis won\u0026rsquo;t show any visual indicator on\nany os\nin android this will trigger the push\nstring call with the message body in ios\nthis will only happen if the application\nis in the foreground otherwise the push\nwill be lost\nthree allows combining a visual push\nwith a non-visual portion\nexpect a message in the form of this is\nwhat the user won\u0026rsquo;t see\nsemicolon this is something he will see\nfor instance you can bundle a special id\nor even a json string in the hidden part\nwhile including a friendly message in\nthe visual part\nwhen active this will trigger the push\nstring method twice once with the visual\nand once with the hidden data\nnotice that if the push arrives when the\napp is in the background on ios and the\nuser doesn\u0026rsquo;t tap the notification\nneither one of the messages will be\nreceived by the app\n4 allows splitting the visual push\nrequest based on the format title\nuh semicolon body to provide better\nvisual representation and some os\u0026rsquo;s\nfive sends a regular push message but\ndoesn\u0026rsquo;t play a sound when the push\narrives\n100 sets the number badge\nit\u0026rsquo;s applicable only to ios it allows\nsetting a numeric badge on the icon to\nthe given number\nthe body of the message must be a number\nfor instance unread count\n101 is identical to 100 with an added\nmessage payload separated with a space\nfor instance 30 space you have 30 unread\nmessages\nwe\u0026rsquo;ll set the badge to 30 and present\nthe push notification text you have 30\nunread messages\nthis again is ios only\nwe need some values from google and\napple to fill fb clone keys properties\nthese values help us send the push\nthrough the apple google servers\nwe need the following keys in that\nproperties file notice i will go into\nthe process of obtaining each of those\nsoon\npush.itunes production\nis true or false\nios push calls target\neither the production or the development\nservers\npush itunes prod cert\ndon\u0026rsquo;t confuse\nthis with a certificate used for app\nsigning\nthis is a separate certificate used for\nauthenticating against apple\u0026rsquo;s push\nservers you need to host it in the cloud\nwe do that for you if you use the\ncertificate wizard\npush dot itunes prod pass this is the\npassword for push itunes prod cert\ncertificate\npush itunes devcert just like with the\ncode signing we have two certificates so\nthis one is used when we are pushing in\nthe sandbox during development\nthis is used when push itunes production\nis set to false\npush token\nsorry push\nitunes dev pass\nthis is the password\nfor the push itunes dev cert certificate\npush token this is a secure token you\ncan fetch from your codename one account\nin the settings tab\npush.gcm key this is the value you need\nto fetch from google developer tools\nconsole\nandroid push goes to google servers\nand to do that we need to register with\ngoogle to get keys for the server usage\nyou need one important value push.gcm\nkey\nto generate this value follow these\nsteps\nlogin to\nconsole.cloud.google.com\nselect apis and services\nselect library\nselect developer tools\nselect google cloud messaging\nclick enable\nand follow the instructions\nthe value we need is the api key which\nyou can see under the credentials entry\nyou will need to rerun the certificate\nwizard for the project for ios\nif you generated certificates before\nsay no to the set step that asks you to\nrevoke them and copy your existing\ncredentials certificate p12 file and\npassword to the new project\nmake sure to check the include push flag\nin the wizard so the generated\nprovisioning includes push data once\nthis is done you should receive an email\nthat includes the certificate details\nthis will include urls for the push\ncertificate we generated for you and the\npasswords for those certificates\napple has two push servers sandbox use\nthis during development production this\nwill only work for shipping apps\nyou need to toggle the push.itunes\nproduction flag so push messages go to\nthe production version of the app\nnow that we understood the theory let\u0026rsquo;s\ngo into the practical terms of sending\npush notifications from the server\nthe first step is in the user entity we\nneed to access the device push key so we\ncan send a push message to the user\u0026rsquo;s\ndevice\nthat\u0026rsquo;s it\nwell almost\nthere are also getters and setters but i\nalways ignore those anyway\nthis isn\u0026rsquo;t in the dow so there is no\nboiler plate there the push key is\nprivate to the server it has no place in\nthe dial so we leave it\nthere here\nwe do however need to add a method to\nthe user repository interface we need\nthis finder to remove out of date and\nexpired push keys based on messages sent\nfrom the push server\nwe need to expose the properties that we\nadded to the fb clone keys properties\nfile in the notification service bin\nmy first intuition was to inject the\nuser service into the notification\nservice class\nthis failed\nthe reason it failed is circular\nreferences\nuser service already references\nnotification service so including user\nservice there\nwould mean spring boot would need to\ncreate user service create notification\nservice to inject into user service\ncreate a user service to inject into the\nnotification service\netc\nthankfully it fails quickly with an\nerror\nthe solution itself is pretty simple\nthough\nwe add a new service that will handle\nthis api keys\nwe removed this code from user service\nas it is as is and placed it here\nthese two helper methods remove the need\nto use api keys variables directly\nthe next step is injecting this into\nboth user service and notification\nservice\ni\u0026rsquo;ll demonstrate this in the\nnotification service but the change to\nuser service is same\ni\u0026rsquo;ll get to the surrounding method soon\nbut for now i just wanted to show how to\nuse this new api to get the values from\nthe properties file\nso all we need to do is replace every\ncall to prop.getproperty\nwith\nkeys.get that\u0026rsquo;s also far more flexible\nand elegant in the future we can\nprobably use a smarter system for\nconfiguration than a properties file\nnow that it\u0026rsquo;s encapsulated\u003c/p\u003e","title":"44. Push Notification - Theory, Entity and Service Layers"},{"content":" Module 13: Creating a Facebook Clone\nTranscript the changes to the notification service are significant and in effect that\u0026rsquo;s the class that implements push notification calls from the server before we start we need to add a few fields to the class these will be used by the code we introduced soon these are besides the keys field i mentioned before this is the url of the codename one push server we\u0026rsquo;ll use that to send out push messages logging is used for errors in the body of the class we need to inject the user\u0026rsquo;s repository now as we need to find the user there the first step is trivial it\u0026rsquo;s about mapping the push key to the service class which is exactly what we do here on push registration we invoke this method to update the push key in the user object if the push server indicates that a push key is invalid or expired we delete that key a fresh key will be created the next time the user runs the app the second method is internal to the server and isn\u0026rsquo;t exposed as a web service but the former method is the next stage is the push notification itself we add these lines to the send notification method notice that a push key can be null since it can expire or might not be registered yet this leads us to the send push notification method but we\u0026rsquo;ll get there via detour this method is based on the server push code from the developer guide notice that this is the import method not the method we invoked before we\u0026rsquo;ll go through this first and then reach that code we connect to the push server url to send the push message a standard form post submission request is used we fetch the values for the fields that can defer specific specifically the certificate and passwords which vary between production and development we send all the details as a post request to the codename one push server which then issues a push to the given device type the server can return 200 in case of an error but if the response isn\u0026rsquo;t 200 then it\u0026rsquo;s surely an error the server response is transformed to a string for passing on the next method i\u0026rsquo;ll cover the read input stream method soon we need to go over the responses from the push server these responses would include information such as push key expiration and we would need to purge that key from our database that\u0026rsquo;s all done in the actual method for sending push messages the async annotation indicates this method should execute on a separate thread this is handled by spring we\u0026rsquo;ll discuss that soon senpush impul returns json with messages which we need to process the spring json parsing api has different forms for map list but we can get both in the response from the server so we need to check if it\u0026rsquo;s a list then it\u0026rsquo;s a device list with either acknowledgement of sending for android only or error messages if we have an error message for a specific device key we need to remove it to prevent future problems with the push servers if we got a map in response it could indicate an error which we currently don\u0026rsquo;t really handle other than through logging if push doesn\u0026rsquo;t work the app would still work fine you\u0026rsquo;ll just need to refresh manually a better implementation would also use a fallback for cases of push failure for instance websocket but it\u0026rsquo;s not essential at least not at first we referenced read input stream in the previous code blocks it\u0026rsquo;s defined in the code as such i could have written more modern code using nio but i was running out of time and i had this code handy it does the job well next we expose the push registration method as a restful web service this is a direct mapping to the update method so there isn\u0026rsquo;t much to say about that the last piece of the server code is the changes we need to make to the facebook clone server application class we didn\u0026rsquo;t touch that class at all when we started off but now we need some changes to support the asynchronous send push notification method first we need the at enable async annotation so at async will work in the app the at bin for the async executor creates the thread pool used when we invoke an at async method we define reasonable capacities we don\u0026rsquo;t want an infinite queue as we can run out of ram and it can be used in a denial of service attack we also don\u0026rsquo;t want too many threads in the pool as our server might overcrowd the push servers and receive rate limits this level should work fine with that the server side portion of the push support is done\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/122-45-push-notification-server-implementation/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/5WpZmIkdUfs?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ethe changes to the notification service\nare significant and in effect that\u0026rsquo;s the\nclass that implements push notification\ncalls from the server\nbefore we start we need to add a few\nfields to the class\nthese will be used by the code we\nintroduced soon\nthese are besides the keys field i\nmentioned before\nthis is the url of the codename one push\nserver we\u0026rsquo;ll use that to send out push\nmessages\nlogging is used for errors in the body\nof the class\nwe need to inject the user\u0026rsquo;s repository\nnow as we need to find the user there\nthe first step is trivial\nit\u0026rsquo;s about mapping the push key to the\nservice class which is exactly what we\ndo here\non push registration we invoke this\nmethod to update the push key in the\nuser object\nif the push server indicates that a push\nkey is invalid or expired we delete that\nkey\na fresh key will be created the next\ntime the user runs the app\nthe second method is internal to the\nserver and isn\u0026rsquo;t exposed as a web\nservice but the former method is\nthe next stage is the push notification\nitself\nwe add these lines to the send\nnotification method\nnotice that a push key can be null since\nit can expire or might not be registered\nyet\nthis leads us to the send push\nnotification method\nbut we\u0026rsquo;ll get there via detour\nthis method is based on the server push\ncode from the developer guide notice\nthat this is the import method not the\nmethod we invoked before\nwe\u0026rsquo;ll go through this first and then\nreach that code\nwe connect to the push server url to\nsend the push message\na standard form post submission request\nis used\nwe fetch the values for the fields that\ncan defer specific\nspecifically the certificate and\npasswords\nwhich vary between production and\ndevelopment\nwe send all the details as a post\nrequest to the codename one push server\nwhich then issues a push to the given\ndevice type\nthe server can return 200 in case of an\nerror\nbut if the response isn\u0026rsquo;t 200 then it\u0026rsquo;s\nsurely an error\nthe server response is transformed to a\nstring for passing on the next method\ni\u0026rsquo;ll cover the read input stream method\nsoon\nwe need to go over the responses from\nthe push server these responses would\ninclude information such as push key\nexpiration\nand we would need to\npurge that key from our database\nthat\u0026rsquo;s all done in the actual method for\nsending push messages\nthe async annotation indicates this\nmethod should execute on a separate\nthread this is handled by spring we\u0026rsquo;ll\ndiscuss that soon\nsenpush impul returns json with messages\nwhich we need to process\nthe spring json parsing api has\ndifferent forms for map\nlist\nbut we can get both in the response from\nthe server so we need to check\nif it\u0026rsquo;s a list then it\u0026rsquo;s a device list\nwith either acknowledgement of sending\nfor android only or error messages\nif we have an error message for a\nspecific device key we need to remove it\nto prevent future problems with the push\nservers\nif we got a map in response it could\nindicate an error which we currently\ndon\u0026rsquo;t really handle other than through\nlogging\nif push doesn\u0026rsquo;t work the app would still\nwork fine you\u0026rsquo;ll just need to refresh\nmanually a better implementation would\nalso use a fallback for cases of push\nfailure for instance websocket but it\u0026rsquo;s\nnot essential at least not at first\nwe referenced read input stream\nin the previous code blocks\nit\u0026rsquo;s defined in the code as such\ni could have written\nmore modern code using nio but i was\nrunning out of time and i had this code\nhandy it does the job well\nnext we expose the push registration\nmethod as a restful web service\nthis is a direct mapping to the update\nmethod so there isn\u0026rsquo;t much to say about\nthat\nthe last piece of the server code is the\nchanges we need to make to the facebook\nclone server application class\nwe didn\u0026rsquo;t touch that class at all when\nwe started off but now we need\nsome changes to support the asynchronous\nsend push notification method\nfirst we need the at enable async\nannotation so at async will work in the\napp\nthe at bin for the async executor\ncreates the thread pool used when we\ninvoke an at async method\nwe define reasonable capacities\nwe don\u0026rsquo;t want an infinite queue as we\ncan run out of ram and it can be used in\na denial of service attack\nwe also don\u0026rsquo;t want too many threads in\nthe pool as our server might overcrowd\nthe push servers and receive rate limits\nthis level\nshould work fine\nwith that the server side portion of the\npush support is done\u003c/p\u003e","title":"45. Push Notification - Server Implementation"},{"content":" Module 13: Creating a Facebook Clone\nTranscript it\u0026rsquo;s now time to map the push support into the client side to do that we need to implement the push callback interface in the main class of our app we can only implement push callback in the main class nowhere else register push should be invoked with every launch to refresh the push key as it might change we use call serially to defer this so we don\u0026rsquo;t block the start method the push method is invoked with the text of the push in that case we call the refresh method to update the ui we\u0026rsquo;ll discuss that method soon the device id isn\u0026rsquo;t the push key it\u0026rsquo;s the os native push value normally you would have no need for it as it\u0026rsquo;s here for compatibility only the push key value is only guaranteed once this callback is invoked if the push key changed since the last time we update the push key in the server we\u0026rsquo;ll cover this method soon there isn\u0026rsquo;t much we can do in the case of an error so right now i only log it in some cases you can show a ui notification but make sure not to do it from this method as it\u0026rsquo;s invoked early in the app launch cycle and that might impact the ui in odd ways just store the error details and show a notice later on next we need to cover the server api changes and refresh method we\u0026rsquo;ll start with the former in the sign up or login method of the server api we need to invoke register push after the successful login this is important for the first time the user logs in to the app next we need to map the update push key method this is just a simple call with one argument we return a boolean value to indicate that the call worked that\u0026rsquo;s it ui controller needs a bit of work too first we need to add a field for the main form instance this will allow us to refresh the main form as notifications come in the method is now updated this method is now updated with the new main field so we can refresh the ui refresh delegates into the main form instance it\u0026rsquo;s possible that the push method is invoked before loading completed so main would be null in that case this isn\u0026rsquo;t a problem since main would be created with fresh data anyway again with mainform we need to take fields that were in the constructor before and move them to the class level so we can refresh them once we went through that with the refresh method is easy if we are currently viewing the news feed and we aren\u0026rsquo;t minimized a refresh might create a bad user experience if we are minimized or in a different tab we can refresh the ui immediately this refresh method is from infinite container the same logic applies to the notification code this method shows a toast bar offering the user a refresh if he taps the toast bar we use this to prompt the user instead of refreshing automatically with that push should work and refresh when applicable\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/123-46-push-client-side-integration/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 13: Creating a Facebook Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/GEzM1MXkqnk?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003eit\u0026rsquo;s now time to map the push support\ninto the client side\nto do that we need to implement the push\ncallback interface in the main class of\nour app\nwe can only implement push callback in\nthe main class\nnowhere else\nregister push should be invoked with\nevery launch to refresh the push key as\nit might change\nwe use call serially to defer this\nso we don\u0026rsquo;t block the start method\nthe push method is invoked with the text\nof the push\nin that case we call the refresh method\nto update the ui\nwe\u0026rsquo;ll discuss that method soon\nthe device id isn\u0026rsquo;t the push key\nit\u0026rsquo;s the os native push value\nnormally you would have no need for it\nas it\u0026rsquo;s here for compatibility only\nthe push key value is only guaranteed\nonce this callback is invoked\nif the push key changed since the last\ntime we update the push key in the\nserver\nwe\u0026rsquo;ll cover this method soon\nthere isn\u0026rsquo;t much\nwe can do in the case of an error so\nright now i only log it\nin some cases you can show a ui\nnotification but make sure not to do it\nfrom this method as it\u0026rsquo;s invoked early\nin the app launch cycle and that might\nimpact the ui in odd ways\njust store the error details and show a\nnotice later on\nnext we need to cover the server api\nchanges and refresh method\nwe\u0026rsquo;ll start with the former\nin the sign up or login method of the\nserver api\nwe need to invoke register push after\nthe successful login\nthis is important for the first time the\nuser logs in to the app\nnext we need to map the update push key\nmethod\nthis is just a simple call with one\nargument\nwe return a boolean value to indicate\nthat the call worked that\u0026rsquo;s it\nui controller needs a bit of work too\nfirst we need to add a field for the\nmain form instance\nthis will allow us to refresh the main\nform as notifications come in\nthe method is now updated\nthis method is now updated with the new\nmain field so we can refresh the ui\nrefresh delegates into the main form\ninstance\nit\u0026rsquo;s possible that the push method is\ninvoked before loading completed so main\nwould be null\nin that case this isn\u0026rsquo;t a problem since\nmain would be created with fresh data\nanyway\nagain with mainform we need to take\nfields that were in the constructor\nbefore and move them to the class level\nso we can refresh them\nonce we went through that with the\nrefresh method is easy\nif we are currently viewing the news\nfeed\nand we\naren\u0026rsquo;t minimized a refresh might create\na bad user experience\nif we are minimized or in a different\ntab we can refresh the ui immediately\nthis refresh method is from infinite\ncontainer\nthe same logic applies to the\nnotification code\nthis method shows a toast bar offering\nthe user a refresh if he taps the toast\nbar\nwe use this to prompt the user instead\nof refreshing automatically\nwith that push should work and refresh\nwhen applicable\u003c/p\u003e","title":"46. Push - Client Side Integration"},{"content":" Module 14: Creating a WhatsApp Clone\nTranscript in this module we\u0026rsquo;ll build a rudimentary whatsapp clone i\u0026rsquo;ll take a very different path when compared to previous cloned applications here we\u0026rsquo;ll talk about that and these things in the next few slides the first thing i\u0026rsquo;d like to go into is that this clone isn\u0026rsquo;t pixel perfect it\u0026rsquo;s a fast and dirty clone i\u0026rsquo;ll focus only on the basic text sending functionality and won\u0026rsquo;t go into nearly as much as detail as i did in the other clones frankly it\u0026rsquo;s not necessary the functionality is simple once you understand the facebook clone i skipped a lot of the core features mostly due to time but also because these features are covered in the facebook clone and re-implementing them for yet another clone would have been redundant i\u0026rsquo;ll only focus on these forms i won\u0026rsquo;t implement everything here either since we already implemented sms verification in the facebook loan i\u0026rsquo;ll use the sms activation library however i\u0026rsquo;ll use server side authentication for that library for extra security whatsapp doesn\u0026rsquo;t use passwords i considered using the phone number as the id which seems to be what they are doing i ended up using a regular id though there is an authorization token which i will discuss later like other clones i use spring boot again that makes this familiar and allows me to grab some code from the other projects the database will read mysql again for the same reason i\u0026rsquo;ll store data as json locally instead of sqlite this makes it easy to use and debug the code that might be something worth changing if you are building this for scale i\u0026rsquo;m still using web services for most of the functionality they are still easier to work with than web sockets however messaging is the ideal use case for websockets and i\u0026rsquo;m using it for that exact purpose when the websocket is closed which would happen if the app isn\u0026rsquo;t running or is minimized i use push push is used strictly as a visual medium to notify the user of a new message when sending and receiving data in websockets i use json in the past i used a binary websocket and i wanted to show how this approach works as well so let\u0026rsquo;s start by creating the spring boot project for the server i\u0026rsquo;m assuming you went through the previous modules and i won\u0026rsquo;t repeat myself too much you can use the spring boot initializer which i used to create this pom file i just defined a new project with this package for java 8. we\u0026rsquo;ll use jpa to communicate with the mysql database we use jersey for pojo json serialization the security package allows us to encrypt credentials into the database it has a lot of other features but they aren\u0026rsquo;t as useful for us we need web services support too and web sockets to implement the full communication protocol the underlying database is mysql so we need the right drivers for that and finally we need the server side twillow library to implement sms support on the server this will be used for the activation code functionality next we need to create the client application which i create as whatsapp clone i use the default native and bare bones settings in the ide i pick the com codename1.whatsapp package nothing special next we\u0026rsquo;ll go into the classes that implement the client functionality\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/124-1-getting-started/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 14: Creating a WhatsApp Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/fJD45Mz8SZM?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ein this module we\u0026rsquo;ll build a rudimentary\nwhatsapp clone\ni\u0026rsquo;ll take a very different path when\ncompared to previous cloned applications\nhere\nwe\u0026rsquo;ll talk about that and\nthese things in the next few slides\nthe first thing i\u0026rsquo;d like to go into is\nthat this clone isn\u0026rsquo;t pixel perfect\nit\u0026rsquo;s a fast and dirty clone\ni\u0026rsquo;ll focus only on the basic text\nsending functionality\nand won\u0026rsquo;t go into\nnearly as much as detail as i did in the\nother clones\nfrankly it\u0026rsquo;s not necessary\nthe functionality is simple once you\nunderstand the facebook clone\ni skipped a lot of the core features\nmostly due to time\nbut also because these features are\ncovered in the facebook clone and\nre-implementing them for yet another\nclone would have been redundant\ni\u0026rsquo;ll only focus on these forms i won\u0026rsquo;t\nimplement everything here either\nsince we already implemented sms\nverification in the facebook loan i\u0026rsquo;ll\nuse the sms activation library however\ni\u0026rsquo;ll use server side authentication for\nthat library for extra security\nwhatsapp doesn\u0026rsquo;t use passwords\ni considered using the phone number as\nthe id which seems to be what they are\ndoing i ended up using a regular id\nthough there is an authorization token\nwhich i will discuss later\nlike other clones i use spring boot\nagain that makes this familiar and\nallows me to grab some code from the\nother projects the database will read\nmysql again for the same reason\ni\u0026rsquo;ll store data as json locally instead\nof sqlite this makes it easy to use and\ndebug the code that might be something\nworth changing if you are building this\nfor scale\ni\u0026rsquo;m still using web services for most of\nthe functionality they are still easier\nto work with than web sockets\nhowever messaging is the ideal use case\nfor websockets and i\u0026rsquo;m using it for that\nexact purpose\nwhen the websocket is closed which would\nhappen if the app isn\u0026rsquo;t running or is\nminimized i use push\npush is used strictly as a visual medium\nto notify the user of a new message\nwhen sending and receiving data in\nwebsockets i use json\nin the past i used a binary websocket\nand i wanted to show how this approach\nworks as well\nso let\u0026rsquo;s start by creating the spring\nboot project for the server i\u0026rsquo;m assuming\nyou went through the previous modules\nand i won\u0026rsquo;t repeat myself too much\nyou can use the spring boot initializer\nwhich i used to create this pom file\ni just defined a new project with this\npackage for java 8.\nwe\u0026rsquo;ll use jpa to communicate with\nthe mysql database\nwe use jersey for pojo json\nserialization\nthe security package allows us to\nencrypt credentials into the database\nit has a lot of other features but they\naren\u0026rsquo;t as useful for us\nwe need\nweb services support too\nand web sockets to implement the full\ncommunication protocol\nthe underlying database is mysql so we\nneed the right drivers for that\nand finally we need the server side\ntwillow library to implement sms support\non the server this will be used for the\nactivation code functionality\nnext we need to create the client\napplication which i create as whatsapp\nclone\ni use the default native and bare bones\nsettings in the ide\ni pick the com\ncodename1.whatsapp package nothing\nspecial next we\u0026rsquo;ll go into the classes\nthat implement the client functionality\u003c/p\u003e","title":"1. Getting Started"},{"content":" Module 14: Creating a WhatsApp Clone\nTranscript we\u0026rsquo;ll jump into the client functionality from the server connectivity class I won\u0026rsquo;t start with the UI and build everything up but instead go through the code relatively quickly as I\u0026rsquo;m assuming you\u0026rsquo;ve gone through the longer explanations in the previous modules like before the server class abstracts the back end I\u0026rsquo;ll soon go into the details of the other classes in this package which are property business object abstractions as a reminder notice that I import the CN class so I can use shorthand Syntax for various apis I do this in almost all files in the project right now the debug environment points at the local host but in order to work with devices this will need to point at an actual URL or IP address as I mentioned before we\u0026rsquo;ll store the data as Json in storage the file names don\u0026rsquo;t have to end in dot Json I just did that for our convenience this is a property business object we\u0026rsquo;ll discuss soon we use it to represent all our contacts and ourselves this is the current websocket connection we need this to be Global as we will disconnect from the server when the app is minimized that\u0026rsquo;s important otherwise battery saving code might kill the app this flag indicates whether the websocket is connected which saves us from asking the connection if it\u0026rsquo;s still active if we aren\u0026rsquo;t connected new messages go into the message queue and will go out when we reconnect the user logged into the app is global the init method is invoked when the app is loaded it loads the global data from storage and sets the variable values normally there should be data here with the special case of the first activation if this is the first activation before receiving the validation SMS this file won\u0026rsquo;t exist in that case we\u0026rsquo;ll just initialize the contact cache as an empty list and be on our way assuming we are logged in we can load the data for the current user this is pretty easy to do for property business objects if there are messages in the message queue we need to load them as well this can happen if the user sends a message without connectivity and the app is killed contacts are cached here the contacts essentially contain everything in the app this might be a bit wasteful to store all the data in this way but it should work reasonably even for relatively large data sets this method sends the content of the message queue it\u0026rsquo;s invoked when we go back online these methods are shorthand for get and post methods of the rest API they force Json usage and add the auth header which most of the server-side apis will need that lets us write shorter code the login method is the first server sign method and doesn\u0026rsquo;t do much it sends the current user to the server then Saves The Returned instance of that user this allows us to refresh you the data from the server we pass the current user as the body in an argument notice I can pass the property business object directly and it will be converted to Json in the response we read the user replace the current instance and save it to disk sign up is very similar to login in fact it\u0026rsquo;s identical however after signup is complete you still don\u0026rsquo;t have everything anything since we need to verify the user so let\u0026rsquo;s skip down to that on the server signup triggers an SMS which we need to intercept we then need to send the SMS code via this API only after this method returns okay our user becomes valid update is practically identical to the two other methods but sends the updated data from the client to the server it isn\u0026rsquo;t interesting send message is probably the most important method here it delivers a message to the server and saves it into the Json storage here we have the time in which a specific contact last chatted this allows us to sort the contacts based on the time a specific contact last chatted with us this sends the message using a web service the message body is submitted as a chat message business object which is implicitly translated to Json initially I sent messages via the websocket but there wasn\u0026rsquo;t a big benefit to doing that I kept that code in place for reference the advantage of using websocket is mostly in the server side where the calls are seamlessly translated sorry the advantages of using web service is mostly that if we are offline the message is added to the message queue and the content of the queue is saved this method binds the websocket to the server and handles incoming and outgoing messages over the websocket connection this is a pretty big method because of the inner class within it but it\u0026rsquo;s relatively simple as the inner class is mostly trivial the bind method receives a callback interface for various application Level events for instance when a message is received we\u0026rsquo;d like to update the UI to indicate that we can do that via the Callback interface without getting all of that logic into the server clause here we create a subclass of websocket and override all the relevant callback methods skipping to the end of the method we can see the connection call and also Auto reconnect method which automatically tries to reconnect every five seconds if we lost the websocket connection let\u0026rsquo;s go back to the Callback method starting with on open this method is invoked when a connection is established once this is established we can start making websocket goals and receiving messages we start by sending an init message this is a simple Json message that provides the authorization token for the current user and the time of the last message received this means the server now knows we are connect connected and knows the time of the message we last received it means that if the server has messages pending it can send them now next we send an event that we are connected notice I used calls serially to send it on the EDT since these events will most likely handle GUI this makes sense finally we open a thread to send a ping message every 80 Seconds this is redundant for most users and you can remove that code if you don\u0026rsquo;t use cloudflare however if you do then cloudflare closes connections after 100 seconds of inactivity that way the connection isn\u0026rsquo;t closed as cloudflare sees that it\u0026rsquo;s active cloudflare is a Content delivery Network we use for our web properties it helps scale and protect your domain but it isn\u0026rsquo;t essential for this specific deployment still I chose to keep that code in because this took us a while to discover and might be a stumbling block for you as well when a connection is closed we call the event again on the EDT and mark the connected flag appropriately all the messages in the app are text-based messages so we use this version of the message callback event to handle incoming messages technically the messages are Json strings so we convert the string to a reader object then we parse the message and pass the result into the property business object this can actually be written in a slightly more concise way with the from Json method however that method didn\u0026rsquo;t exist when I wrote this code now that we parsed the object we need to decide what to do with it we do that on the EDT since the results would process uh to to impact the UI the typing flag allows us to send an event that a user is typing I didn\u0026rsquo;t fully implement this feature but the Callback and event behavior is correct another feature that I didn\u0026rsquo;t completely finish is the viewed by feature here here we can process an event indicating there was a change in the list of people who saw a specific message if it\u0026rsquo;s not one of those then it\u0026rsquo;s an actual message we need to start by updating the last received message time I\u0026rsquo;ll discuss update messages soon it effectively stores the message act message acknowledges the server to the server that the message was received this is important otherwise a message might be resent to make sure we received it finally we invoke the message received callback since we are already within the call serially we don\u0026rsquo;t need to wrap this too we don\u0026rsquo;t use binary messages and most errors would be resolved by o to reconnect still it\u0026rsquo;s important to at least log the errors the update method is invoked to update messages in the chat first we Loop over the existing contacts to try to find the right one once we find the contact we can add the message to the contact the find method finds that contact and we add a new message into the database this is invoked when a contact doesn\u0026rsquo;t already exist within the list of contacts we already have cached the method closes the websocket connection it\u0026rsquo;s something we need to do when the app is suspended so the OS doesn\u0026rsquo;t kill the app we\u0026rsquo;ll discuss this when talking about the lifecycle methods later the contacts are saved on the contacts grid we use this helper method to go into the helper thread to prevent race conditions fetch contacts loads the contacts from the Json list or the device contacts since this can be an expensive operation we do it on a separate context thread which is an easy thread easy trades let us send tasks to the thread similarly to call serially on the EDT here we lazily create the easy thread and then run fetch contacts on that thread assuming the current easy thread is null if the thread already exists we check whether we already are on the easy thread assuming we aren\u0026rsquo;t on the easy thread we call this method again on the thread and return all the following lines are now guaranteed to run on one thread which is the easy thread as such there are effectively thread safe and won\u0026rsquo;t slow down the EDT unless we do something that\u0026rsquo;s very CPU intensive we already have the data we use called serial if we already have the data we use call Siri on idle this is a slow version of call serially that waits for the EDT to reach idle state this is important for performance a regular call serially might occur when the system is animating or in need of resources if we want to do something expensive or slow it might cause choking of the UI call Syria on idle will delay the call serially to a point where there are no pending animations or user interaction this means that there is enough CPU to perform the operation if we have a Json file for the contacts we use that as a starting point this allows us to store all the data in one place and mutate the data as we see fit we keep the contacts in a contacts cache map which enables fast access at the trade-off of some Ram this isn\u0026rsquo;t too much since we store the thumbnails as external jpegs once we loaded the core Json data we use call serially to send the event of loading completion but we aren\u0026rsquo;t done yet we Loop over the contacts we loaded and check if there is an image file matching the contact name assuming there is we load it on the context thread and set it to the contact this will fire an event on the property object and trigger a repaint asynchronously if we don\u0026rsquo;t have a Json file we need to create it and the place to start is the contacts on the device get all contacts fetches all the device contacts the first argument is true if we only want contacts that have phone numbers associated with them this is true as we don\u0026rsquo;t need contacts without phone numbers the next few values indicate the attributes we need from the contacts database we don\u0026rsquo;t need most of the attributes we only need we only fetch the full name and phone number the reason for this is performance fetching all attributes can be very expensive even on a fast device next we Loop over each contact and add it to the list of contacts we convert the built-in contact object to chat contact and the process for every entry in the contacts we need to fetch an image we can use calls serially on idle to do that this allows the image loading to occur when the user isn\u0026rsquo;t scrolling the UI so it won\u0026rsquo;t noticeably impact performance once we load the photo into the object we save it to storage as well for faster retrieval in the future this is pretty simplistic code proper code would have scaled the image to a uniform size as well this would have saved memory finally once we are done we save the contacts to the Json file this isn\u0026rsquo;t shown here but the content of the photo property is installed to the Json file to keep the size minimal and loading time short once loaded we invoke the callback with the proper argument when we want to contact a user we need to First make sure he\u0026rsquo;s on our chat platform for this we have the find registered user server API with this API we will receive a list with one user object or an empty list from the server this API is asynchronous and we use it to decide whether we can send a message to someone from our contacts this is a similar method that allows us to get a user based on the user ID instead of a phone if we get a chat message that was sent by a specific user we will need to know about that user this method lets us fetch the method metadata related to that user the chats we have open with users can be extracted from the list of contacts since every contact has its own chat thread so to fetch the chats we see in the main form of the WhatsApp UI we need to First fetch the contacts as they might not have been loaded yet we Loop over the contacts and if we had activity with that contact we add him to the list in the response but before we finish we need to sort the responses based on activity time the sort method is built into Java Collections API it accepts a comparator which we represented here as a Lambda expression the comparator Compares two objects in the list to one another it returns a value smaller than zero to indicate the first value is smaller zero to indicate the values are identical and More Than Zero To indicate the second value is larger The Simple Solution is sorry smaller The Simple Solution is subtracting the time values to get a valid comparison result we saw the ack call earlier this stands for acknowledgment we effectively acknowledge that the message was received if this doesn\u0026rsquo;t go to the server the server doesn\u0026rsquo;t know if a message reached its destination finally we need this method for push notification it sends the push key to the device of the device to the server so the server will be able to send push messages to the device\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/125-2-client-to-server-abstraction/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 14: Creating a WhatsApp Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/gJoJQST5jyM?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ewe\u0026rsquo;ll jump into the client functionality\nfrom the server connectivity class\nI won\u0026rsquo;t start with the UI and build\neverything up but instead go through the\ncode relatively quickly as I\u0026rsquo;m assuming\nyou\u0026rsquo;ve gone through the longer\nexplanations in the previous modules\nlike before the server class abstracts\nthe back end I\u0026rsquo;ll soon go into the\ndetails of the other classes in this\npackage which are property business\nobject abstractions\nas a reminder notice that I import the\nCN class so I can use shorthand Syntax\nfor various apis\nI do this in almost all files in the\nproject\nright now the debug environment points\nat the local host but in order to work\nwith devices this will need to point at\nan actual URL or IP address\nas I mentioned before we\u0026rsquo;ll store the\ndata as Json in storage the file names\ndon\u0026rsquo;t have to end in dot Json I just did\nthat for our convenience\nthis is a property business object we\u0026rsquo;ll\ndiscuss soon\nwe use it to represent all our contacts\nand ourselves\nthis is the current websocket connection\nwe need this to be Global as we will\ndisconnect from the server when the app\nis minimized\nthat\u0026rsquo;s important otherwise battery\nsaving code might kill the app\nthis flag indicates whether the\nwebsocket is connected\nwhich saves us from asking the\nconnection if it\u0026rsquo;s still active\nif we aren\u0026rsquo;t connected new messages go\ninto the message queue and will go out\nwhen we reconnect\nthe user logged into the app is global\nthe init method is invoked when the app\nis loaded\nit loads the global data from storage\nand sets the variable values normally\nthere should be data here with the\nspecial case of the first activation\nif this is the first activation before\nreceiving the validation SMS this file\nwon\u0026rsquo;t exist\nin that case we\u0026rsquo;ll just initialize the\ncontact cache as an empty list and be on\nour way\nassuming we are logged in we can load\nthe data for the current user this is\npretty easy to do for property business\nobjects\nif there are messages in the message\nqueue we need to load them as well this\ncan happen if the user sends a message\nwithout connectivity and the app is\nkilled\ncontacts are cached here\nthe contacts essentially contain\neverything in the app this might be a\nbit wasteful to store all the data in\nthis way but it should work reasonably\neven for relatively large data sets\nthis method sends the content of the\nmessage queue it\u0026rsquo;s invoked when we go\nback online\nthese methods are shorthand for get and\npost methods of the rest API\nthey force Json usage and add the auth\nheader which most of the server-side\napis will need\nthat lets us write shorter code\nthe login method is the first server\nsign method\nand doesn\u0026rsquo;t do much it sends the current\nuser to the server then Saves The\nReturned instance of that user\nthis allows us to refresh you the data\nfrom the server\nwe pass the current user as the body in\nan argument notice I can pass the\nproperty business object directly and it\nwill be converted to Json\nin the response we read the user replace\nthe current instance and save it to disk\nsign up is very similar to login in fact\nit\u0026rsquo;s identical however after signup is\ncomplete you still don\u0026rsquo;t have everything\nanything since we need to verify the\nuser so let\u0026rsquo;s skip down to that\non the server signup triggers an SMS\nwhich we need to intercept\nwe then need to send the SMS code via\nthis API\nonly after this method returns okay our\nuser becomes valid\nupdate is practically identical to the\ntwo other methods but sends the updated\ndata from the client to the server it\nisn\u0026rsquo;t interesting\nsend message is probably the most\nimportant method here it delivers a\nmessage to the server and saves it into\nthe Json storage\nhere we have the time in which a\nspecific contact last chatted this\nallows us to sort the contacts based on\nthe time a specific contact last chatted\nwith us\nthis sends the message using a web\nservice\nthe message body is submitted as a chat\nmessage business object which is\nimplicitly translated to Json\ninitially I sent messages via the\nwebsocket\nbut there wasn\u0026rsquo;t a big benefit to doing\nthat I kept that code in place for\nreference\nthe advantage of using websocket is\nmostly in the server side where\nthe calls are seamlessly translated\nsorry the advantages of using web\nservice\nis mostly that\nif we are offline the message is added\nto the message queue and the content of\nthe queue is saved\nthis method binds the websocket to the\nserver and handles incoming and outgoing\nmessages over the websocket connection\nthis is a pretty big method because of\nthe inner class within it but it\u0026rsquo;s\nrelatively simple as the inner class is\nmostly trivial\nthe bind method receives a callback\ninterface for various application Level\nevents for instance when a message is\nreceived we\u0026rsquo;d like to update the UI to\nindicate that\nwe can do that via the Callback\ninterface without getting all of that\nlogic into the server clause\nhere we create a subclass of websocket\nand override all the relevant callback\nmethods\nskipping to the end of the method we can\nsee the connection call and also Auto\nreconnect method which automatically\ntries to reconnect every five seconds if\nwe lost the websocket connection\nlet\u0026rsquo;s go back to the Callback method\nstarting with on open\nthis method is invoked when a connection\nis established once this is established\nwe can start making websocket goals and\nreceiving messages\nwe start by sending an init message this\nis a simple Json message that provides\nthe authorization token for the current\nuser and the time of the last message\nreceived\nthis means the server now knows we are\nconnect connected and knows the time of\nthe message we last received it means\nthat if the server has messages pending\nit can send them now\nnext we send an event that we are\nconnected notice I used calls serially\nto send it on the EDT since these events\nwill most likely handle GUI this makes\nsense\nfinally we open a thread to send a ping\nmessage every 80 Seconds\nthis is redundant for most users and you\ncan remove that code if you don\u0026rsquo;t use\ncloudflare\nhowever if you do then cloudflare closes\nconnections after 100 seconds of\ninactivity\nthat way the connection isn\u0026rsquo;t closed as\ncloudflare sees that it\u0026rsquo;s active\ncloudflare is a Content delivery Network\nwe use for our web properties it helps\nscale and protect your domain but it\nisn\u0026rsquo;t essential for this specific\ndeployment\nstill I chose to keep that code in\nbecause this took us a while to discover\nand might be a stumbling block for you\nas well\nwhen a connection is closed we call the\nevent again on the EDT and mark the\nconnected flag appropriately\nall the messages in the app are\ntext-based messages so we use this\nversion of the message callback event to\nhandle incoming messages\ntechnically the messages are Json\nstrings so we convert the string to a\nreader object then we parse the message\nand pass the result into the property\nbusiness object\nthis can actually be written in a\nslightly more concise way with the from\nJson method however that method didn\u0026rsquo;t\nexist when I wrote this code\nnow that we parsed the object we need to\ndecide what to do with it\nwe do that on the EDT since the results\nwould process uh to to impact the UI\nthe typing flag allows us to send an\nevent that a user is typing I didn\u0026rsquo;t\nfully implement this feature but the\nCallback and event behavior is correct\nanother feature that I didn\u0026rsquo;t completely\nfinish is the viewed by feature here\nhere we can process an event indicating\nthere was a change in the list of people\nwho saw a specific message\nif it\u0026rsquo;s not one of those then it\u0026rsquo;s an\nactual message we need to start by\nupdating the last received message time\nI\u0026rsquo;ll discuss update messages soon it\neffectively stores the message\nact message acknowledges the server to\nthe server that the message was received\nthis is important otherwise a message\nmight be resent to make sure we received\nit\nfinally we invoke the message received\ncallback since we are already within the\ncall serially we don\u0026rsquo;t need to wrap this\ntoo\nwe don\u0026rsquo;t use binary messages and most\nerrors would be resolved by o to\nreconnect still it\u0026rsquo;s important to at\nleast log the errors\nthe update method is invoked to update\nmessages in the chat\nfirst we Loop over the existing contacts\nto try to find the right one\nonce we find the contact we can add the\nmessage to the contact\nthe find method finds that contact and\nwe add a new message into the database\nthis is invoked when a contact doesn\u0026rsquo;t\nalready exist within the list of\ncontacts we already have cached\nthe method closes the websocket\nconnection\nit\u0026rsquo;s something we need to do when the\napp is suspended so the OS doesn\u0026rsquo;t kill\nthe app\nwe\u0026rsquo;ll discuss this when talking about\nthe lifecycle methods later\nthe contacts are saved on the contacts\ngrid we use this helper method to go\ninto the helper thread to prevent race\nconditions\nfetch contacts loads the contacts from\nthe Json list or the device contacts\nsince this can be an expensive operation\nwe do it on a separate context thread\nwhich is an easy thread\neasy trades let us send tasks to the\nthread similarly to call serially on the\nEDT\nhere we lazily create the easy thread\nand then run fetch contacts on that\nthread assuming the current easy thread\nis null\nif the thread already exists we check\nwhether we already are on the easy\nthread assuming we aren\u0026rsquo;t on the easy\nthread we call this method again on the\nthread and return\nall the following lines are now\nguaranteed to run on one thread which is\nthe easy thread as such there are\neffectively thread safe and won\u0026rsquo;t slow\ndown the EDT unless we do something\nthat\u0026rsquo;s very CPU intensive\nwe already have the data we use called\nserial if we already have the data we\nuse call Siri on idle this is a slow\nversion of call serially that waits for\nthe EDT to reach idle state\nthis is important for performance a\nregular call serially might occur when\nthe system is animating or in need of\nresources if we want to do something\nexpensive or slow it might cause choking\nof the UI call Syria on idle will delay\nthe call serially to a point where there\nare no pending animations or user\ninteraction\nthis means that there is enough CPU to\nperform the operation\nif we have a Json file for the contacts\nwe use that as a starting point this\nallows us to store all the data in one\nplace and mutate the data as we see fit\nwe keep the contacts in a contacts cache\nmap which enables fast access at the\ntrade-off of some Ram this isn\u0026rsquo;t too\nmuch since we store the thumbnails as\nexternal jpegs\nonce we loaded the core Json data we use\ncall serially to send the event of\nloading completion\nbut we aren\u0026rsquo;t done yet\nwe Loop over the contacts we loaded and\ncheck if there is an image file matching\nthe contact name\nassuming there is we load it on the\ncontext thread and set it to the contact\nthis will fire an event on the property\nobject and trigger a repaint\nasynchronously\nif we don\u0026rsquo;t have a Json file we need to\ncreate it and the place to start is the\ncontacts on the device\nget all contacts fetches all the device\ncontacts\nthe first argument is true if we only\nwant contacts that have phone numbers\nassociated with them this is true as we\ndon\u0026rsquo;t need contacts without phone\nnumbers\nthe next few values indicate the\nattributes we need from the contacts\ndatabase\nwe don\u0026rsquo;t need most of the attributes we\nonly need we only fetch the full name\nand phone number the reason for this is\nperformance fetching all attributes can\nbe very expensive even on a fast device\nnext we Loop over each contact and add\nit to the list of contacts we convert\nthe built-in contact object to chat\ncontact and the process\nfor every entry in the contacts we need\nto fetch an image we can use calls\nserially on idle to do that this allows\nthe image loading to occur when the user\nisn\u0026rsquo;t scrolling the UI so it won\u0026rsquo;t\nnoticeably impact performance\nonce we load the photo into the object\nwe save it to storage as well for faster\nretrieval in the future this is pretty\nsimplistic code proper code would have\nscaled the image to a uniform size as\nwell this would have saved memory\nfinally once we are done we save the\ncontacts to the Json file this isn\u0026rsquo;t\nshown here but the content of the photo\nproperty is installed to the Json file\nto keep the size minimal and loading\ntime short\nonce loaded we invoke the callback with\nthe proper argument\nwhen we want to contact a user we need\nto First make sure he\u0026rsquo;s on our chat\nplatform\nfor this we have the find registered\nuser server API with this API we will\nreceive a list with one user object or\nan empty list from the server this API\nis asynchronous and we use it to decide\nwhether we can send a message to someone\nfrom our contacts\nthis is a similar method that allows us\nto get a user based on the user ID\ninstead of a phone if we get a chat\nmessage that was sent by a specific user\nwe will need to know about that user\nthis method lets us fetch the method\nmetadata related to that user\nthe chats we have open with users can be\nextracted from the list of contacts\nsince every contact has its own chat\nthread\nso to fetch the chats we see in the main\nform of the WhatsApp UI we need to First\nfetch the contacts as they might not\nhave been loaded yet\nwe Loop over the contacts and if we had\nactivity with that contact we add him to\nthe list in the response\nbut before we finish we need to sort the\nresponses based on activity time the\nsort method is built into Java\nCollections API it accepts a comparator\nwhich we represented here as a Lambda\nexpression\nthe comparator Compares two objects in\nthe list to one another\nit returns a value smaller than zero to\nindicate the first value is smaller zero\nto indicate the values are identical and\nMore Than Zero To indicate the second\nvalue is larger\nThe Simple Solution is\nsorry smaller The Simple Solution is\nsubtracting the time values to get a\nvalid comparison result\nwe saw the ack call earlier this stands\nfor acknowledgment we effectively\nacknowledge that the message was\nreceived if this doesn\u0026rsquo;t go to the\nserver\nthe server doesn\u0026rsquo;t know if a message\nreached its destination\nfinally we need this method for push\nnotification it sends the push key to\nthe device of the device to the server\nso the server will be able to send push\nmessages to the device\u003c/p\u003e","title":"2. Client to Server Abstraction"},{"content":" Module 14: Creating a WhatsApp Clone\nTranscript the next step are the other classes within the model package the rest is relatively trivial after the server class this is the callback interface we used within the server class it\u0026rsquo;s pretty trivial i added some methods for future enhancement too the first two methods inform the observer that the server is connected or disconnected message received is invoked to update the ui based on the new incoming message the last two callbacks aren\u0026rsquo;t really implemented but they allow us to update the ui if a user is typing in a chat the message viewed event similarly indicates if a user viewed the message this can provide an indicator in the ui that the message was seen chat contact is a property business object that stores the content of a specific contact entry i chose to use unique ids instead of using the phone as an id this was something i was conflicted about i eventually chose to use an id which i think is more secure overall it would also support the option of changing a phone number in a future in the future or using an email as the unique identifier local id should map to the id in the contacts this allows us to refresh the contact details from the device address book in the future the phone property is pretty obvious the photo property stores the picture of the contact there is a lot to this property so i\u0026rsquo;ll discuss it in more details soon these are the common attributes for name and tagline used in whatsapp for simple simplicity i chose to use a full name and ignored nuances such as first lost middle initial etc the token is effectively our password to use the service since there is no login process a token is generated on the server as a key that allows us to use the service a chat contact can also serve as a group i didn\u0026rsquo;t fully implement this logic but it\u0026rsquo;s wired almost everywhere in this case we have two sets for members of the group and the admin of the group these sets would be empty for a typical user the this property allows us to mute a chat contact so we won\u0026rsquo;t see notifications from that contact if this is a group then it was created by a specific user the id of that user should be listed here the creation date is applicable to both groups individual users this is the timestamp of the last message we received from the given user we saw this updated in the server class we use use this to sort the chats by latest update chat message is the property business object that contains the content of the message here we saw the actual chats we had with the contact or group as i mentioned before photo is installed in json when we save the contact to keep the size low we save the contact image in a separate file and don\u0026rsquo;t want too much noise here the app has two thumbnail images one is slightly smaller than the other and both are rounded to keep the code generic i used arrays with the detail and then used two sizes one small size maps to the zero offset and the array and the large size maps to the one offset here are the sizes of these two images in millimeters images are masked to these sizes masking allows us to round an image in this case we generate placeholder images which are used when an image is unavailable this method creates a mask image of a given size and pixels a mask image uses black pixels to represent transparency and white pixels to represent the physical visible opacity so where we draw a black rectangle image with a white circle in the center when we apply this mask to an image only the portion represented by the white circle will remain the placeholder image is used when no image is defined again we create this based on size and pixels we create a gray image and then draw on it using white we use the material font to draw the image of a person onto this image this method gets the image represented by the contact in theory i could have used the photo property and overridden get to implement this i thought this is a simpler approach here we lazily initialize the arrays of the mask image for larger or larger small images we create the mask images then convert the mask image to mask object finally we create the placeholder image if the photo is null i return the placeholder image instead of using the photo object otherwise we fill the image into the size of the mask and apply the mask to create a round object fill scales the image so it\u0026rsquo;s cropped while filling the exact boundaries given it doesn\u0026rsquo;t distort the aspect ratio of the image like a typical scale operation would the final public methods and variables cache the small and large image appropriately they are the publicly exposed apis for this functionality\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/126-3-the-model-package/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 14: Creating a WhatsApp Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/46TpE-Cgtw8?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ethe next step are the other classes\nwithin the model package\nthe rest is relatively trivial after the\nserver class\nthis is the callback interface we used\nwithin the server class it\u0026rsquo;s pretty\ntrivial i added some methods for future\nenhancement too\nthe first two methods inform the\nobserver that the server is connected or\ndisconnected\nmessage received is invoked to update\nthe ui based on the new incoming message\nthe last two callbacks aren\u0026rsquo;t really\nimplemented but they allow us to update\nthe ui if a user is typing in a chat\nthe message viewed event similarly\nindicates if a user viewed the message\nthis can provide an indicator in the ui\nthat the message was seen\nchat contact is a property business\nobject that stores the content of a\nspecific contact entry\ni chose to use unique ids instead of\nusing the phone as an id\nthis was something i was conflicted\nabout\ni eventually chose to use an id which i\nthink is more secure overall\nit would also support the option of\nchanging a phone number in a future in\nthe future or using an email as the\nunique identifier\nlocal id should map to the id in the\ncontacts this allows us to refresh the\ncontact details from the device address\nbook in the future\nthe phone property is pretty obvious\nthe photo property stores the picture of\nthe contact there is a lot to this\nproperty so i\u0026rsquo;ll discuss\nit in more details soon\nthese are the common attributes for name\nand tagline used in whatsapp\nfor simple simplicity i chose to use a\nfull name and ignored nuances such as\nfirst lost middle initial etc\nthe token is effectively our password to\nuse the service\nsince there is no login process a token\nis generated on the server as a key that\nallows us to use the service\na chat contact can also serve as a group\ni didn\u0026rsquo;t fully implement this logic but\nit\u0026rsquo;s wired\nalmost everywhere\nin this case we have two sets for\nmembers of the group\nand the admin of the group\nthese sets would be empty for a typical\nuser\nthe this property allows us to mute a\nchat contact so we won\u0026rsquo;t see\nnotifications from that contact\nif this is a group then it was created\nby a specific user the id of that user\nshould be listed here\nthe creation date is applicable to both\ngroups individual users\nthis is the timestamp of the last\nmessage we received from the given user\nwe saw this updated in the server class\nwe use use this to sort the chats by\nlatest update\nchat message is the property business\nobject\nthat contains the content of the message\nhere we saw the actual chats we had with\nthe contact or group\nas i mentioned before photo is installed\nin json when we save the contact to keep\nthe size low\nwe save the contact image in a separate\nfile and don\u0026rsquo;t want too much noise here\nthe app has two thumbnail images one is\nslightly smaller than the other and both\nare rounded\nto keep the code generic i used arrays\nwith the detail and then used two sizes\none small size maps to the zero offset\nand the array and the large size maps to\nthe one offset\nhere are the sizes of these two images\nin millimeters\nimages are masked to these sizes\nmasking allows us to round an image in\nthis case\nwe generate placeholder images which are\nused when an image is unavailable\nthis method creates a mask image of a\ngiven size and pixels\na mask image uses black pixels to\nrepresent transparency and white pixels\nto represent the physical visible\nopacity\nso where we draw a black rectangle image\nwith a white circle in the center\nwhen we apply this mask to an image only\nthe portion represented by the white\ncircle will remain\nthe placeholder image is used when no\nimage is defined again we create this\nbased on size and pixels\nwe create a gray image and then draw on\nit using white\nwe use the material font to draw the\nimage of a person onto this image\nthis method gets the image represented\nby the contact\nin theory i could have used the photo\nproperty and overridden get to implement\nthis i thought this is a simpler\napproach\nhere we lazily initialize the arrays of\nthe mask image\nfor larger or larger small images\nwe create the mask images then convert\nthe mask image to mask object finally we\ncreate the placeholder image\nif the photo is null i return the\nplaceholder image instead of using the\nphoto object\notherwise we fill the image into the\nsize of the mask and apply the mask to\ncreate a round object fill scales the\nimage so it\u0026rsquo;s cropped while filling the\nexact boundaries given it doesn\u0026rsquo;t\ndistort the aspect ratio of the image\nlike a typical scale operation would\nthe final public methods and variables\ncache the small and large image\nappropriately they are the publicly\nexposed apis for this functionality\u003c/p\u003e","title":"3. The Model Package"},{"content":" Module 14: Creating a WhatsApp Clone\nTranscript there is still one other class within the model package once we finish that we\u0026rsquo;ll go to the main class the chat message class is another property business object but one that\u0026rsquo;s even simpler than the last one this is the author of the message since we use ids and not phones this might become an issue so we need to keep track of both sent to can be important as this message might have been sent to a group and not directly to our current user the timestamp of the message and the actual text of the message are the main payload attachments aren\u0026rsquo;t fully implemented the general idea is a url of the attachment mapping to a mime type so we can represent it in the ui as image slash video audio or document the list of people who viewed the message which can be more than one for a message sent to a group the typing message is a special type of message that we don\u0026rsquo;t currently send but it can be sent pretty easily and just update the ui that the user is typing to this chat this is the final property in this class which is relatively simple with that long detour out of the way let\u0026rsquo;s go back to the main class as you can see i left most of the code intact and kept it as the default the first piece of code you will see that isn\u0026rsquo;t part of the default code is this line to initialize the server and load the saved data there is also the push interface which we need to implement to receive push callbacks that leads us directly to the first method from that interface we don\u0026rsquo;t need to implement this method since we use push only as a visual medium and rely on web sockets to carry the actual data push is inherently unreliable and might perform badly it places limitations on the type of data you can send we have more control over web sockets we use push only when the app is minimized the one method we need to implement from the push interface is the registered for push corbett when this callback is invoked we need to send the push key to the server this is important notice that the push key isn\u0026rsquo;t the device id there are different values don\u0026rsquo;t confuse them the sms verification class is an abstract class from the sms verification cn1 lib it lets us move some of the functionality of that library into the server the first method is the send sms code method it sends an sms mesh message to the given phone number on the server it invokes the signup call which triggers an sms to that phone number this callback is invoked as part of the signup process when the user types in or the system intercepts a phone number this callback is invoked it sends the verification string to the server side and returns the result based on that the message listener allows us to track messages from the server such as connect incoming messages etc a lot of this isn\u0026rsquo;t implemented as we don\u0026rsquo;t need it right now but it could be useful for the ui as it evolves one thing we do implement here is the message received api there isn\u0026rsquo;t much going on in this method though if the current form is the chat form then we need to check if we are currently in the chat form with the sender of the incoming message assuming this is the case we can add this message to the ui regardless we need to refresh the main ui of the chat list container since the order to the contacts will change next we have the start lifecycle method you will notice that we invoke bind message listener even when we restore a running app as you might recall we close the websocket connection when the app is minimized this effectively restores that connection when the app is restored back to normal the this call happens when the app is launched in a cold start if the phone number isn\u0026rsquo;t set this is the first activation and we need to set up a new user the activation form api builds the data and you are using a builder pattern where every method adds to the resulting form first we allocate the activation form with the title sign up when we then determine that we want a six digit activation code instead of the default four digit code we finally show the activation ui this accepts two arguments the second argument is the sms verification subclass we discussed earlier it sends the sms details to the server which issues an sms it then performs verification on the server which is more secure than client-side verification the first argument is a callback that\u0026rsquo;s invoked when the activation is completed it\u0026rsquo;s invoked with a phone number in the result here we store the new phone number to the preferences then show the main form ui if the user was already registered we show the main form directly we discussed the bind method before so the last piece is the register push core this is an essential part of the push notification support finally we added close websocket code to the stop method this implements the logic of stopping the websocket connection when the app is minimized\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/127-4-the-main-class/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 14: Creating a WhatsApp Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/65LciCzyRNQ?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ethere is still one other class within\nthe model package\nonce we finish that\nwe\u0026rsquo;ll go to the main class\nthe chat message class is another\nproperty business object\nbut one that\u0026rsquo;s even simpler than the\nlast one\nthis is the author of the message since\nwe use ids and not phones this might\nbecome an issue so we need to keep track\nof both\nsent to can be important as this message\nmight have been sent to a group and not\ndirectly to our current user\nthe timestamp of the message and the\nactual text of the message are the main\npayload\nattachments aren\u0026rsquo;t fully implemented the\ngeneral idea is a url of the attachment\nmapping to a mime type so we can\nrepresent it in the ui as image slash\nvideo audio or document\nthe list of people who viewed the\nmessage which can be more than one for a\nmessage sent to a group\nthe typing message is a special type of\nmessage that we don\u0026rsquo;t currently send\nbut it can be sent pretty easily and\njust update the ui that the user is\ntyping to this chat\nthis is the final property in this class\nwhich is relatively simple\nwith that long detour out of the way\nlet\u0026rsquo;s go back to the main class\nas you can see i left most of the code\nintact and kept it as the default\nthe first piece of code you will see\nthat isn\u0026rsquo;t part of the default code is\nthis line to initialize the server and\nload the saved data\nthere is also the push interface which\nwe need to implement to receive push\ncallbacks\nthat leads us directly to the first\nmethod from that interface\nwe don\u0026rsquo;t need to implement this method\nsince we use push only as a visual\nmedium and rely on web sockets to carry\nthe actual data\npush is inherently unreliable and might\nperform badly it places limitations on\nthe type of data you can send\nwe have more control over web sockets\nwe use push only when the app is\nminimized\nthe one method we need to implement from\nthe push interface is the registered for\npush corbett\nwhen this callback is invoked we need to\nsend the push key to the server this is\nimportant\nnotice that the push key isn\u0026rsquo;t the\ndevice id\nthere are different values don\u0026rsquo;t confuse\nthem\nthe sms verification class is an\nabstract class from the sms verification\ncn1 lib\nit lets us move some of the\nfunctionality of that library into the\nserver\nthe first method is the send sms code\nmethod it sends an sms mesh message to\nthe given phone number\non the server it invokes the signup call\nwhich triggers an sms to that phone\nnumber\nthis callback is invoked as part of the\nsignup process\nwhen the user types in or the system\nintercepts a phone number\nthis callback is invoked it sends the\nverification string to the server side\nand returns the result based on that\nthe message listener allows us to track\nmessages from the server such as connect\nincoming messages etc\na lot of this isn\u0026rsquo;t implemented as we\ndon\u0026rsquo;t need it right now\nbut it could be useful for the ui as it\nevolves\none thing we do implement here is the\nmessage received api\nthere isn\u0026rsquo;t much going on in this method\nthough\nif the current form\nis the chat form\nthen we need to check if we are\ncurrently in the chat form with the\nsender of the incoming message assuming\nthis is the case we can add this message\nto the ui\nregardless we need to refresh the main\nui\nof the chat list container\nsince the order\nto the contacts will change\nnext we have the start lifecycle method\nyou will notice that we invoke bind\nmessage listener even when we restore a\nrunning app\nas you might recall we close the\nwebsocket connection when the app is\nminimized this effectively restores that\nconnection when the app is restored back\nto normal\nthe this call happens when the app is\nlaunched in a cold start\nif the phone number isn\u0026rsquo;t set this is\nthe first activation and we need to set\nup a new user\nthe activation form api builds the data\nand you are using a builder pattern\nwhere every method adds\nto the resulting form\nfirst we allocate the activation form\nwith the title sign up\nwhen\nwe then determine that we want a six\ndigit activation code instead of the\ndefault four digit code\nwe finally show the activation ui this\naccepts two arguments\nthe second argument is the sms\nverification subclass we discussed\nearlier\nit sends the sms details to the server\nwhich issues an sms it then performs\nverification on the server which is more\nsecure than client-side verification\nthe first argument is a callback that\u0026rsquo;s\ninvoked when the activation is completed\nit\u0026rsquo;s invoked with a phone number in the\nresult\nhere we store the new phone number to\nthe preferences then show the main form\nui\nif the user was already registered we\nshow the main form\ndirectly we discussed the bind method\nbefore so the last piece is the register\npush core\nthis is an essential part of the push\nnotification support\nfinally we added close websocket code to\nthe stop method this implements the\nlogic of stopping the websocket\nconnection\nwhen the app is minimized\u003c/p\u003e","title":"4. The Main Class"},{"content":" Module 14: Creating a WhatsApp Clone\nTranscript now that we implemented the model code and the lifecycle code we are almost finished we are down to ui code and css we start with the main form which covers the list of chat elements as is the case with all the forms in this app we derive from form for simplicity the main body of the form is a tabs component that allows us to switch between camera status and calls camera kit is used to implement the camera ui but due to a regression in the native library this code is currently commented out there are the three tab containers we make use of them in the scrolling logic later the main form is a singleton as we need a way to refresh it when we are in a different form the form itself uses a border layout to place the tabs in the center we also save the form instance for later use we hide the tabs it generally means that these aren\u0026rsquo;t actually tabs they are buttons we draw ourselves the reason for that is the special animation we need in the title area we add the tabs and select the second one as the default as we don\u0026rsquo;t want to open with the camera view instead of using the title we use title component which may takes over the entire title area and lets us build whatever we want up there i\u0026rsquo;ll discuss it more when covering that method the back command of the form respects the hardware back buttons and some devices and the android native back arrow here we have custom behavior for the form if we are in a tab other than the first tab we need to return to that tab otherwise the app is minimized this seems to be the behavior of the native app the calls container is a y-scrollable container this is simply a placeholder i placed here a multi-button representing incoming outgoing calls and a floating action button the same is true for the status container this isn\u0026rsquo;t an important part of the functionality with this tutorial you might recall that we invoke this method from the main ui to refresh the ongoing chat status we fetch up to date data from storage this is an asynchronous call that returns on the edt so the rest of the code goes into the lambda we remove the old content as we\u0026rsquo;ll just read it we loop over the contacts and for every new contact we create a chat multi button with the given name if there is a tagline defined we set that tagline we also use the large icon for that per person if the button is clicked we show the chat form for this user the chats container is the same as the other containers we saw but it\u0026rsquo;s actually fully implemented it invokes the refresh chats container method we previously saw previously saw in the order in order to fill up the container and the floating action button here is actually implemented by showing the new message form [Music] camera support is currently commented out due to a regression in the native library however the concept is relatively simple we use the tab selection listener to activate the camera as we need the overflow menu is normally implemented in the toolbar but since i wanted more control over the toolbar area i chose to implement it manually in the code i used buttons with the command uiid and container with the command list uid to create this ui i\u0026rsquo;ll discuss the css that created this in the next lesson i create a transparent dialog by giving it the container ui id i place the menu in the center the dialog has no transition and disposed if the user taps outside of it or uses the back button this disables the default darkening of the form when a dialog is shown this version of the show method places the dialog with a fixed distance from the edges we give it a small margin on the top to take the state status bar into account then use left and bottom margin to push the dialog to the top right side this gives us a lot of flexibility and allows us to show the dialogue in any way we want this method creates the title component for the form which is this region the method accepts the scrollable containers in the tabs container this allows us to track scrolling and seamlessly fold the title area the title itself is just a label with a title ui id it\u0026rsquo;s placed in the center of the title area border layout if we are on ios we want the title to be centered in that case we need to use the center version of the border layout the reason for this is that center alignment doesn\u0026rsquo;t know about the full layout and would center based on available space it would ignore the search and overflow buttons on the right when centering since it isn\u0026rsquo;t aware of other components however using the center alignment and placing these buttons in the east solves that problem and gives us the correct title position a search and overflow commands are just buttons with the title and the title ui id we already discussed the show overflow menu method so this should be pretty obvious we just placed the two buttons in the grid i chose not to use a command as this might create a misalignment for the this use case and won\u0026rsquo;t have saved on the amount of code i had to write these are the tabs for selecting camera chat etc there are just toggle buttons which in this case are classified as radio buttons this means only one of the radio buttons within the button group can be selected we give them all the subtitle ui id which again i\u0026rsquo;ll discuss in the next lesson we use table layout to place the tabs into the ui this allows us to explicitly determine the width of the columns notice that the table layout has two rows the second row of the table contains a white line using the side title underline ui id this line is placed in row one and column one so it\u0026rsquo;s under the chats entry when we move between tabs this underline needs to animate to the new position here we bind the listeners to all four buttons mapping to each tab when a button is clicked we select the appropriate tab the next line two lines implement the underline animation effect that we see when we click a button notice how the line animates to the right tab button to achieve this we remove the current white line and add it back to the toggle container in the right position we reset the height of the title in case it was shrunk during scrolling and we finally update the layout with an animation which performs the actual line move animation the previous block updated the tab selection when we select a button this block does the opposite it updates the button selection when we swipe the tabs it uses a tab selection listener if the button isn\u0026rsquo;t selected then we need to update it [Music] again we need to reset the title size next we select the button that matches the tab [Music] finally we perform the animation of moving the underline between tabs notice that this is almost identical to the previous animation code only in this case it\u0026rsquo;s triggered by dragging the tabs instead of the button click events the last two lines in this method are the bind folding call which we\u0026rsquo;ll discuss soon and the box layout y which wraps the two containers as one the bind folding method implements this animation of the folding title it\u0026rsquo;s implemented by tracking pointer drag events and shrinking the title when the pointer is released we need to check if the title shrunk enough to minimize it minimize or not enough so it would go back to the full size if the title area height is different from the original height it means we are in the process of shrinking the title in that case we need to decide whether the process is closer to the finish line or to the start it\u0026rsquo;s less than halfway to the height of the title we reset the preferred size of the title area that means the title area will take up its original original preferred size and go back to full height otherwise we set the title area height to zero so it\u0026rsquo;s effectively hidden regardless of the choice we made above we show it using an animation we detect the drag operation by binding a scroll listener to the three scrollable containers i could have used pointer drag listeners but they might generate too much noise that isn\u0026rsquo;t applicable [Music] i chose to make a special case for the tensile drag effect the tensile effect in is the ios scroll behavior where a drag extends beyond the top most part then bounces back like a rubber band this can cause a problem with the logic below so i decided that any scroll position above 10 pixels should probably show the full title now that all of that is out of the way we can calculate the direction of the scroll and shrink or grow the title area appropriately if the diff is larger than zero then the title area should grow we\u0026rsquo;re setting the preferred height to the diff plus the preferred height but we make sure not to cross the maximum height value we then revalidate to refresh the ui a negative diff is practically identical with the exception of making it zero or larger instead of using the minimum value we use the max method and with that the title folding is implemented the one last method in the class is this we use a custom toolbar that disables centered title the centered title places the title area in the center of the ui and it doesn\u0026rsquo;t work for folding we need to disable it for this form so the title acts correctly on ios\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/128-5-main-form/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 14: Creating a WhatsApp Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/csTtSj6TqRE?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003enow that we implemented the model code\nand the lifecycle code we are almost\nfinished we are down to ui code and css\nwe start with the main form which covers\nthe list of chat elements\nas is the case with all the forms in\nthis app\nwe derive from form for simplicity\nthe main body of the form is a tabs\ncomponent that allows us to switch\nbetween camera status and calls\ncamera kit is used to implement the\ncamera ui but due to a regression in the\nnative library this code is currently\ncommented out\nthere are the three tab containers\nwe make use of them in the scrolling\nlogic later\nthe main form is a singleton as we need\na way to refresh it when we are in a\ndifferent form\nthe form itself uses a border layout to\nplace the tabs in the center\nwe also save the form instance for later\nuse\nwe hide the tabs it generally means that\nthese aren\u0026rsquo;t actually tabs they are\nbuttons\nwe draw ourselves\nthe reason for that is the special\nanimation we need in the title area\nwe add the tabs and select the second\none as the default as we don\u0026rsquo;t want to\nopen with the camera view\ninstead of using the title we use title\ncomponent which may takes over the\nentire title area and lets us build\nwhatever we want up there\ni\u0026rsquo;ll discuss it more when covering that\nmethod\nthe back command of the form respects\nthe hardware back buttons and some\ndevices\nand the android native back arrow\nhere we have custom behavior for the\nform\nif we are in a tab other than the first\ntab we need to return to that tab\notherwise the app is minimized\nthis seems to be the behavior of the\nnative app\nthe calls container is a y-scrollable\ncontainer\nthis is simply a placeholder i placed\nhere a multi-button representing\nincoming outgoing calls and a floating\naction button\nthe same is true for the status\ncontainer this isn\u0026rsquo;t an important part\nof the functionality with this tutorial\nyou might recall that we invoke this\nmethod from the main ui to refresh\nthe ongoing chat status\nwe fetch up to\ndate data from storage this is an\nasynchronous call that returns on the\nedt so the rest of the code goes into\nthe\nlambda we remove the old content as\nwe\u0026rsquo;ll just read it\nwe loop over the contacts and for every\nnew contact we create a\nchat multi button with the given name\nif there is a tagline defined we set\nthat tagline we also use the large icon\nfor that per person\nif the button is clicked we show the\nchat form for this user\nthe chats container is the same as the\nother containers we saw but it\u0026rsquo;s\nactually fully implemented\nit invokes the refresh chats container\nmethod we previously saw previously saw\nin the order in order to fill up the\ncontainer\nand the floating action button here is\nactually implemented by showing the new\nmessage form\n[Music]\ncamera support is currently commented\nout due to a regression in the native\nlibrary however the concept is\nrelatively simple\nwe use the tab selection listener to\nactivate the camera as we need\nthe overflow menu is normally\nimplemented in the toolbar but since i\nwanted more control over the toolbar\narea i chose to implement it\nmanually in the code\ni used buttons with the command uiid and\ncontainer with the command list uid to\ncreate this ui\ni\u0026rsquo;ll discuss the css that created this\nin the next lesson\ni create a transparent dialog by giving\nit the container ui id\ni place the menu in the center\nthe dialog has no transition and\ndisposed\nif the user taps outside of it or uses\nthe back button\nthis disables the default darkening of\nthe form when a dialog is shown\nthis version of the show method places\nthe dialog with a fixed distance from\nthe edges\nwe give it a small margin on the top to\ntake the state status bar into account\nthen use left and bottom margin to push\nthe dialog to the top right side\nthis gives us a lot of flexibility and\nallows us to show the dialogue in any\nway we want\nthis method creates the title component\nfor the form\nwhich is this region\nthe method accepts the scrollable\ncontainers in the tabs container this\nallows us to track scrolling and\nseamlessly fold the title area\nthe title itself is just a label\nwith a title ui id\nit\u0026rsquo;s placed in the center of the title\narea border layout\nif we are on ios we want the title to be\ncentered\nin that case we need to use the center\nversion of the border layout the reason\nfor this is that center alignment\ndoesn\u0026rsquo;t know about the full layout and\nwould center based on available space\nit would ignore the search and overflow\nbuttons on the right when centering\nsince it isn\u0026rsquo;t aware of other components\nhowever using the center alignment and\nplacing these buttons in the east\nsolves that problem and gives us the\ncorrect title position\na search and overflow commands are just\nbuttons with the title and the title ui\nid\nwe already discussed the show overflow\nmenu method so this should be pretty\nobvious\nwe just placed the two buttons in the\ngrid\ni chose not to use a command as this\nmight create a misalignment for the this\nuse case and won\u0026rsquo;t have saved on the\namount of code i had to write\nthese are the tabs for selecting camera\nchat etc\nthere are just toggle buttons which in\nthis case are classified as radio\nbuttons\nthis means only one of the radio buttons\nwithin the button group can be selected\nwe give them all the subtitle ui id\nwhich again i\u0026rsquo;ll discuss in the next\nlesson\nwe use table layout to place the tabs\ninto the ui this allows us to explicitly\ndetermine the width of the columns\nnotice that the table layout has two\nrows\nthe second row of the table contains a\nwhite line\nusing the side title underline ui id\nthis line is placed in\nrow one and column one so it\u0026rsquo;s under the\nchats entry\nwhen we move between tabs this underline\nneeds to animate to the new position\nhere we bind the listeners to all four\nbuttons mapping to each tab\nwhen a button is clicked we select the\nappropriate tab\nthe next line two lines implement the\nunderline animation effect that we see\nwhen we click a button notice how the\nline animates to the right tab button\nto achieve this we remove the current\nwhite line\nand add it back\nto the toggle container in the right\nposition\nwe reset the height of the title in case\nit was shrunk during scrolling\nand we finally update the layout with an\nanimation which performs the actual line\nmove animation\nthe previous block updated the tab\nselection when we select a button\nthis block does the opposite\nit updates the button selection when we\nswipe the tabs\nit uses\na tab selection listener if the button\nisn\u0026rsquo;t selected then we need to update it\n[Music]\nagain we need to reset the title size\nnext we select the button that matches\nthe tab\n[Music]\nfinally we perform the animation of\nmoving the underline between tabs notice\nthat this is almost identical to the\nprevious animation code only in this\ncase it\u0026rsquo;s triggered by dragging the tabs\ninstead of the button click events\nthe last two lines in this method are\nthe bind folding call which we\u0026rsquo;ll\ndiscuss soon and the box layout y which\nwraps the two containers as one\nthe bind folding method implements this\nanimation of the folding title it\u0026rsquo;s\nimplemented by tracking pointer drag\nevents and shrinking the title\nwhen the pointer is released we need to\ncheck if the title shrunk enough to\nminimize it minimize or not enough so it\nwould go back to the full size\nif the title area height is different\nfrom the original height it means we are\nin the process of shrinking the title\nin that case we need to decide whether\nthe process is closer to the finish line\nor to the start\nit\u0026rsquo;s less than halfway to the height of\nthe title we reset the preferred size of\nthe title area that means the title area\nwill take up its original original\npreferred size and go back to full\nheight\notherwise we set the title area height\nto zero so it\u0026rsquo;s effectively hidden\nregardless of the choice we made above\nwe show it using an animation\nwe detect the drag operation by binding\na scroll listener to the three\nscrollable containers\ni could have used pointer drag listeners\nbut they might generate too much noise\nthat isn\u0026rsquo;t applicable\n[Music]\ni chose to make a special case for the\ntensile drag effect\nthe tensile effect\nin is the ios scroll behavior where a\ndrag extends beyond the top most part\nthen bounces back like a rubber band\nthis can cause a problem with the logic\nbelow so i decided that any scroll\nposition above 10 pixels should probably\nshow the full title\nnow that all of that is out of the way\nwe can calculate the direction of the\nscroll and shrink or grow the title area\nappropriately\nif the diff is larger than zero then the\ntitle area should grow\nwe\u0026rsquo;re setting the preferred height to\nthe diff plus the preferred height\nbut we make sure not to cross the\nmaximum height value\nwe then revalidate to refresh the ui\na negative diff is practically identical\nwith the exception of making it zero or\nlarger instead of using the minimum\nvalue we use the max method and with\nthat the title folding is implemented\nthe one last method in the class is this\nwe use a custom toolbar that disables\ncentered title\nthe centered title places the title area\nin the center of the ui and it doesn\u0026rsquo;t\nwork for folding\nwe need to disable it for this form so\nthe title acts correctly on ios\u003c/p\u003e","title":"5. Main Form"},{"content":" Module 14: Creating a WhatsApp Clone\nTranscript now that we looked at the first ui form let\u0026rsquo;s take a short detour via the css for the app i chose to go with css as it\u0026rsquo;s much easier for tutorials i can use sources instead of multiple screenshots to explain an idea the first selector is a constants selector it lets us define theme constants here we include two basic values that most apps should include include native ball indicates that we want the theme to derive from the native theme as a starting point this is essential as it defines a lot of important things such as the spacing on top of ios devices etc the scroll visible ball constant it hides the scroll bars that might show in some os\u0026rsquo;s pop-up dialog appears as an arrow dialogue on in ios but other os\u0026rsquo;s don\u0026rsquo;t implement it the pop-up dialog is used in the sign-up process for picking the country of sms verification the background color of the pop-up is white and implied implicitly defined as opaque we have a subtle rounded corners with a radius of one millimeter on the dialog you will notice zero margin as the dialog touches the edges but two millimeters in padding which space the content a bit from its edges label is pretty standard so i won\u0026rsquo;t spend too much time on that it\u0026rsquo;s just a two and a half millimeter light font multiline 1 is used to describe the first line of the multi button there isn\u0026rsquo;t much here just a light slightly larger font the one thing to notice is the zero padding on the bottom so the first line and the next line will be close together multi-line 2 is pretty similar to multiline one only with a slightly smaller font notice that the blue color of the text is derived from the native theme and isn\u0026rsquo;t declared here also also notice the one pixel grey border at the bottom of the multi-line multi-line three and four have zero padding and margin this removes potential error in spaces from the list of buttons the whole multi button is styled here to have a white background with no margin or padding notice that border is explicitly defined as none this is important as the multi button contains a line border and some native themes that would collide with the shorter border we want in this case the toolbar defines the background and the top of the form we give it a one pixel bottom border which is pretty similar to the border defined in the native app it\u0026rsquo;s very subtle when styling the title we should usually style the commands as well so they have similar proportions and alignment subtitle represents the four buttons below the title they are similar but have an off-white color are slightly smaller and are center center aligned toggle buttons use the press state to indicate selection in which case we want them to be white the subtitle underline is the animated small thin white line below the buttons this draws the full content of the component chat form uses the image as a background image notice the source dpi 0 argument which means we don\u0026rsquo;t want to use multi image for this for this specific case this just sets the color of the floating action button we use the text field in the signup form it\u0026rsquo;s added by the sms activation cn1 lib there\u0026rsquo;s nothing special about it however the chat text field is a separate component it uses a pull border to wrap its content technically this is a container that tracks the actual text field but it\u0026rsquo;s still perceived as a text field the icons within the text field are just simple font image icons with a specific color and very little margin the text field hint is just a great text for the text field and the record button has round border similar to the floating action button nothing special other than a bit of padding and margin to position it properly chat time represents the hour next to the message within the chat bubble it\u0026rsquo;s just gray and smallish we make sure it\u0026rsquo;s transparent so it can work on white or green backgrounds the same goes for the chat text with larger black font it\u0026rsquo;s still transparent for the same reason the bubble of the chat is implemented in code as a custom border i thought about using a nine piece border and this seemed like a better option i use margin on the right side to prevent the bubble from going too deep into the other side this seems close to what whatsapp is doing in their app the same is true for chat bubbles right with a different color and direction of the margin which is now spaced on the left side the command list is the style of the overflow menu i use box shadow which unfortunately produces a nine piece image border hopefully the css support will improve and use round wrecked border for this in the future notice there is a subtle border radius css attribute that rounds the corners of this dialog each entry here is a command they have a simple two milliliter millimeter padding with light font style the last style is day it maps to the day label making chats in a specific marking chat in a specific date we use the pull border with a bluish color with that the css is done\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/129-6-theme-css/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 14: Creating a WhatsApp Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/BbVoa3vw7OM?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003enow that we looked at the first ui form\nlet\u0026rsquo;s take a short detour via the css\nfor the app\ni chose to go with css as it\u0026rsquo;s much\neasier for tutorials\ni can use\nsources instead of multiple screenshots\nto explain an idea\nthe first selector is a constants\nselector it lets us define theme\nconstants\nhere we include two basic values\nthat most apps should include\ninclude native ball indicates that we\nwant the theme to derive from the native\ntheme as a starting point\nthis is essential as it defines a lot of\nimportant things such as the spacing on\ntop of ios devices etc\nthe scroll visible ball constant it\nhides the scroll bars that might show in\nsome os\u0026rsquo;s\npop-up dialog appears as an arrow\ndialogue on in ios but other os\u0026rsquo;s don\u0026rsquo;t\nimplement it the pop-up dialog is used\nin the sign-up process for picking the\ncountry of sms verification\nthe background color of the pop-up is\nwhite and implied implicitly\ndefined as opaque\nwe have a subtle rounded corners with a\nradius of one millimeter on the dialog\nyou will notice zero margin as the\ndialog touches the edges but two\nmillimeters in padding which space the\ncontent a bit from its edges\nlabel is pretty standard so i won\u0026rsquo;t\nspend too much time on that it\u0026rsquo;s just a\ntwo and a half millimeter light font\nmultiline 1 is used to describe the\nfirst line of the multi button\nthere isn\u0026rsquo;t much here just a light\nslightly larger font\nthe one thing to notice is the zero\npadding on the bottom so the first line\nand the next line will be close together\nmulti-line 2 is pretty similar to\nmultiline one\nonly with a slightly smaller font\nnotice that the blue color of the text\nis derived from the native theme and\nisn\u0026rsquo;t declared here\nalso also notice the one pixel grey\nborder at the bottom of the multi-line\nmulti-line three and four have zero\npadding and margin\nthis removes potential error in spaces\nfrom the list of buttons\nthe whole multi button is styled here to\nhave a white background with no margin\nor padding\nnotice that border is explicitly defined\nas none\nthis is important as the multi button\ncontains a line border and some native\nthemes\nthat would collide with the shorter\nborder we want in this case\nthe toolbar defines the background and\nthe top of the form we give it a one\npixel bottom border which is pretty\nsimilar to the border defined in the\nnative app\nit\u0026rsquo;s very subtle\nwhen styling the title we should usually\nstyle the commands\nas well so they have similar proportions\nand alignment\nsubtitle represents the four buttons\nbelow the title\nthey are similar but have an off-white\ncolor\nare slightly smaller and are center\ncenter aligned\ntoggle buttons use\nthe press state to indicate selection\nin which case we want them to be white\nthe subtitle underline is the animated\nsmall thin white line below the buttons\nthis draws the full content of the\ncomponent\nchat form uses the image as a background\nimage notice the source dpi 0 argument\nwhich means we don\u0026rsquo;t want to use multi\nimage for this for this specific case\nthis just sets the color of the floating\naction button\nwe use the text field in the signup form\nit\u0026rsquo;s added by the sms activation cn1 lib\nthere\u0026rsquo;s nothing special about it\nhowever the chat text field is a\nseparate component it uses a pull border\nto wrap its content\ntechnically this is a container that\ntracks the actual text field but it\u0026rsquo;s\nstill perceived as a text field\nthe icons within the text field are just\nsimple font image icons with a specific\ncolor and very little margin\nthe text field hint is just a great text\nfor the text field\nand the record button has round border\nsimilar to the floating action button\nnothing special other than a bit of\npadding and margin to position it\nproperly\nchat time represents the hour next to\nthe message\nwithin the chat bubble\nit\u0026rsquo;s just gray and smallish we make sure\nit\u0026rsquo;s transparent so it can work on white\nor green backgrounds\nthe same goes for the chat text with\nlarger black font it\u0026rsquo;s still transparent\nfor the same reason\nthe bubble of the chat is implemented in\ncode as\na custom border\ni thought about using a nine piece\nborder and this seemed like a better\noption\ni use margin on the right side to\nprevent the bubble from going too deep\ninto the other side this seems close to\nwhat whatsapp is doing in their app\nthe same is true for chat bubbles right\nwith a different color and direction of\nthe margin which is now spaced on the\nleft side\nthe command list is the style of the\noverflow menu\ni use box shadow which unfortunately\nproduces a nine piece image border\nhopefully the css support will improve\nand use round wrecked border for this in\nthe future\nnotice there is a subtle border radius\ncss attribute that rounds the corners of\nthis dialog\neach entry here is a command they have a\nsimple two milliliter millimeter padding\nwith light font style\nthe last style is day\nit maps to the day label making chats in\na specific marking chat in a specific\ndate we use the pull border with a\nbluish color with that the css is done\u003c/p\u003e","title":"6. Theme CSS"},{"content":" Module 14: Creating a WhatsApp Clone\nTranscript while we are on the subject of theming there is one missing piece we neglected in the theme css the chat bubble border implements the chat bubble appearance it extends the border class and is based on the code of round rect border from codename one i won\u0026rsquo;t go into the whole code as there is a lot here in fact it\u0026rsquo;s pretty similar to the special border i created for the uber clone module so i\u0026rsquo;ll just review the changes i did for this class i added two flags to indicate whether this border has a left pointing arrow or a right pointing pointed arrow these variables are exposed using setter methods like the rest of the set of methods in this class the create shape method is where we do the actual change to implement the arrow support the arrows are drawn by moving the pen further to the side to draw the respective arrows\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/130-7-bubble-border/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 14: Creating a WhatsApp Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/jR7_OTg-aG0?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ewhile we are on the subject of theming\nthere is one missing piece we neglected\nin the theme css\nthe chat bubble border implements the\nchat bubble appearance\nit extends the border class and is based\non the code of round rect border from\ncodename one\ni won\u0026rsquo;t go into the whole code as there\nis a lot here\nin fact it\u0026rsquo;s pretty similar to the\nspecial border i created for the uber\nclone module\nso i\u0026rsquo;ll just review the changes i did\nfor this class\ni added two flags to indicate whether\nthis border has a left pointing arrow or\na right pointing pointed arrow\nthese variables are exposed using setter\nmethods like the rest of the set of\nmethods in this class\nthe create shape method is where we do\nthe actual change to implement the arrow\nsupport\nthe arrows are drawn by moving the pen\nfurther to the side to draw the\nrespective arrows\u003c/p\u003e","title":"7. Bubble Border"},{"content":" Module 14: Creating a WhatsApp Clone\nTranscript the next step is the actual chat form the chat form is a form like the main form we discussed earlier a chat with a specific contact which is passed in the constructor as we saw in the previous main form we also have a getter for this property which we used in the main class to check if the current chat contact matches the one in the incoming message this is a common constant i use a lot to represent a single day in milliseconds it\u0026rsquo;s convenient it\u0026rsquo;s probably probably should have been static as well this is the date format used to represent the day label here this indicates whether the blue label that says today was added if not when we type in the first message to we need to add a label indicating that this message was sent today the chat form uses the y last box layout this is a special type of box layout y where the last component is pushed to the bottom of the form so here we will use that position for the text field historically i used to build apps like this with border layout and place the text field in the south both approaches are good with different trade-offs for each this approach has the downside of hiding the chat text field when scrolling up which is inconsistent with where whatsapp works so you might want to revisit this with a border layout if you want that behavior we use the chat form uiid for the background image of the form here we use a standard title with the back arrow to navigate to the previous form these are all the standard comment commands that appear in the whatsapp application i didn\u0026rsquo;t implement them and just added them to create a similar design the input container is this we just add it to the box layout y since it\u0026rsquo;s in the last mode it will glue itself to the bottom as long as it\u0026rsquo;s the last component from now on we\u0026rsquo;ll need to add all components before that component in the container now we go over the existing chats so the ui opens with the content of previous chats stored on the phone each chat has a time time is represented in milliseconds since epoch which uh is january 1st 2009 sorry 1970. we use that to divide the time by constant the constant we have for day this will give us a number that represents a day since 1970. we can then check if the time from one chat is from the same day or from a different day this can be tested with a simple not equals test notice i could have used code based on java util calendar to do this test but i think this approach is both faster and simpler in both cases we use add date to add this label before we add the chat content for a specific day we then add a message to the ui normally when we add a component to the ui we need to animate or revalidate the ui so it will show the component however since this code is running before the form is shown we don\u0026rsquo;t want such an animation as it might collide with the transition the show listener is invoked when a form is actually shown here we can do things that will happen only after the form becomes visible notice i used an anonymous inner class instead of a lambda expression here this is the reason we can remove the show listener using this command if it\u0026rsquo;s an anonymous inner class but we can\u0026rsquo;t remove it if it\u0026rsquo;s a lambda as this will map to the chat form instance this is why we need this listener in the first place this scrolls down to the last component it\u0026rsquo;s important to do this after the form is shown because if it\u0026rsquo;s done before some components could still be laid out incorrectly the add day method adds the day label if necessary there are some nuances to this beyond the label alone first we need to check if today is the current day since every day has a number associated with it as we discussed before this is pretty easy if the day is today then we need to add that special case label we also need to flip the flag indicating that it was added this boolean flag is a special case that we will discuss later there is another slightly simpler special case for yesterday showing the previous day with a special matching label otherwise we use the formatter we declared at the top of the class to generate the text of the day label we create a label with the right style and add it before the text input component which brings us to the input container i mentioned before this method creates that container which includes everything in this line including the microphone button the container starts with a text field where the messages can be typed there are two important features we need in this text field first we don\u0026rsquo;t want a border we\u0026rsquo;ll set the border to the parent container which we defined as a pill border in the css second we want this to be a multi-line text field this allows us to type in longer messages and review them however it means that enter won\u0026rsquo;t map to sending the done listener is the first way to send a message it can be triggered by using the device virtual keyboard when pressing done this adds the message to the ui and it does that with an animation that lays out the message on the form after adding the message we want to clear the text so we stop the editing process and set the text to an empty string this would have worked had we not stopped the edit wouldn\u0026rsquo;t have worked had we not stopped the editing these are the three buttons we see next to the text field here the text field is between them and not under them it just has no border the round pill border is a container that surrounds the buttons and the text field i\u0026rsquo;ll talk about attachments soon this isn\u0026rsquo;t fully implemented but i\u0026rsquo;ll cover this when we reach these methods the input container wraps these three buttons and the text field we give it the chat text field uiid which includes the perl border finally microphone has the record button design there is a partial partial worker for voice recording when we override pointer pressed we can do use the media recorder to start voice recording and stop stop it in pointer released i eventually didn\u0026rsquo;t get around to doing that if there is text in the input field the microphone icon becomes a send icon here we use the data change listener to track that and update the icon on the fly the action listener is only applicable when the microsoft microphone is in send mode it\u0026rsquo;s used to send the text in the text field this code is effectively identical to the code we saw earlier in the method it might make sense to generalize this block finally this method returns a border layout that pairs together the input container and the microphone as a single container this is a utility method i use quite often to write a number as two digits it\u0026rsquo;s useful for formatting hours so a number like 1 will be written as 0 1 and etc the logic is trivial if a number is smaller than 10 return it with a 0 prepended to it otherwise return the number as a string i make use of this method in the time formatting method below this method formats the time as hours and minutes used to display the hour next to the message this method just gets the hour and minutes from the calendar class and formats them as two digits with a colon in the middle we saw the add message method invoked when the user types a new message it\u0026rsquo;s pretty simple as most of the logic in this method is delegated to the following add message to ui no animation method but it does contain a couple of interesting bits this is why we have the today added flag if this flag isn\u0026rsquo;t set we need to add today to the dates before adding a new message this method does the heavy lifting of adding a message to the ui here we animate the addition notice i used an and weight variant of the method it\u0026rsquo;s so the scroll component to visible below will work this won\u0026rsquo;t work during the animation as the position wouldn\u0026rsquo;t be correct at that point this is the method that actually adds chat bubbles to the ui this is the logic to determine if the bubble goes in the right or left i use this logic so it will work even with groups i could have simplified it if there were only two options the main difference between the left and right chat bubble is the ui id as i mentioned in the theme the actual component placed in the chat is created by a separate method if this is a media component we\u0026rsquo;ll call create media message and if it\u0026rsquo;s a text message we use create text message the rest of this method styles the result of that method the component uses the chat bubble however we need to know whether the component should have an arrow or not notice that if we have two chat bubbles one on top the other and and the other from the same sender the second bubble doesn\u0026rsquo;t have an arrow this is true for both sides of the conversation however if we have a message from someone else then the arrow returns the this block tries to implement that logic by detecting this situation the first condition is meant to detect a chat with no components in it in this case the arrow must be shown so we can easily set the arrow on the correct side by using the left boolean variable to determine that otherwise we need to dig through the components we already added the last component is the input component so we need to look at the components before that to align chat bubbles correctly we use container wrapped wrapper so the previous container is a container we exact the child the first child of that container and save it into cnt cnt is now the previous component if the ui id of the previous component matches our current ui id it means that the previous component pinpointed to the same side pointed to the same side that means we don\u0026rsquo;t need an arrow if the uids aren\u0026rsquo;t identical the arrow needs to point into one of these directions this is another special case when the arrow is removed we also want less space between the chat bubbles this is a small nuance of the app that helps associate uh the components as part of the same conversation we wrap the component in a flow layout so it will align correctly to the left or right side we set the ui id to the ui id we picked at the beginning of the method we add the component to the offset just before the input component we stole the message itself we store the message itself as a client property in the component this makes it easier to implement features such as search as we can easily determine the business object related to a specific component finally we set the border to the component and return the container instance this version of the method does all of that but also sends the message to the server this is the version of the method we invoke when a user types a message this is the method that creates the components for a text message as you recall we have two methods one for text and one for images we use a text area to represent the text it\u0026rsquo;s more direct than span label which is technically just a text area wrapped in a container act as label removes some optimizations from the text area so the text is laid out accurately it can make a it\u0026rsquo;s slightly slower to render though we block editing and focus so a user can\u0026rsquo;t interact with the text area we set the ui id to chat text so it will use the right font and colors time is the label with the current time for this message it uses the chat time style time is the label with the current time for this message it uses the chat time style notice that short messages place the time next to the text whereas long messages place it below i chose to use the 30 character mark to decide this a better strategy might have been to calculate preferred size in some way and decide based on that but i wanted to keep things simple so i chose this approach finally we returned the bubble container that includes the text and the time the media message is similar but it uses the media file url right now the method is designed only to work with images but this can probably be fixed relatively easily we open a fast stream for the media we calculate a desired size for the media which is half the size of the portrait screen we load the image then scale it into a button as the icon of that button once there we enclose it in a layered layout so the time is overlaid at the bottom right of the layered layout as you might recall the open camera method was mapped as a listener to this button it\u0026rsquo;s a simple method that invokes capture and then adds the result as a message the last method in the class is open file which is effectively identical it uses the file chooser cn1 lib api and maps to the attach button it allows opening all files but in order for this to work we need to process all file types however i only implemented image support as i did in the previous method\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/131-8-chat-form/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 14: Creating a WhatsApp Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/65jD9oGw61w?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ethe next step is the actual chat form\nthe chat form is a form like the main\nform we discussed earlier\na chat with a specific contact which is\npassed in the constructor as we saw in\nthe previous main form\nwe also have a getter for this property\nwhich we used in the main class to check\nif the current chat contact matches the\none in the incoming message\nthis is a common constant i use a lot to\nrepresent a single day in milliseconds\nit\u0026rsquo;s convenient it\u0026rsquo;s probably probably\nshould have been static as well\nthis is the date format used to\nrepresent the day label here\nthis indicates whether the blue label\nthat says today\nwas added\nif not\nwhen we type in the first message to we\nneed to add a label\nindicating that this message was sent\ntoday\nthe chat form uses the y last box layout\nthis is a special type of box layout y\nwhere the last component is pushed to\nthe bottom of the form\nso here\nwe will use that position for the text\nfield\nhistorically i used to build apps like\nthis with border layout and place the\ntext field in the south\nboth approaches are good with different\ntrade-offs for each\nthis approach has the downside of hiding\nthe chat text field when scrolling up\nwhich is inconsistent with where\nwhatsapp works\nso you might want to revisit this with a\nborder layout if you want that behavior\nwe use the chat form uiid for the\nbackground image of the form\nhere we use a standard title with the\nback arrow to navigate to the previous\nform\nthese are all the standard comment\ncommands that appear in the whatsapp\napplication\ni didn\u0026rsquo;t implement them and just added\nthem to create a similar design\nthe input container is this\nwe just add it to the box layout y since\nit\u0026rsquo;s in the last mode\nit will glue itself to the bottom as\nlong as it\u0026rsquo;s the last component\nfrom now on we\u0026rsquo;ll need to add all\ncomponents before that component in the\ncontainer\nnow we go over the existing chats so the\nui opens\nwith the content of previous chats\nstored on the phone\neach chat has a time\ntime is represented in milliseconds\nsince epoch which uh is january 1st 2009\nsorry 1970.\nwe use that to divide the time by\nconstant the constant we have for day\nthis will give us a number that\nrepresents a day since 1970.\nwe can then check if the time from one\nchat is from the same day or from a\ndifferent day this can be tested with a\nsimple not equals test\nnotice i could have used code based on\njava util calendar to do this test but i\nthink this approach is both faster and\nsimpler\nin both cases we use add date to add\nthis label before we add the chat\ncontent for a specific day\nwe then add a message to the ui\nnormally when we add a component to the\nui we need to animate or revalidate the\nui so it will show the component\nhowever since this code is running\nbefore the form is shown we don\u0026rsquo;t want\nsuch an animation as it might collide\nwith the transition\nthe show listener is invoked when a form\nis actually shown\nhere we can do things that will happen\nonly after the form becomes visible\nnotice i used an anonymous inner class\ninstead of a lambda expression here\nthis is the reason\nwe can remove the show listener using\nthis command\nif it\u0026rsquo;s an anonymous inner class but we\ncan\u0026rsquo;t remove it if it\u0026rsquo;s a lambda as this\nwill map to the chat form instance\nthis is why we need this listener in the\nfirst place\nthis scrolls down to the last component\nit\u0026rsquo;s important to do this after the form\nis shown\nbecause if it\u0026rsquo;s done before some\ncomponents could still be laid out\nincorrectly\nthe add day method adds the day label if\nnecessary there are some nuances to this\nbeyond the label alone\nfirst we need to check if today is the\ncurrent day\nsince every day has a number associated\nwith it as we discussed before this is\npretty easy\nif the day is today then we need to add\nthat special case label\nwe also need to flip the flag indicating\nthat it was added\nthis boolean flag is a special case that\nwe will discuss later\nthere is another slightly simpler\nspecial case for yesterday showing the\nprevious day with a special matching\nlabel\notherwise we use the formatter we\ndeclared at the top of the class to\ngenerate the text of the day label\nwe create a label with the right style\nand add it before the text input\ncomponent\nwhich brings us to the input container i\nmentioned before\nthis method creates that container which\nincludes everything in this line\nincluding the microphone button\nthe container starts with a text field\nwhere the messages can be typed\nthere are two important features we need\nin this text field first we don\u0026rsquo;t want a\nborder\nwe\u0026rsquo;ll set the border to the parent\ncontainer which we defined as\na pill border in the css\nsecond we want this to be a multi-line\ntext field\nthis allows us to type in longer\nmessages and review them\nhowever it means that enter won\u0026rsquo;t map to\nsending\nthe done listener is the first way to\nsend a message it can be triggered by\nusing the device virtual keyboard when\npressing done\nthis adds the message to the ui and it\ndoes that with an animation that lays\nout the message on the form\nafter adding the message we want to\nclear the text so we stop the editing\nprocess and set the text to an empty\nstring\nthis would have worked had we not\nstopped the edit wouldn\u0026rsquo;t have worked\nhad we not stopped the editing\nthese are the three buttons we see next\nto the text field here\nthe text field is between them and not\nunder them\nit just has no border\nthe round pill border is a container\nthat surrounds the buttons and the text\nfield\ni\u0026rsquo;ll talk about attachments soon this\nisn\u0026rsquo;t fully implemented but i\u0026rsquo;ll cover\nthis when we reach these methods\nthe input container wraps these three\nbuttons and the text field\nwe give it the chat text field uiid\nwhich includes the perl border\nfinally microphone has the record button\ndesign\nthere is a partial partial worker for\nvoice recording when we override pointer\npressed we can do use the media recorder\nto start voice recording and stop stop\nit in pointer released i eventually\ndidn\u0026rsquo;t get around to doing that\nif there is text in the input field the\nmicrophone icon becomes a send icon here\nwe use the data change listener to track\nthat and update the icon on the fly\nthe action listener is only applicable\nwhen the microsoft microphone is in send\nmode it\u0026rsquo;s used to send the text in the\ntext field\nthis code is effectively identical to\nthe code we saw earlier in the method it\nmight make sense to generalize this\nblock\nfinally this method returns a border\nlayout that pairs together the input\ncontainer and the microphone as a single\ncontainer\nthis is a utility method i use quite\noften\nto write a number as two digits it\u0026rsquo;s\nuseful for formatting hours so a number\nlike\n1 will be written as 0 1 and etc\nthe logic is trivial if a number is\nsmaller than 10\nreturn it with a 0 prepended to it\notherwise return the number as a string\ni\nmake use of this method in the time\nformatting method below\nthis method formats the time as hours\nand minutes used to display the hour\nnext to the message\nthis method just gets the hour and\nminutes from the calendar class and\nformats them as two digits with a colon\nin the middle\nwe saw the add message method invoked\nwhen the user types a new message\nit\u0026rsquo;s pretty simple as most of the logic\nin this method\nis\ndelegated to the following add message\nto ui no animation method\nbut it does contain a couple of\ninteresting bits\nthis is why we have the today\nadded flag\nif this flag isn\u0026rsquo;t set we need to add\ntoday to the dates before adding a new\nmessage\nthis method does the heavy lifting of\nadding a message to the ui\nhere we animate the addition notice i\nused an and weight variant of the method\nit\u0026rsquo;s so the scroll component to visible\nbelow will work this won\u0026rsquo;t work during\nthe animation as the position wouldn\u0026rsquo;t\nbe correct at that point\nthis is the method that actually adds\nchat bubbles to the ui\nthis is the logic to determine if the\nbubble goes\nin the right or left i\nuse this logic\nso it will work even with groups\ni could have simplified it if there were\nonly two options\nthe main difference between the left and\nright chat bubble is the ui id as i\nmentioned\nin the theme\nthe actual component placed in the chat\nis created by a separate method\nif this is a media component we\u0026rsquo;ll call\ncreate media message\nand if it\u0026rsquo;s a text message we use create\ntext message the rest of this method\nstyles the result of that method\nthe component uses the chat bubble\nhowever we need to know whether the\ncomponent should have an arrow or not\nnotice that if we have two chat bubbles\none on top the other\nand and the other from the same sender\nthe second bubble doesn\u0026rsquo;t have an arrow\nthis is true for both sides of the\nconversation\nhowever if we have a message from\nsomeone else\nthen the arrow returns\nthe this block tries to implement that\nlogic by detecting this situation\nthe first condition is meant to detect a\nchat with no components in it in this\ncase the arrow must be shown so we can\neasily set the arrow on the correct side\nby using the left boolean variable to\ndetermine that\notherwise\nwe need to dig through the components\nwe already added the last component is\nthe input component so we need to look\nat the components before that\nto align chat bubbles correctly we use\ncontainer wrapped\nwrapper so the previous container is a\ncontainer\nwe exact the child\nthe first child of that container and\nsave it into cnt\ncnt is now the previous component if the\nui id of the previous component matches\nour current ui id it means that the\nprevious component\npinpointed to the same side\npointed to the same side that means we\ndon\u0026rsquo;t need an arrow\nif the uids aren\u0026rsquo;t identical the arrow\nneeds to point\ninto one of these directions\nthis is another special case\nwhen the arrow is removed we also want\nless space between the chat bubbles this\nis a small nuance of the app\nthat helps associate\nuh the components as part of the same\nconversation\nwe wrap the component in a flow layout\nso it will align correctly to the left\nor right side\nwe set the ui id to the ui id we picked\nat the beginning of the method\nwe add the component\nto the offset just before the input\ncomponent\nwe stole the message itself\nwe store the message itself as a client\nproperty in the component\nthis makes it easier to implement\nfeatures such as search as we can easily\ndetermine the business object related to\na specific component\nfinally we set the border to the\ncomponent and return the container\ninstance\nthis version of the method does all of\nthat but also sends the message to the\nserver\nthis is the version of the method we\ninvoke when a user types a message\nthis is the method that creates the\ncomponents for a text message\nas you recall we have two methods one\nfor text and one for images\nwe use a text area to represent the text\nit\u0026rsquo;s more direct than span label which\nis technically just a text area wrapped\nin a container\nact as label removes some optimizations\nfrom the text area\nso the text is laid out accurately\nit can make a it\u0026rsquo;s slightly slower\nto render though\nwe block editing and focus so a user\ncan\u0026rsquo;t interact with the text area\nwe set the ui id to chat text so it will\nuse the right font and colors\ntime is the label with the current time\nfor this message\nit uses the chat time style\ntime is the label with the current time\nfor this message it uses the chat time\nstyle\nnotice that short messages place the\ntime next to the text whereas long\nmessages place it below i chose to use\nthe 30 character mark to decide this\na better strategy might have been to\ncalculate preferred size in some way and\ndecide based on that but i wanted to\nkeep things simple so i chose this\napproach\nfinally we returned the bubble container\nthat includes the text and the time\nthe media message is similar but it uses\nthe media file url right now the method\nis designed only to work with images but\nthis can probably be fixed relatively\neasily\nwe open a fast stream for the media\nwe calculate a desired size for the\nmedia which is half the size of the\nportrait screen\nwe load the image then scale it into a\nbutton as the icon of that button\nonce there we enclose it in a layered\nlayout so the time is overlaid at the\nbottom right of the layered layout\nas you might recall the open camera\nmethod was mapped as a listener to this\nbutton\nit\u0026rsquo;s a simple method that invokes\ncapture and then adds the result as a\nmessage\nthe last method in the class is open\nfile which is effectively identical\nit uses the file chooser cn1 lib api and\nmaps to the attach button\nit allows opening all files but in order\nfor this to work we need to process all\nfile types\nhowever i only implemented image support\nas i did in the previous method\u003c/p\u003e","title":"8. Chat Form"},{"content":" Module 14: Creating a WhatsApp Clone\nTranscript the final part discussing the client-side code covers the new message form class New Message Form new message form is a form we see when we press the floating action button in the main form the class is trivial by comparison to previous the previous class it\u0026rsquo;s just a box layout y form that lets us pick a contact we wish to chat with the new group and contact buttons aren\u0026rsquo;t currently mapped to anything they\u0026rsquo;re just simple buttons List of Contacts we use the fetch contacts method to fetch the list of contacts to show here for every contact in the list of contacts we create a multi button matching the name and icon Contact Check if a contact is clicked we check if he has an id if not this is someone that might not be in the app yet so we need to contact the server and check the find registered user finds the specific user based on his phone number if we get null as a result it means this is no such registered user in the app we go back to the previous form and show a toast bar message there if there is we update the user id and save we can then launch the chat form with this new contact Launch Chat Form since the multi buttons are added asynchronously we need to revalidate so they will show on the form as i said this is a super simple short class and with that we finished the client side work\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/132-9-the-new-message-form/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 14: Creating a WhatsApp Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/0ETli_N__ZY?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ethe final part discussing the\nclient-side code covers the new message\nform class\nNew Message Form\nnew message form\nis a form we see when we press the\nfloating action button\nin the main form\nthe class is trivial by comparison to\nprevious the previous class it\u0026rsquo;s just a\nbox layout y form that lets us pick a\ncontact we wish to chat with\nthe new group and contact buttons aren\u0026rsquo;t\ncurrently mapped to anything they\u0026rsquo;re\njust simple buttons\nList of Contacts\nwe use the fetch contacts method to\nfetch the list of contacts to show here\nfor every contact in the list of\ncontacts we create a multi button\nmatching the name and icon\nContact Check\nif a contact is clicked we check if he\nhas an id\nif not this is someone that might not be\nin the app yet\nso we need to contact the server and\ncheck\nthe find registered user\nfinds the specific user based on his\nphone number\nif we get null as a result it means this\nis no such registered user in the app\nwe go back to the previous form and show\na toast bar message there\nif there is we update the user id and\nsave\nwe can then launch the chat form with\nthis new contact\nLaunch Chat Form\nsince the multi buttons are added\nasynchronously we need to revalidate so\nthey will show on the form\nas i said this is a super simple short\nclass and with that we finished the\nclient side work\u003c/p\u003e","title":"9. The New Message Form"},{"content":" Module 14: Creating a WhatsApp Clone\nTranscript we are finally back to the spring boot server we set up initially the code here is pretty simple as well the whatsapp application is the boilerplate main class of the spring boot project there isn\u0026rsquo;t much here and i\u0026rsquo;m only mentioning it for completeness security configuration is a bit more interesting although again it\u0026rsquo;s similar to what we saw in previous projects first we need to permit all requests to remove some http security limits we don\u0026rsquo;t need them here since this isn\u0026rsquo;t a web app similarly we need to disable csrf protection as it isn\u0026rsquo;t applicable for native apps finally we need to provide password encoder implementation we use this to encrypt the tokens in the database next let\u0026rsquo;s go into the entity objects i won\u0026rsquo;t go into what entities are as i discussed them a lot in the previous modules they are effectively an abstraction of the underlying data store the user entity represents the data we save for a chat contact i use a string unique id with a universal unique identifier which is more secure as i mentioned before it might make sense to use the phone as the id value though the username and tagline are also stored similarly to the client side code phone is listed as unique which makes sure the value is unique in the database when we send a verification code we store it in a database i could use a distributed caching system like redis or memcached but they\u0026rsquo;re an overkill for something as simple as this the date in which the user end entry was created is a standard database date this isn\u0026rsquo;t used at this time but it\u0026rsquo;s very similar to the code we have in the facebook clone to store media in fact it\u0026rsquo;s copied from there and we can refer to that for media storage slash upload the auth token is effectively a combination of username and password as such it\u0026rsquo;s hashed and as such only the user device knows that value i believe that\u0026rsquo;s how whatsapp works that\u0026rsquo;s why only one device can connect to a whatsapp account since the token is hashed when you need to retrieve an access token you need to effectively delete the last token and create a new one in order to set up a hash for the uninitiated a hash is an encrypted value that can only be generated but not retrieved so if my password is password and the hash is x y z j k l then i can get the value of the password from the hash but i can check that and i can check that password matches x y z jko but not vice versa hashes are also salted so they have 60 characters and length and the strong hashes are impossible to crack with standard tools the push key is the key used to send push messages to the client device this flag indicates whether a user is verified when we create a new user we initialize the id and creation date sensibly if this entity is loaded from the database these values will be overridden the dow methods create data access objects that we can send to the client we will make use of them later in the service code the user repository maps to the user object and exposes three finder methods we use find by phone during sign up and sending to detect the user with the given phone this method should be removed as it\u0026rsquo;s part of the copy and pasted media entity code we need to find the put the push by push key in order to remove or update expired push keys if the server returns an error we need to update that user dao is pretty much the content of the user class there isn\u0026rsquo;t much to discuss here with one major exception and that\u0026rsquo;s the json format annotation here we explicitly declare how we want the date object to translate to json when it\u0026rsquo;s sent to the client this is the standard json pattern and codename one in the client side knows how to parse this you\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/133-10-server-entities/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 14: Creating a WhatsApp Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/Rok0Ubr4xes?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ewe are finally back to the spring boot\nserver we set up initially\nthe code here is pretty simple as well\nthe whatsapp application is the\nboilerplate main class of the spring\nboot project there isn\u0026rsquo;t much here and\ni\u0026rsquo;m only mentioning it for completeness\nsecurity configuration is a bit more\ninteresting\nalthough again it\u0026rsquo;s similar to what we\nsaw in previous projects\nfirst we need to permit all requests to\nremove some http security limits\nwe don\u0026rsquo;t need them here since this isn\u0026rsquo;t\na web app\nsimilarly we need to disable csrf\nprotection as it isn\u0026rsquo;t applicable for\nnative apps\nfinally we need to provide password\nencoder implementation\nwe use this to encrypt the tokens in the\ndatabase\nnext let\u0026rsquo;s go into the entity objects i\nwon\u0026rsquo;t go into what entities are as i\ndiscussed them a lot in the previous\nmodules they are effectively an\nabstraction of the underlying data store\nthe user entity represents the data\nwe save for a chat contact\ni use a string unique id with a\nuniversal unique identifier which is\nmore secure as i mentioned before\nit might make sense to use the phone as\nthe id value though\nthe username and tagline are also stored\nsimilarly to the client side code\nphone is listed as unique which makes\nsure the value is unique in the database\nwhen we send a verification code we\nstore it in a database i could use a\ndistributed caching system like redis or\nmemcached but they\u0026rsquo;re an overkill for\nsomething as simple as this\nthe date in which the user end entry was\ncreated is a standard database date\nthis isn\u0026rsquo;t used at this time but it\u0026rsquo;s\nvery similar to the code we have in the\nfacebook clone to store media\nin fact it\u0026rsquo;s copied from there and we\ncan refer to that for media storage\nslash upload\nthe auth token is effectively a\ncombination of username and password\nas such it\u0026rsquo;s hashed and as such only the\nuser\ndevice knows that value\ni believe that\u0026rsquo;s how whatsapp works\nthat\u0026rsquo;s why only one device can connect\nto a whatsapp account since the token is\nhashed when you need to retrieve an\naccess token you need to effectively\ndelete the last token and create a new\none in order to set up a hash\nfor the uninitiated a hash is an\nencrypted value that can only be\ngenerated but not retrieved so if my\npassword is password and the hash is x y\nz j k l\nthen i can get the value of the password\nfrom the hash\nbut i can check that and i can check\nthat password matches\nx y\nz jko\nbut not vice versa\nhashes are also\nsalted so they have 60 characters and\nlength and the strong hashes are\nimpossible to crack with standard tools\nthe push key is the key used to send\npush messages to the client device\nthis flag indicates whether a user is\nverified\nwhen we create a new user we initialize\nthe id and creation date sensibly\nif this entity is loaded from the\ndatabase these values will be overridden\nthe dow methods create data access\nobjects\nthat we can send to the client\nwe will make use of them later in the\nservice code\nthe user repository maps to the user\nobject and exposes three finder methods\nwe use find by phone\nduring sign up and sending to detect the\nuser with the given phone\nthis method should be removed as it\u0026rsquo;s\npart of the copy and pasted media entity\ncode\nwe need to find the put the push by push\nkey in order to remove or update expired\npush keys\nif the server returns an error we need\nto update that\nuser dao is pretty much the content of\nthe user class there isn\u0026rsquo;t much to\ndiscuss here with one major exception\nand that\u0026rsquo;s the json format annotation\nhere we explicitly declare how we want\nthe date object to translate to json\nwhen it\u0026rsquo;s sent to the client\nthis is the standard json pattern and\ncodename one in the client side knows\nhow to parse\nthis you\u003c/p\u003e","title":"10. Server Entities"},{"content":" Module 14: Creating a WhatsApp Clone\nTranscript let\u0026rsquo;s continue with the other entities i\u0026rsquo;ll skip media as it\u0026rsquo;s just a copy and paste of the facebook media class and partially implemented to boot chat group is an entity that traps the concept of a group in a sense it\u0026rsquo;s similar to the user entity but has no phone all of these properties the id name tagline creation date and even avatar are a part of a group however unlike a regular user a group is effectively created by a user a group also has two lists of group administrators and group members the chat group repository is empty as this is a feature we didn\u0026rsquo;t finish a chat message must be stored on servers for a while if your device isn\u0026rsquo;t connected at this moment for instance flight the server would need to keep the message until you are available again it can then be purged if we wish to be very secure we can encrypt the message based on client public key that way no one in the middle could peek into that message this should be easy enough to implement but i didn\u0026rsquo;t get around to to it it would mostly be client-side work here we store message messages so they can be fetched by the app like everything else we have a unique string id per message every message naturally has an author of that message but most importantly a destination which can be either a different user or group not both every message has a date timestamp for when it was sent the message has a text body always it can be now though if we have a media attachment to the message the ack flag indicates whether the client acknowledges acknowledged receiving the message this works great for one-to-one messages but the message sent to a group would probably need a more elaborate ack implementation the dao is again practically copied from the facebook app we can include the ids for the attachments as part of the message the chat message repository includes one fine method which helps us find messages that we didn\u0026rsquo;t acknowledge yet if a specific user has pending messages this finder is used to locate such messages and send them again the message dao entry represents the current message it maps pretty accurately to the entity object with that effectively done with the entity and dow layers there is still an error dial but it\u0026rsquo;s effectively identical to what we had in the facebook app and it\u0026rsquo;s totally trivial so i\u0026rsquo;ll skip that\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/134-11-server-dao-and-entities/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 14: Creating a WhatsApp Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/BSj3KRM5Sj0?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003elet\u0026rsquo;s continue with the other entities\ni\u0026rsquo;ll skip media as it\u0026rsquo;s just a copy and\npaste of the facebook media class and\npartially implemented to boot\nchat group is an entity that traps the\nconcept of a group\nin a sense it\u0026rsquo;s similar to the user\nentity but has no phone\nall of these properties the id name\ntagline creation date and even avatar\nare a part of a group\nhowever unlike a regular user a group is\neffectively created by a user\na group also has two lists of group\nadministrators and group members\nthe chat group repository is empty as\nthis is a feature we didn\u0026rsquo;t finish\na chat message must be stored on servers\nfor a while\nif your device isn\u0026rsquo;t connected at this\nmoment for instance flight\nthe server would need to keep the\nmessage until you are available again\nit can then be purged\nif we wish to be very secure we can\nencrypt the message based on client\npublic key that way no one\nin the middle could peek into that\nmessage\nthis should be easy enough to implement\nbut i didn\u0026rsquo;t get around to to it\nit would mostly be client-side work\nhere we store message messages so they\ncan be fetched by the app\nlike everything else we have a unique\nstring id per message\nevery message naturally has an author of\nthat message\nbut most importantly a destination which\ncan be either a different user or group\nnot both\nevery message has a date timestamp for\nwhen it was sent\nthe message has a text body always\nit can be now though\nif we have a media attachment to the\nmessage\nthe ack flag indicates whether the\nclient acknowledges acknowledged\nreceiving the message\nthis works great for one-to-one messages\nbut the message sent to a group would\nprobably need a more elaborate ack\nimplementation\nthe dao is again practically copied from\nthe facebook app\nwe can include the ids for the\nattachments as part of the message\nthe chat message repository includes one\nfine method which helps us find messages\nthat we didn\u0026rsquo;t acknowledge yet\nif a specific user has pending messages\nthis finder is used to locate such\nmessages and send them again\nthe message dao entry represents the\ncurrent message\nit maps pretty accurately to the entity\nobject\nwith that effectively done with the\nentity and dow layers\nthere is still an error dial but it\u0026rsquo;s\neffectively identical to what we had in\nthe facebook app\nand it\u0026rsquo;s totally trivial so i\u0026rsquo;ll skip\nthat\u003c/p\u003e","title":"11. Server DAO and Entities"},{"content":" Module 14: Creating a WhatsApp Clone\nTranscript the next step is the services layer which implements the relatively simple business layer of this application we\u0026rsquo;ll start with the user service class it\u0026rsquo;s the main class in this package and handles pretty much the entire business logic of the app it\u0026rsquo;s a service bean this means it handles generic business logic for the application we need access to the repositories we just defined for users groups and messages the api keys service is the exact one i used in facebook with the exception of a different properties file name i\u0026rsquo;ll discuss that later it generally abstracts api keys and separates them from the source code the password encoder is used to encrypt and verify the token media repository and notification servers are identical to the stuff we had in the facebook clone app this method sends an sms message via the twillow web service if you recall we added the twillow sdk into the pom file in the first lesson this sdk makes sending an sms message very easy as you can see from the code the login api lets us validate a user and get the current data the server has for that user since there is no username slash password we need to use the token to authenticate first we need to find the user with the given phone assuming the user isn\u0026rsquo;t there will throw an exception since the auth is hashed as we discussed before we need to test the incoming auth via the matches method in encoder it verifies the hash matches the auth token this method creates a string of the given length which includes a random number for verification signup creates an entry for a specific user but doesn\u0026rsquo;t activate the account until it\u0026rsquo;s verified we first check if the phone number is already registered if so we need to fail otherwise we create the new user and initialize the value of the data and the verification code finally we send the activation code and return the user entity the verify method activates a user account if the verification mode is correct we mark the user as verified and return true we use set props both from the sign up and update methods there isn\u0026rsquo;t much here but if we add additional metadata this might become a bigger method like it is and the facebook clone update verifies the user\u0026rsquo;s token then updates the properties there isn\u0026rsquo;t much here these aren\u0026rsquo;t used at the moment but they are pretty much identical to what we have in the facebook clone and should be easy to integrate in a similar way this is part of the work to integrate support for the user typing feature right now the client app doesn\u0026rsquo;t send or render this event but it should be relatively simple to add when a user starts typing to a conversation we can invoke this method two user can be a user or a group is the user present it\u0026rsquo;s if the user is present it\u0026rsquo;s a user i\u0026rsquo;ll discuss the event code in the sockets when we reach the app socket class and this if this is a group we need to send the event to all the users within the group via the socket connection this method sends a message to its destination which can be a user or a group in order to send a message we first need to create a chat entity message entity so we can persist the message in case delivery failed this is the same code we saw in the typing event if the message is destined to a user the following block will occur otherwise we\u0026rsquo;ll go to the else block where the exact same code will execute in a loop over the members of the group we mark the destination of the message and convert it to json to adjacent string we invoke the send message api the send message uses the socket to send the message to the device if this failed and the device isn\u0026rsquo;t reachable we should send this message as text using push notification this method is identical to the other send message method but it uses a json string which is more convenient when a message comes in through the websocket the previous version is the one used when this is invoked from the web service which is what we use and this one works when a message is sent via the websocket this method converts a chat message entity to json so we can send it to the client object mapper can convert a pojo object to the equivalent json string this method sends json via the socket to the group or a user it allows us to propagate a message onward it works pretty much like the other methods in this class that send to a group or a user this method finds the user matching the given phone number this method is used by find registered user and find registered user by id it generalizes that translation of a user list to a single user dial value it implicitly fails for unverified users as well ack allows us to acknowledge that a message was received it just toggles the ack flag when a user connects via websocket this method is invoked it finds all the messages that weren\u0026rsquo;t act by the user and sends them to that user that way if a device lost connection it will get the content once it\u0026rsquo;s back online this method is invoked on launch to update the push key in the server so we can send push messages to the device with that user service is finished\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/135-12-user-service/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 14: Creating a WhatsApp Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/5EyrMpQqR-k?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ethe next step is the services layer\nwhich implements\nthe relatively simple business layer of\nthis application\nwe\u0026rsquo;ll start with the user service class\nit\u0026rsquo;s the main class in this package and\nhandles pretty much the entire business\nlogic of the app\nit\u0026rsquo;s a service bean this means it\nhandles generic business logic for the\napplication\nwe need access to the repositories we\njust defined for users groups and\nmessages\nthe api keys service is the exact one i\nused in facebook with the exception of a\ndifferent properties file name\ni\u0026rsquo;ll discuss that later\nit generally abstracts api keys and\nseparates them from the source code\nthe password encoder is used to encrypt\nand verify the token\nmedia repository and notification\nservers are identical to the stuff we\nhad in the facebook clone app\nthis method sends an sms message via the\ntwillow web service\nif you recall we added the twillow sdk\ninto the pom file in the first lesson\nthis sdk makes sending an sms message\nvery easy as you can see from the code\nthe login api lets us validate a user\nand get the current data\nthe server has for that user\nsince there is no username slash\npassword we need to use the token to\nauthenticate\nfirst we need to find the user with the\ngiven phone assuming the user isn\u0026rsquo;t\nthere will throw an exception\nsince the auth is hashed as we discussed\nbefore\nwe need to test the incoming auth via\nthe matches method in encoder it\nverifies the hash matches the auth token\nthis method creates a string of the\ngiven length which includes a random\nnumber for verification\nsignup creates an entry for a specific\nuser but doesn\u0026rsquo;t activate the account\nuntil it\u0026rsquo;s verified\nwe first check if the phone number is\nalready registered if so we need to fail\notherwise we create the new user and\ninitialize the value of the data and the\nverification code\nfinally we send the activation code and\nreturn the user entity\nthe verify method activates a user\naccount if the verification mode is\ncorrect we mark the user as verified and\nreturn true\nwe use set props both from the sign up\nand update methods\nthere isn\u0026rsquo;t much here but if we add\nadditional metadata this might become a\nbigger method like it is and the\nfacebook clone\nupdate verifies the user\u0026rsquo;s token\nthen updates the properties there isn\u0026rsquo;t\nmuch here\nthese aren\u0026rsquo;t used at the moment\nbut they are pretty much identical to\nwhat we have in the facebook clone and\nshould be easy to integrate in a similar\nway\nthis is part of the work to integrate\nsupport for the user typing feature\nright now the client app doesn\u0026rsquo;t send or\nrender this event but it should be\nrelatively simple to add\nwhen a user starts typing to a\nconversation we can invoke this method\ntwo user can be a user or a group\nis\nthe user present it\u0026rsquo;s if the user is\npresent it\u0026rsquo;s a user\ni\u0026rsquo;ll discuss the event code in the\nsockets\nwhen we reach the app socket class\nand this if this is a group we need to\nsend the event to all the users within\nthe group\nvia the socket connection\nthis method sends a message to its\ndestination which can be a user or a\ngroup\nin order to send a message we first need\nto create a chat entity message entity\nso we can persist the message in case\ndelivery failed\nthis is the same code we saw in the\ntyping event if the message is destined\nto a user the following block will occur\notherwise we\u0026rsquo;ll go to the else block\nwhere the exact same code will execute\nin a loop\nover the members of the group\nwe mark the destination of the message\nand convert it to json to adjacent\nstring\nwe invoke the send message api\nthe send message uses the socket to send\nthe message to the device\nif this failed and the device isn\u0026rsquo;t\nreachable\nwe should send this message as text\nusing push notification\nthis method is identical to the other\nsend message method but it uses a json\nstring\nwhich is more convenient when a message\ncomes in through the websocket\nthe previous version is the one used\nwhen this is invoked from the web\nservice which is what we use\nand this one works when a message is\nsent via the websocket\nthis method converts a chat message\nentity to json so we can send it to the\nclient\nobject mapper can convert a pojo object\nto the equivalent json string\nthis method sends json via the socket to\nthe group or a user it allows us to\npropagate a message onward it works\npretty much like the other methods in\nthis class that send to a group or a\nuser\nthis method finds the user matching the\ngiven phone number this method is used\nby find registered user and find\nregistered user by id\nit generalizes that translation of a\nuser list to a single user dial value it\nimplicitly fails for unverified users as\nwell\nack allows us to acknowledge that a\nmessage was received\nit just toggles the ack flag\nwhen a user connects via websocket this\nmethod is invoked it finds all the\nmessages that weren\u0026rsquo;t act by the user\nand sends them to that user\nthat way if a device lost connection\nit will get the content once it\u0026rsquo;s back\nonline\nthis method is invoked on launch to\nupdate the push key\nin the server so we can send push\nmessages to the device\nwith that user service is finished\u003c/p\u003e","title":"12. User Service"},{"content":" Module 14: Creating a WhatsApp Clone\nTranscript next we\u0026rsquo;ll jump to the web service package this is pretty much identical to the facebook clone app we create a web service mapping for the user services technically we could have broken this down to more web services but there is no real reason as we don\u0026rsquo;t have that much functionality here this is a thin wrapper around user service that contains no actual functionality it only translates the logic in that class to web calls if an exception is thrown in this class it\u0026rsquo;s implicitly translated to an error dao which is translated to an error json login and sign up are almost identical with the small exception that login expects an auth header value both are simple post methods that return the dao object as json body to the client verify and update return string values to indicate that they succeeded i added the implementation to get set avatar via url but this isn\u0026rsquo;t mapped to the client side this can probably be implemented in the same way as the facebook clone these methods return their result as an array of one element or as a zero length array since there is no way and json to return null like the business logic method does so we return a blank array list or a list with one element and that\u0026rsquo;s the end of the class the rest of the methods delegate directly to the user service bin\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/136-13-user-web-service/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 14: Creating a WhatsApp Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/BSrupbUahRM?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003enext we\u0026rsquo;ll jump to the web service\npackage\nthis is pretty much identical to the\nfacebook clone app\nwe create a web service mapping for the\nuser services\ntechnically we could have broken this\ndown\nto more web services but there is no\nreal reason as we don\u0026rsquo;t have that much\nfunctionality here\nthis is a thin wrapper around user\nservice that contains no actual\nfunctionality it only translates the\nlogic in that class to web calls\nif an exception is thrown in this class\nit\u0026rsquo;s implicitly translated to an error\ndao which is translated to an error json\nlogin and sign up are almost identical\nwith the small exception that login\nexpects an auth header value\nboth are simple post methods\nthat return the dao object as json body\nto the client\nverify and update return string values\nto indicate that they succeeded\ni added the implementation to get set\navatar\nvia url\nbut this\nisn\u0026rsquo;t mapped to the client side this can\nprobably be implemented in the same way\nas the facebook clone\nthese methods return their result as an\narray of one element or as a zero length\narray since there is no way and json to\nreturn null like the business logic\nmethod does\nso we return a blank array list\nor a list with one element\nand that\u0026rsquo;s the end of the class the rest\nof the methods delegate directly to the\nuser service bin\u003c/p\u003e","title":"13. User Web Service"},{"content":" Module 14: Creating a WhatsApp Clone\nTranscript next we\u0026rsquo;ll jump to the websocket package which is the last package first we need to configure the websocket we do this by implementing the websocket configurer and using the annotations on the class to indicate its purpose we define the socket so we can define the packet size to 8k we can set a larger size but generally keeping packets small is a good practice the app socket class is bound to the slash socket url in this line of code this is the thread used to process the websocket connections we can allocate more thread resources based on need let\u0026rsquo;s go to the app socket the app is an implementation of text websocket handler which handles text messages since all our messages are json this makes more sense i cache the currently active connections here this isn\u0026rsquo;t a good approach in the long term a better approach would be redis for this sort of caching but for an initial app this can work fine we need access to the user service so we can send message to a group or user the method sends this method sends json to a websocket based on the user token and returns true if it is successful we get the sessions for the given client if he has a web service session we create a text message with js the json we loop over all the websocket connections one by one if a connection is open we send the message there and return otherwise we add the socket to the remove queue we don\u0026rsquo;t want to remove in the middle of the loop to prevent an exception we remove all the defunct websockets from the queue in this line for all the classes we\u0026rsquo;re sending via socket in work we return force this method handles the incoming text packets we need to parse the json into a map if m has a type of pro it\u0026rsquo;s probably an init method if init messages allows us to add a websocket to our cache of connections so we can push a message back into the websocket when we need to send a server note notification otherwise we test if this is a user typing event in which case we need to send a typing message onward finally we send the message as json to the users in the group or to the specific user this invokes the code we saw in the user service class when combination when a connection is closed we loop over the existing list and purge it of the dead connection for simplicity we don\u0026rsquo;t support partial messages which shouldn\u0026rsquo;t be necessary for a small 8k messages with that the class is done\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/137-14-web-socket/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 14: Creating a WhatsApp Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/YwD35TG6WAg?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003enext we\u0026rsquo;ll jump to the websocket package\nwhich is the last package\nfirst we need to configure the websocket\nwe do this by implementing the websocket\nconfigurer\nand using the annotations on the class\nto indicate its purpose\nwe define the socket so we can define\nthe packet size\nto 8k\nwe can set a larger size but generally\nkeeping packets small\nis a good practice\nthe app socket class is bound to the\nslash socket url\nin this line of code\nthis is the thread used to process the\nwebsocket connections\nwe can allocate more thread resources\nbased on need\nlet\u0026rsquo;s go to the app socket\nthe app\nis an implementation of text websocket\nhandler which handles text messages\nsince all our messages are json this\nmakes more sense\ni cache the currently active connections\nhere\nthis isn\u0026rsquo;t a good approach in the long\nterm a better approach would be redis\nfor\nthis sort of caching\nbut for an initial app this can work\nfine\nwe need access to the user service\nso we can send message\nto a group or\nuser\nthe method sends this method sends json\nto a websocket based\non the user token and returns true if it\nis successful\nwe get the sessions for the given client\nif he has a web service session\nwe create a text message\nwith js\nthe json\nwe loop over all the websocket\nconnections\none by one\nif a connection is open\nwe send the message\nthere and return\notherwise we add the socket to the\nremove queue\nwe don\u0026rsquo;t want to remove in the middle of\nthe loop to prevent an exception\nwe remove all the defunct websockets\nfrom the queue in this\nline\nfor all the classes\nwe\u0026rsquo;re sending via socket in work we\nreturn force\nthis method handles the incoming text\npackets\nwe need\nto parse the json into a map\nif m\nhas a type of pro it\u0026rsquo;s probably an init\nmethod\nif\ninit messages allows us to add a\nwebsocket\nto our cache of connections so we can\npush a message back into the websocket\nwhen we need to send a server note\nnotification\notherwise we test if this is a user\ntyping event in which case we need to\nsend a typing message onward\nfinally we send the message as json to\nthe users in the group or to the\nspecific user this invokes the code we\nsaw in the user service class\nwhen combination\nwhen a connection is closed we loop over\nthe existing list and purge it\nof the dead connection\nfor simplicity we don\u0026rsquo;t support partial\nmessages which shouldn\u0026rsquo;t be necessary\nfor a small 8k messages\nwith that the class is done\u003c/p\u003e","title":"14. Web Socket"},{"content":" Module 15: Create a Netflix Clone\nTranscript welcome to the first lesson of creating a netflix clone with codename one there are a few things i\u0026rsquo;d like to talk about in this module but first i want to clarify that this module is relatively short as are trying to focus only on the new things so the netflix clone is less of a clone and more of a proof of concept the clone is much simpler in scope and functionality when compared to previous modules this is intentional i don\u0026rsquo;t want to repeat things that were better covered in the facebook or uber tutorials but i do want to cover new things i placed most of the focus on the nuances of the netflix ui but i also placed some focus on different approaches for working with spring boot i think these will prove valuable as we go back and look at the stuff we did in the previous modules but first let\u0026rsquo;s talk about the complexities of video platforms technically they aren\u0026rsquo;t very complex in fact they are remarkably simple for the most part the biggest problem faced by netflix is scale and that only matters when you reach netflix levels of scale videos and platforms like netflix are generally generated statically before the first request is made that effectively means that servers just serve ready-made files and don\u0026rsquo;t do complex runtime work there are great tools that pre-process video files such as ffmpeg these tools can be used as native libraries in the server or as command line tools most netflix clones just pre-generate all the video files in the various resolutions bitrate options then the work amounts to picking the right video url the video urls can be further scaled using pre-existing content delivery networks also known as cdns we specifically use cloudflare at codename one but any cdn would do we didn\u0026rsquo;t cover cdn hosting and literally all of the complexities in the server here we also don\u0026rsquo;t cover anything related to video processing that\u0026rsquo;s server logic that falls way outside the scope of a mobile tutorial furthermore a lot of this work can be done completely outside of the server as a separate tool that updates the url\u0026rsquo;s databases video hosting can be done as a separate microservice and mostly hidden from our main backend logic as a result the content of the application will be mostly hard coded this is important as there is an ip issue with distributing a clone of content which we don\u0026rsquo;t want to get into we also won\u0026rsquo;t implement the multi-user and authentication portions of the app we covered all of that rather well in the uber clone and there\u0026rsquo;s no point of going into this again once all this is removed the server is ridiculously trivial most of this applies to the client ui to we covered almost all of this before so the netflix clone is a rehash of many of those ideas with a new coat of paint the ui is trivial and includes only two forms both of which are only partially implemented there is no reason to go deeper as the their source application isn\u0026rsquo;t very complicated to begin with you can use the facebook clone as a reference to more elaborate ui once the css is in place implementing the missing functionality in a netflix clone becomes trivial but there\u0026rsquo;s one bigger mission i chose to use the native player native video playback is actually pretty great it handles everything we need in terms of ui for the video player the problem starts when that mode isn\u0026rsquo;t enough say we want more control over the behavior of playback code we can\u0026rsquo;t do much in that mode our control is very limited however native playback is pretty much a turnkey solution for video playback that\u0026rsquo;s why we picked it it\u0026rsquo;s a great tool for getting started lightweight is more error prone and powerful a good example is closed captions which we can implement manually in lightweight mode but literally placing by literally labeling and placing labels on top of the playing video that\u0026rsquo;s very powerful i will create a separate module that will cover lightweight video playback it should be easy to adapt the playback code to make use of that approach the final ui should include these two forms the latter will allow video playback notice that all the videos lead to a hard-coded video url of a spinning earth again due to ip issues thanks for watching i hope you\u0026rsquo;ll enjoy the rest of the course and will find it educational\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/138-introduction/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 15: Create a Netflix Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/r_ti2QAhm9s?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ewelcome to the first lesson\nof creating a netflix clone with\ncodename one\nthere are a few things i\u0026rsquo;d like to talk\nabout in this module\nbut first i want to clarify that this\nmodule is relatively short as are trying\nto focus only on the new things\nso the netflix clone is less of a clone\nand more of a proof of concept\nthe clone is much simpler in scope and\nfunctionality when compared to previous\nmodules this is intentional i don\u0026rsquo;t want\nto repeat things that were better\ncovered in the facebook or uber\ntutorials\nbut i do want to cover new things\ni placed most of the focus on the\nnuances of the netflix ui\nbut i also placed some focus on\ndifferent approaches\nfor working with spring boot\ni think these will prove valuable as we\ngo back and look at the stuff we did in\nthe previous modules\nbut first let\u0026rsquo;s talk about the\ncomplexities of video platforms\ntechnically they aren\u0026rsquo;t very complex in\nfact they are remarkably simple for the\nmost\npart the biggest problem faced by\nnetflix is scale\nand that only matters when you reach\nnetflix levels of scale\nvideos and platforms like netflix are\ngenerally\ngenerated statically before the first\nrequest is made\nthat effectively means that servers just\nserve ready-made files and don\u0026rsquo;t do\ncomplex runtime work\nthere are great tools that pre-process\nvideo files such as ffmpeg\nthese tools can be used as native\nlibraries in the server or as command\nline tools\nmost netflix clones just pre-generate\nall the video files in the various\nresolutions bitrate options\nthen the\nwork amounts to picking the right video\nurl\nthe video urls can be further scaled\nusing pre-existing content delivery\nnetworks also known as cdns\nwe specifically use cloudflare at\ncodename one but any cdn would do\nwe didn\u0026rsquo;t cover cdn hosting and\nliterally all of the complexities in the\nserver here we also don\u0026rsquo;t cover anything\nrelated to video processing\nthat\u0026rsquo;s server logic that falls way\noutside the scope of a mobile tutorial\nfurthermore a lot of this work can be\ndone completely outside of the server as\na separate tool that updates the url\u0026rsquo;s\ndatabases\nvideo hosting can be done as a separate\nmicroservice and mostly hidden from our\nmain backend logic\nas a result the content of the\napplication will be mostly hard coded\nthis is important as there is an ip\nissue with distributing a clone of\ncontent which we don\u0026rsquo;t want to get into\nwe also won\u0026rsquo;t implement the multi-user\nand authentication portions of the app\nwe covered all of that rather well in\nthe uber clone and there\u0026rsquo;s no point of\ngoing into this again\nonce all this is removed the server is\nridiculously trivial\nmost of this applies to the client ui to\nwe covered almost all of this before so\nthe netflix clone is a rehash of many of\nthose ideas with a new coat of paint\nthe ui is trivial and includes only two\nforms both of which are only partially\nimplemented there is no reason to go\ndeeper as\nthe\ntheir source application isn\u0026rsquo;t very\ncomplicated to begin with\nyou can use the facebook clone as a\nreference to more elaborate ui\nonce the css is in place implementing\nthe missing functionality in a netflix\nclone becomes trivial\nbut there\u0026rsquo;s one bigger mission i chose\nto use the native player\nnative video playback is actually pretty\ngreat it handles everything we need in\nterms of ui for the video player\nthe problem starts when that mode isn\u0026rsquo;t\nenough say we want more control over the\nbehavior of playback code we can\u0026rsquo;t do\nmuch in that mode our control is very\nlimited\nhowever\nnative playback is pretty much a turnkey\nsolution for video playback that\u0026rsquo;s why\nwe picked it it\u0026rsquo;s a great tool for\ngetting started\nlightweight is more error prone and\npowerful a good example is closed\ncaptions which we can implement manually\nin lightweight mode but literally\nplacing by literally labeling and\nplacing labels on top of the playing\nvideo\nthat\u0026rsquo;s very powerful\ni will create a separate module that\nwill cover lightweight video playback it\nshould be easy to adapt the playback\ncode to make use of that approach\nthe final ui should include these two\nforms\nthe latter will allow video playback\nnotice that all the videos lead to a\nhard-coded video url of a spinning earth\nagain due to ip issues\nthanks for watching i hope you\u0026rsquo;ll enjoy\nthe rest of the course and will find it\neducational\u003c/p\u003e","title":"Introduction"},{"content":" Module 15: Create a Netflix Clone\nTranscript in this lesson we\u0026rsquo;ll go over the basic server architecture and project lombok which we use in the server implementation we\u0026rsquo;ll start with some basic information about the server and then dive into quick lombok overview so first let\u0026rsquo;s talk about the database unlike previous modules where i chose to use mysql this time around i picked h2 for the database since it requires literally no setup i wouldn\u0026rsquo;t use it for production but since the whole complexity of mysql is covered in other modules this just isn\u0026rsquo;t necessary lombok is used to make the server code tiny and devoid of boilerplate this is pretty cool we don\u0026rsquo;t really need much in terms of web services if we had authentication and authorization there would have been more i could also implement paging support and more complex requests for various segments of the ui but those are pretty obvious if you\u0026rsquo;ve gone through gone over the feed section of the facebook loan the authentication aspect is the big missing piece here and i just didn\u0026rsquo;t want to get into it it\u0026rsquo;s usually one of the more painful aspects of building a server but since this is a mobile course i don\u0026rsquo;t think it\u0026rsquo;s very important to cover again as it was covered in previous modules let\u0026rsquo;s start with a palm file this is all pretty minimal first we have the standard declarations we use spring boot 2.2.2 which is the current version at this time this code is generated with the spring initializer which i described before this declares the h2 database instead of mysql and here we declare the use of lombok which i\u0026rsquo;ll get into shortly i also added a dependency on apache commons io which is pretty useful for small utility calls lombok is a set of tools that include ide plugins libraries and runtime tools they essentially try to modernize the java syntax using special annotations and it does a pretty great job at removing a lot of the common boilerplate from java 8 syntax their biggest claim to fame is removing the getter and setup boilerplate code from java in this module we\u0026rsquo;ll use lombok in the server it works for codename one app code but we won\u0026rsquo;t touch on that the main reason that is that the value of lombok diminishes thanks to properties so we don\u0026rsquo;t need it as much but if you need it you can see this tip about installing lombok for a codename one app let\u0026rsquo;s look at a few examples of using lombok notice that these examples are picked directly from the lombok developer guide here we have a class with three fields but only one of them is marked as non-null as such we can\u0026rsquo;t construct this object without the description field as we would have an invalid object so we have a private constructor that accepts this required field to create the actual instance of this class we use the of method which accepts the required description argument so you would be able to just write constructorexample.of description that\u0026rsquo;s pretty nice but it took five lines of code not including curly brace braces or spaces that\u0026rsquo;s a bit verbose that can be achieved with one annotation in lombok you just define the constructor and the method name that you wish to add as a static factory method and voila it works exactly like the code we saw before you can literally write constructed example.of description the other constructor is for subclasses it accepts all of the state members and also makes sure to fail if we try to violate the not null annotation notice it\u0026rsquo;s scoped as protected so it would be used only when deriving the class this can be implemented with a single line of code the all args constructor annotation does all of that implicitly it also has an optional access level property which defaults to public the inner class is pretty simple there isn\u0026rsquo;t too much to save here but still there\u0026rsquo;s a bit of vibrosity we can implement the blank constructor using the no args constructor notice that this example is a bit synthetic normally we would use this annotation in conjunction with other constructor options to indicate that we also want that option we already saw non-null being used before so this example should come as no surprise this annotation can also apply to method arguments etc the method can now assume the variable isn\u0026rsquo;t null notice that this usage is a bit stupid as the person.get name call will throw a null pointer exception anyway but if you invoke code that might propagate null it could be useful let\u0026rsquo;s move on to another cool feature of lombok notice that this code can be improved by using the java 8 try with resource syntax so this isn\u0026rsquo;t as beneficial but it\u0026rsquo;s still pretty cool this block can be written like this which is as terse as with the try with resources code and possibly even more terse lombok claims lombok\u0026rsquo;s claim to fame has always been getter and sitter elimination so this whole block of code can be replaced with this notice that this is still relatively verbose as we want a protected setter so let\u0026rsquo;s see something that\u0026rsquo;s even more terse first notice that the setter for age as package protected access while has package protected access while the getter is public also check out all the boilerplate code we have for equals and tostring this can be optimized with some of the newer objects class methods but not by much the boilerplate doesn\u0026rsquo;t end though we have a hashcode method too and a non-trivial inner class with a static creation method notice that this is the required arc constructor syntax we mentioned before that code that includes pages of data can be achieved using the at data annotation it includes getters setters tostring and hash code implicitly notice you can explicitly override the definition of a specific setter from data as we did for the case of age another common task is variable definition again there is a lot of boilerplate here so much that java defined a new val keyword keyword but this isn\u0026rsquo;t yet available for java 8 which is used by most of us lombok added two keywords vel and var va var var lets us define a variable that can change a mutable variable val defines an immutable variable effectively a final variable there are a lot of annotations we didn\u0026rsquo;t cover here at value is the immutable variant of at data all fields are made private and final by default and setters are not generated the class itself is also made final by default because immutability is not something that can be forced onto a subclass just like data the tostring equals and code methods are also generated each field gets a getter method and a constructor that covers every argument is also generated the builder annotation produces complex builder apis for your classes at builder lets you automatically produce the code required to have your class be instantiatable with code such as person.builder.name shy.build notice that this works nicely with the add value annotation to produce immutable classes with the builder pattern add sneaky throws can be used to sneakily throw checked exceptions without actually declaring this in your methods throws clause since checked exceptions are a feature of the java language and not of the java bytecode this is technically possible synchronized is a safer variant of the synchronized method modifier the synchronized keyword locks on this object which is problematic as it exposes the lock state externally this annotation implicitly creates a hidden dollar lock object and synchronizes on that object the next best alternative to a setter for an immutable property is to construct a clone of the object but with a new value for this one field a method to generate this clone is precisely what at with generates a with field name method which produces a clone except for the new value for the associated field you put at log in your clock in your class you you then will have a static final log field initialized as is the commonly described prescribed way for the logging framework you use which you can then use to write log statements notice that there are a lot of annotations you can use to describe explicit log system you want to use in the project you can let lombok generate a getter which will calculate a value once the first time the scatter is called and cached and cache it from then on this can be useful if calculating the value takes a lot of cpu or the value takes a lot of memory to use this feature create a private final variable initialize it with the expression that\u0026rsquo;s expensive to run and annotate your field with at getter lazy equals true the field will be hidden from the rest of your code and the expression will be evaluated no more than once when the getter is first called there are no magic marker values i.e even if the result of your expensive calculation is null the result is cached and your expensive calculation need not be thread safe as lombok takes care of locking most of this is taken directly from uh the projectlombok.org features slash all tutorial but there\u0026rsquo;s a lot more information there thanks for watching i hope you enjoy the rest of the course and find it educational\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/139-server-part-i/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 15: Create a Netflix Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/7CoD9u6KM2Q?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ein this lesson we\u0026rsquo;ll go over the basic\nserver architecture and project lombok\nwhich we use in the server\nimplementation\nwe\u0026rsquo;ll start with some basic information\nabout the server and then dive into\nquick lombok overview\nso first let\u0026rsquo;s talk about the database\nunlike previous modules where i chose to\nuse mysql\nthis time around i picked h2 for the\ndatabase since it requires literally no\nsetup\ni wouldn\u0026rsquo;t use it for production but\nsince the whole complexity of mysql is\ncovered in other modules this just isn\u0026rsquo;t\nnecessary\nlombok is used to make the server code\ntiny and devoid of boilerplate this is\npretty cool\nwe don\u0026rsquo;t really need much in terms of\nweb services if we had authentication\nand authorization there would have been\nmore i could also implement paging\nsupport and more complex requests for\nvarious segments of the ui but those are\npretty obvious if you\u0026rsquo;ve gone through\ngone over the feed section of the\nfacebook loan\nthe authentication aspect is the big\nmissing piece here\nand i just didn\u0026rsquo;t want to get into it\nit\u0026rsquo;s usually one of the more painful\naspects of building a server but since\nthis is a mobile course i don\u0026rsquo;t think\nit\u0026rsquo;s very important to cover again as it\nwas covered in previous modules\nlet\u0026rsquo;s start with a palm file this is all\npretty minimal\nfirst we have the standard declarations\nwe use spring boot 2.2.2 which is the\ncurrent version at this time\nthis code is generated with the spring\ninitializer which i described before\nthis declares the h2 database instead of\nmysql\nand here we declare the use of lombok\nwhich i\u0026rsquo;ll get into shortly\ni also added a dependency on apache\ncommons io which is pretty useful for\nsmall utility calls\nlombok is a set of tools\nthat include ide plugins libraries and\nruntime tools they essentially try to\nmodernize the java syntax using special\nannotations and it does a pretty great\njob at removing a lot of the common\nboilerplate from java 8 syntax their\nbiggest claim to fame is removing the\ngetter and setup boilerplate code from\njava\nin this module we\u0026rsquo;ll use lombok in the\nserver it works for codename one app\ncode but we won\u0026rsquo;t touch on that\nthe main reason that is\nthat the value of lombok diminishes\nthanks to properties so we don\u0026rsquo;t need it\nas much\nbut if you need it you can see this tip\nabout installing lombok for a codename\none app\nlet\u0026rsquo;s look at a few examples of using\nlombok notice that these examples are\npicked directly from the lombok\ndeveloper guide\nhere we have a class with three fields\nbut only one of them is marked as\nnon-null\nas such we can\u0026rsquo;t construct this object\nwithout the description field as we\nwould have an invalid object\nso we have a private constructor that\naccepts this required field to create\nthe actual instance of this class we use\nthe of method which accepts the required\ndescription argument\nso you would be able to just write\nconstructorexample.of\ndescription\nthat\u0026rsquo;s pretty nice\nbut it took five lines of code\nnot including curly brace braces or\nspaces that\u0026rsquo;s a bit verbose\nthat can be achieved with one annotation\nin lombok\nyou just define the constructor and the\nmethod name that you wish to add as a\nstatic factory method and voila\nit works exactly like the code we saw\nbefore you can literally write\nconstructed example.of description\nthe other constructor is for subclasses\nit accepts all of the state members and\nalso makes sure to fail if we try to\nviolate the not null annotation\nnotice it\u0026rsquo;s scoped as protected so it\nwould be used only when deriving the\nclass\nthis can be implemented with a single\nline of code\nthe all args constructor annotation does\nall of that implicitly it also has an\noptional access level property which\ndefaults to public\nthe inner class\nis pretty simple there isn\u0026rsquo;t too much to\nsave here but still there\u0026rsquo;s a bit of\nvibrosity\nwe can implement the blank constructor\nusing the no args constructor\nnotice that this example is a bit\nsynthetic normally we would use this\nannotation in conjunction with other\nconstructor options to indicate that we\nalso want\nthat option\nwe already saw non-null\nbeing used before so this example should\ncome as no surprise this annotation can\nalso apply to method arguments etc\nthe method can now assume the variable\nisn\u0026rsquo;t null notice that this usage is a\nbit stupid as the person.get name call\nwill throw a null pointer exception\nanyway but if you invoke code that might\npropagate null\nit could be useful\nlet\u0026rsquo;s move on to another cool feature of\nlombok\nnotice that this code can be improved by\nusing the java 8 try with resource\nsyntax so this isn\u0026rsquo;t as beneficial\nbut it\u0026rsquo;s still pretty cool\nthis block can be written like this\nwhich is as terse as with\nthe try with resources code and possibly\neven more terse\nlombok claims\nlombok\u0026rsquo;s claim to fame has always been\ngetter and sitter elimination so this\nwhole block of code can be replaced with\nthis notice that this is still\nrelatively verbose as we want a\nprotected setter\nso let\u0026rsquo;s see something that\u0026rsquo;s even more\nterse\nfirst notice that the setter for age as\npackage protected access while has\npackage protected access while the\ngetter is public\nalso check out all the boilerplate code\nwe have for equals and tostring\nthis can be optimized with some of the\nnewer objects class methods but not by\nmuch\nthe boilerplate doesn\u0026rsquo;t end though\nwe have a hashcode method too\nand a non-trivial inner class with a\nstatic creation method\nnotice that this is the required arc\nconstructor syntax we mentioned before\nthat code that includes pages of data\ncan be achieved using the at data\nannotation\nit includes getters setters tostring and\nhash code implicitly notice you can\nexplicitly override the definition of a\nspecific setter from data as we did for\nthe case of age\nanother common task is variable\ndefinition\nagain there is a lot of boilerplate here\nso much\nthat java defined a new val keyword\nkeyword but this isn\u0026rsquo;t yet available for\njava 8 which is used by most of us\nlombok added two keywords vel and var\nva var\nvar lets us define a variable that can\nchange\na mutable variable\nval defines an immutable variable\neffectively a final variable\nthere are a lot of annotations we didn\u0026rsquo;t\ncover here\nat value is the immutable variant of at\ndata\nall fields are made private and final by\ndefault and setters are not generated\nthe class itself is also made final by\ndefault because immutability is not\nsomething that can be forced onto a\nsubclass just like data\nthe tostring equals and code methods are\nalso generated each field gets a getter\nmethod and a constructor that covers\nevery argument is also generated\nthe builder annotation produces complex\nbuilder apis for your classes at builder\nlets you automatically produce the code\nrequired to have your class be\ninstantiatable with code such as\nperson.builder.name shy.build\nnotice that this works nicely with the\nadd value annotation to produce\nimmutable classes with the builder\npattern\nadd sneaky throws can be used to\nsneakily throw checked exceptions\nwithout\nactually declaring this in your methods\nthrows clause since checked exceptions\nare a feature of the java language and\nnot of the java bytecode this is\ntechnically possible\nsynchronized is a safer variant of the\nsynchronized method modifier the\nsynchronized keyword locks on this\nobject which is problematic as it\nexposes the lock state externally\nthis annotation implicitly creates a\nhidden\ndollar lock object and synchronizes on\nthat object\nthe next best alternative to a setter\nfor an immutable property is to\nconstruct a clone of the object\nbut with a new value for this one field\na method to generate this clone is\nprecisely what\nat with generates\na with field name method which produces\na clone except for the new value for the\nassociated field\nyou put at log in your clock\nin your class\nyou\nyou then will have a static final log\nfield\ninitialized as is the commonly described\nprescribed way for the logging framework\nyou use which you can then use to write\nlog statements\nnotice that there are a lot of\nannotations you can use to describe\nexplicit log system you want to use in\nthe project\nyou can let lombok generate a getter\nwhich will calculate a value once\nthe first time the scatter is called and\ncached\nand cache it from then on this can be\nuseful if calculating the value takes a\nlot of cpu or the value takes a lot of\nmemory to use this feature create a\nprivate final variable initialize it\nwith the expression that\u0026rsquo;s expensive to\nrun and annotate your field with at\ngetter lazy equals true\nthe field will be hidden from the rest\nof your code and the expression will be\nevaluated no more than once\nwhen the getter is first called\nthere are no magic marker values i.e\neven\nif the result of your expensive\ncalculation is null the result is cached\nand your expensive calculation need not\nbe thread safe as lombok takes care of\nlocking\nmost of this is taken directly from\nuh\nthe\nprojectlombok.org features slash all\ntutorial\nbut there\u0026rsquo;s a lot more information there\nthanks for watching i hope you enjoy the\nrest of the course and find it\neducational\u003c/p\u003e","title":"Server Part I"},{"content":" Module 15: Create a Netflix Clone\nTranscript in the third part we\u0026rsquo;ll dive right into the model objects representing the server and ultimately the front end code if you\u0026rsquo;re unfamiliar with entities jpa uuid etc i suggest going back to the previous modules and refreshing your memory a bit as we\u0026rsquo;ll build a lot on top of that one way in which this will be different though is the usage of lombok which will make our code far more tears still the code here is mostly mock the real world netflix has a lot of code but most of it applies to algorithmic scheduling user management scaling etc all of these aren\u0026rsquo;t applicable here in this lesson our focus will be on entities and data transfer objects also known as dtos which are sometimes mixed with data access objects or dowels there is overlap between both of these concepts but what we have is generally dtos is they transfer data to the client they don\u0026rsquo;t just abstract the database layer writing an entity with lombok is much easier there are no getters setters constructors equals hash codes etc notice we still use jpa just like we used to so we have the jpa entity annotation and then the lombok annotations everything works as you would expect including the primary key definition etc notice i chose to go with uuid object as a primary key coupled with auto generation that\u0026rsquo;s a much simpler trick than the one i picked in previous modules we already talked about using strings for keys when we use a uuid object we get a long string that isn\u0026rsquo;t guessable in the database that means we can expose that primary key to the end user without worrying that he might use it to scan through details of other users as the string is pretty long and hard to guess as we saw we just need to use the uuid object type there are several other strategies for generating a uuid and jpa i chose the simplest one it might not be the best one but it is convenient so why doesn\u0026rsquo;t everyone use this approach turns out it\u0026rsquo;s much slower than using numeric auto increment values on a database column databases such as mysql are heavily optimized for auto increment fields and string based primary keys are just slower to insert some developers consider that a non-starter especially when looking at performance graphs which is scary performance really takes a dive for instant operations while it remains flat when using long auto increment fields personally i don\u0026rsquo;t think that\u0026rsquo;s a problem even for video app like this you wouldn\u0026rsquo;t insert too often and read operations are still pretty fast this might become an issue if you have a log or auditing table that might include multiple insert operations per second at that point you need to use a long for that for the primary key and make sure never to expose it externally the name and description fields correspond to these fields in the database this is the entire definition as the excesses are generated automatically we have three one-to-one media relations these include the three images for every content item specifically the hero image which is the big picture that appears on top of the application the show logo is displayed on top of the hero image it\u0026rsquo;s a separate image to support different device aspect ratio and layout and the icon is the image representing a show within the list finally we have the actual video files which we store in media objects as well we have multiple video files representing different quality levels of the video in real life we can have even more options such as different aspect ratios languages etc normally i would like this to be a map between quality and media but this is a bit challenging to represent correctly in jpa so i left this as a simple set for convenience we place the dto creation within the entity object this code is mostly just the construction but it\u0026rsquo;s uh it it\u0026rsquo;s there\u0026rsquo;s one block where we convert the media object if the dto in the dto it makes more sense to hold the media as a map instead of a list or set so we translate the video to a map i find the stream syntax a bit obtuse sometimes this is how it would look with a standard for loop essentially for each element we replace the content with a map where the key is the quality and the value as the media url once this is done we create a new dto object with the automatic constructor and return it and finally i also added a small helper method to make the code above a bit simpler so we won\u0026rsquo;t get a null pointer exception if the media is null this is the dto object we just created notice it\u0026rsquo;s super simple and mostly consistent consists of the lombok annotations the strings just map directly to the entity there\u0026rsquo;s nothing to say here for the media i chose to include the icons themselves i could have taken the approach of returning urls for the media which might have advantages in the future for now this is simpler but possibly not as efficient using a url would have had the advantage of caching the data locally for future refreshes using the actual icon means all the data is transferred with one request this is the map we created for the media items we already discussed this in the stream part before it maps between the video quality enum and the string url for the sake of completeness this is the video quality enum pretty simple but matches what we need right now the media entity is another standard lombok entity with the standard trimmings we use the same uuid primary key generation logic rest of the stuff is pretty standard notice that we store the modified time as an instant instead of date instant is a java 8 date time api class it represents a timestamp and is more convenient to use than date the media data is stored in blob storage in the database finally the url to the media and the video quality enum are stored as well that means we can have multiple instances of the same media object for various quality levels one thing i didn\u0026rsquo;t cover here is the repositories for the entity objects they\u0026rsquo;re all empty as we don\u0026rsquo;t need any finder methods for this specific demo so it\u0026rsquo;s all pretty trivial thanks for watching i hope you\u0026rsquo;ll enjoy the rest of the course and find it educational\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/140-server-part-ii/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 15: Create a Netflix Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/47WhIiLxv78?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ein the third part we\u0026rsquo;ll dive right into\nthe model objects representing the\nserver and ultimately the front end code\nif you\u0026rsquo;re unfamiliar with entities jpa\nuuid etc i suggest going back to the\nprevious modules and refreshing your\nmemory a bit as we\u0026rsquo;ll build a lot on top\nof that\none way in which this will be different\nthough is the usage of lombok which will\nmake our code far more tears\nstill the code here is mostly mock the\nreal world netflix has a lot of code but\nmost of it applies to algorithmic\nscheduling user management scaling etc\nall of these aren\u0026rsquo;t applicable here\nin this lesson our focus will be on\nentities and data transfer objects also\nknown as dtos which are sometimes mixed\nwith data access objects or dowels\nthere is overlap between both of these\nconcepts but what we have is generally\ndtos is they transfer data to the client\nthey don\u0026rsquo;t just abstract the database\nlayer\nwriting an entity with lombok is much\neasier\nthere are no getters setters\nconstructors equals hash codes etc\nnotice we still use jpa just like we\nused to so\nwe have the jpa entity annotation\nand then the lombok annotations\neverything works as you would expect\nincluding the primary key definition etc\nnotice i chose to go with uuid object as\na primary key coupled with auto\ngeneration\nthat\u0026rsquo;s a much simpler trick than the one\ni picked in previous modules\nwe already talked about using strings\nfor keys when we use a uuid object we\nget a long string that isn\u0026rsquo;t guessable\nin the database\nthat means we can expose that primary\nkey to the end user without worrying\nthat he might use it to scan through\ndetails of other users\nas the string is pretty long and hard to\nguess\nas we saw we just need to use the uuid\nobject type there are several other\nstrategies for generating a uuid and jpa\ni chose the simplest one it might not be\nthe best one but it is convenient\nso why doesn\u0026rsquo;t everyone use this\napproach turns out it\u0026rsquo;s much slower than\nusing numeric auto increment values on a\ndatabase column\ndatabases such as mysql are heavily\noptimized for auto increment fields and\nstring based primary keys are just\nslower to insert\nsome developers consider that a\nnon-starter especially when looking at\nperformance graphs which\nis scary\nperformance really takes a dive for\ninstant operations\nwhile it remains flat when using long\nauto increment fields\npersonally i don\u0026rsquo;t think that\u0026rsquo;s a\nproblem even for video app like this you\nwouldn\u0026rsquo;t insert too often and read\noperations are still pretty fast\nthis might become an issue if you have a\nlog or auditing table that might include\nmultiple insert operations per second\nat that point you need to use a long for\nthat for the primary key and make sure\nnever to expose it externally\nthe name and description fields\ncorrespond to these fields in the\ndatabase\nthis is the entire definition as the\nexcesses are generated automatically\nwe have three one-to-one media relations\nthese include the three images for every\ncontent item specifically\nthe hero image which is the big picture\nthat appears on top of the application\nthe show logo is displayed on top of the\nhero image it\u0026rsquo;s a separate image to\nsupport different device aspect ratio\nand layout\nand the icon is the image representing a\nshow within the list\nfinally we have the actual video files\nwhich we store in media objects as well\nwe have multiple video files\nrepresenting different quality levels of\nthe video\nin real life we can have even more\noptions such as different aspect ratios\nlanguages etc\nnormally i would like\nthis to be a map between quality and\nmedia\nbut this is a bit challenging to\nrepresent correctly in jpa so i left\nthis as a simple set\nfor convenience we place the dto\ncreation within the entity object\nthis code is mostly just the\nconstruction\nbut it\u0026rsquo;s uh it\nit\u0026rsquo;s there\u0026rsquo;s\none block where we convert the media\nobject\nif the dto\nin the dto it makes more sense to hold\nthe media as a map instead of a list or\nset so we translate the video to a map\ni find the stream syntax a bit obtuse\nsometimes this is how it would look with\na standard for loop\nessentially for each element we replace\nthe content with a map where the key is\nthe quality and the value as the media\nurl\nonce this is done we create a new dto\nobject with the automatic constructor\nand return it\nand finally i also added a small helper\nmethod to make the code above a bit\nsimpler so we won\u0026rsquo;t get a null pointer\nexception if the media is null\nthis is the dto object we just created\nnotice it\u0026rsquo;s super simple and mostly\nconsistent\nconsists of the lombok annotations\nthe strings just map directly to the\nentity there\u0026rsquo;s nothing to say here\nfor the media i chose to include the\nicons themselves i could have taken the\napproach of returning urls for the media\nwhich might have advantages in the\nfuture for now this is simpler but\npossibly not as efficient\nusing a url would have had the advantage\nof caching the data locally for future\nrefreshes\nusing the actual icon means all the data\nis transferred with one request\nthis is the map we created for the media\nitems we already discussed this in the\nstream part before\nit maps between the video quality enum\nand the string\nurl for the sake of completeness this is\nthe video quality enum\npretty simple but matches what we need\nright now\nthe media entity is another standard\nlombok entity with the standard\ntrimmings\nwe use the same uuid primary key\ngeneration logic\nrest of the stuff is pretty standard\nnotice that we store the modified time\nas an instant instead of date\ninstant is a java 8 date time api class\nit represents a timestamp and is more\nconvenient to use than date\nthe media data is stored in blob storage\nin the database\nfinally the url to the media and the\nvideo quality enum are stored as well\nthat means we can have multiple\ninstances of the same media object for\nvarious quality levels\none thing i didn\u0026rsquo;t cover here is the\nrepositories for the entity objects\nthey\u0026rsquo;re all empty as we don\u0026rsquo;t need any\nfinder methods for this specific demo so\nit\u0026rsquo;s all pretty trivial\nthanks for watching i hope you\u0026rsquo;ll enjoy\nthe rest of the course and find it\neducational\u003c/p\u003e","title":"Server Part II"},{"content":" Module 15: Create a Netflix Clone\nTranscript in this final installment covering the server we\u0026rsquo;ll go over the service classes and the final entity representing the content creation the content collection is an oversimplification of the concept a site like netflix would probably generate this data dynamically based on user viewing preferences and complex heuristics i just hard coded an entity which was simpler the service class doesn\u0026rsquo;t do anything other than create the built-in data and implements the basic service call the content collection starts similarly to the other entities again it uses a uuid as an identifier at the moment will only have one content collection but in theory there can be as many as there are users the lead content represents the show that appears on the top of the ui in this case it\u0026rsquo;s the stranger things header these represents the rows of content below that they contain the popular recommended and personal list of shows next we have the method that returns the dto since all lists are effectively lots of content we use the same method to convert everything again we make use of java 8 streams to get all the dtos from the list by invoking the getdto method on every element now we\u0026rsquo;re getting to the web service code we\u0026rsquo;re using the request mapping attribute to specify that this is a web service on the video path the rest controller attribute designates this as a simple json api so a lot of common sense defaults follow for instance response in the body etc notice the all args constructor this means the class has a constructor that accepts all arguments no default constructor this is important notice the final field for the video service it\u0026rsquo;s passed via the constructor notice that the video service doesn\u0026rsquo;t have the autowad annotation we usually place for beans in spring boot this is called constructor injection and it has a few advantages normally it\u0026rsquo;s a bit too verbose as we need to maintain a constructor with all the injected beans but in this case lombok makes it seamless in other words lombok and spring boot inject the video service being pretty seamlessly for us we only have one api in the server it returns the content json a more real world api would also have authentication identity apis and maybe a state querying submitting api for instance view positions statistics etc but those are relatively simple and we were covered by other modules here so i\u0026rsquo;m skipping them for now the service class is similar to the rest api class i used the required rx constructor which is effectively the same as all arcs constructed in this case it creates a constructor for all the required args specifically all the final fields this again works for creating constructor based injection this class is also transactional as it accesses the database we need access to all the repositories to create the entities this is a simple utility method to read bytes from a stream in the class path notice the usage of the add cleanup annotation from lombok and apaches i o util api post construct is a feature of spring boot that lets us invoke a method after the container was constructed this is effectively a constructor for the entire application here we can initialize the app with default data if necessary notice i throw an exception here since i assume this method won\u0026rsquo;t fail it\u0026rsquo;s the first launch so it\u0026rsquo;s core that it succeeds it\u0026rsquo;s pretty easy to detect the first launch if the database is empty the count method on the repository will return 0 elements in that case we need to initialize the database in this large method i set up the initial data in the database i prefer doing it through code rather than manually populating the database and providing a pre-filled one as it\u0026rsquo;s easier to do when working in a fluid environment where you constantly wipe the database in this case i just take the hard-coded images and get their byte array data i then create media objects for all the thumbnail entities the rest is pretty self-explanatory eventually all the videos are created and all the media entities are added notice the urls are to an external video sample site i was able to find online this is consistent with the way a video site would work your actual content would be hosted on a cdn for performance also notice i didn\u0026rsquo;t get into the whole process of encryption encryption and complex drm streaming that\u0026rsquo;s a whole different level of complexity finally the last bit of content is added to the content repository and everything is saved to the database this is the entire server api this returns a json structure used in the client we could stream this in smaller blocks but that was already covered in the facebook demo so i skipped it here thanks for watching i hope you\u0026rsquo;ll enjoy the rest of this course and find it educational you\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/141-server-part-iii/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 15: Create a Netflix Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/vLBQhAJ6aTk?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ein this final installment covering the\nserver we\u0026rsquo;ll go over the service classes\nand the final entity representing the\ncontent creation\nthe content collection is an\noversimplification of the concept\na site like netflix would probably\ngenerate this data dynamically based on\nuser viewing preferences and complex\nheuristics\ni just hard coded an entity which was\nsimpler\nthe service class doesn\u0026rsquo;t do anything\nother than create the built-in data and\nimplements the basic service call\nthe content collection starts similarly\nto the other entities\nagain it uses a uuid as an identifier at\nthe moment will only have one content\ncollection but in theory there can be as\nmany as there are users\nthe lead content represents the show\nthat appears on the top of the ui in\nthis case it\u0026rsquo;s the stranger things\nheader\nthese represents the rows of content\nbelow that they contain the popular\nrecommended and personal list of shows\nnext we have\nthe method that returns the dto\nsince all lists are effectively lots of\ncontent\nwe use the same method to convert\neverything\nagain we make use of java 8 streams to\nget all the dtos from the list by\ninvoking the getdto method on every\nelement\nnow we\u0026rsquo;re getting to the web service\ncode\nwe\u0026rsquo;re using the request mapping\nattribute to specify that this is a web\nservice on the video path\nthe rest controller attribute designates\nthis as a simple json api so a lot of\ncommon sense defaults follow\nfor instance response in the body etc\nnotice the all args constructor this\nmeans the class has a constructor that\naccepts all arguments no default\nconstructor this is important\nnotice the final field for the video\nservice\nit\u0026rsquo;s passed via the constructor\nnotice that the video service doesn\u0026rsquo;t\nhave the autowad annotation\nwe usually place for beans in spring\nboot this is called constructor\ninjection and it has a few advantages\nnormally it\u0026rsquo;s a bit too verbose as we\nneed to maintain a constructor with all\nthe injected beans\nbut in this case lombok makes it\nseamless\nin other words lombok and spring boot\ninject the video service being pretty\nseamlessly for us\nwe only have one api in the server it\nreturns the\ncontent json\na more real world api would also have\nauthentication identity apis and maybe a\nstate querying submitting api\nfor instance view positions statistics\netc\nbut those are relatively simple and we\nwere covered by other modules\nhere so i\u0026rsquo;m skipping them for now\nthe service class is similar to the rest\napi class i used the required rx\nconstructor which is effectively the\nsame as all arcs constructed in this\ncase it creates a constructor for all\nthe required args specifically all the\nfinal fields\nthis again works for creating\nconstructor based injection\nthis class is also transactional as it\naccesses the database\nwe need access to all the repositories\nto create the entities\nthis is a simple utility method to read\nbytes from a stream\nin the class path notice the usage of\nthe add cleanup annotation from lombok\nand apaches i o util\napi\npost construct is a feature of spring\nboot that lets us invoke a method after\nthe\ncontainer was constructed\nthis is effectively a constructor for\nthe entire application\nhere we can initialize the app with\ndefault data if necessary\nnotice i\nthrow an exception here since i assume\nthis method won\u0026rsquo;t fail\nit\u0026rsquo;s the first launch so it\u0026rsquo;s core that\nit succeeds\nit\u0026rsquo;s pretty easy to detect the first\nlaunch\nif the database is empty\nthe count method on the repository will\nreturn 0\nelements in that case we need to\ninitialize the database\nin this large method i set up the\ninitial data in the database i prefer\ndoing it through code rather than\nmanually populating the database and\nproviding a pre-filled one as it\u0026rsquo;s\neasier to do when working in a fluid\nenvironment where you constantly wipe\nthe database\nin this case i just take the hard-coded\nimages and get their byte array data\ni then create media objects for all the\nthumbnail entities\nthe rest is pretty self-explanatory\neventually all the videos are created\nand all the media entities are added\nnotice the urls are to an external video\nsample site i was able to find online\nthis is consistent with the way a video\nsite would work your actual content\nwould be hosted on a cdn for performance\nalso notice i didn\u0026rsquo;t get into the whole\nprocess of encryption encryption and\ncomplex drm streaming that\u0026rsquo;s a whole\ndifferent level of complexity\nfinally the last bit of content is added\nto the content repository and everything\nis saved to the database\nthis is the entire server api this\nreturns a json structure used in the\nclient we could stream this in smaller\nblocks but that was already covered in\nthe facebook demo so i skipped it here\nthanks for watching\ni hope you\u0026rsquo;ll enjoy the rest of this\ncourse and find it educational\nyou\u003c/p\u003e","title":"Server Part III"},{"content":" Module 15: Create a Netflix Clone\nTranscript we\u0026rsquo;re finally at the client side which is also pretty simple this time we\u0026rsquo;ll start with the model and move to the ui rather than the other direction which is what we normally cover since we did the server work first this fits pretty directly after that which makes it easier to start with that portion this model is pretty much proper property business objects to match the lombok objects in the server side while some of the terse aspects of lombok are missed properties make up for it by being far more powerful overall we start with the server class which abstracts our connection to the server since we have one method in the server web service this is continued here we fetch the content from the server synchronically using the rest api this api translates to the the response to json almost seamlessly we say that the response should be in the form of the content collection class this means the json will be parsed into that class which will will examine next the content collection is a standard property business object it maps almost directly to the class with the same name on the server side the main difference is that the properties use our object syntax these match their definition in the server side and include the exact same data the entire class is pretty standard property business object finally the last properties object we have is the content object which is the same as the one in the server the final piece is the enum that matches the one in the server with that our communication layer is complete and we can move on to the ui elements thanks for watching i hope you\u0026rsquo;ll enjoy the rest of the course and find it educational\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/142-client-model/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 15: Create a Netflix Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/HJvMQKM5FPY?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003ewe\u0026rsquo;re finally at the client side which\nis also pretty simple\nthis time we\u0026rsquo;ll start with the model\nand move to the ui rather than the other\ndirection which is what we normally\ncover\nsince we did the server work first this\nfits pretty directly after that\nwhich makes it easier to start with that\nportion\nthis model is pretty much proper\nproperty business objects to match the\nlombok objects in the server side\nwhile some of the terse aspects of\nlombok are missed properties make up for\nit by being far more powerful overall\nwe start with the server class which\nabstracts our connection to the server\nsince we have one method in the server\nweb service this is continued here we\nfetch the content from the server\nsynchronically using the rest api this\napi translates to the the response to\njson almost seamlessly\nwe say that the response should be in\nthe form of the content collection class\nthis means the json will be parsed into\nthat class which will\nwill examine next\nthe content collection is a standard\nproperty business object it maps almost\ndirectly to the class with the same name\non the server side the main difference\nis that the properties use our object\nsyntax\nthese match their definition in the\nserver side and include the exact same\ndata the entire class is pretty standard\nproperty business object\nfinally the last properties object we\nhave is the content object which is the\nsame as the one in the server\nthe final piece is the enum that matches\nthe one in the server with that our\ncommunication layer is complete and we\ncan move on to the ui elements\nthanks for watching i hope you\u0026rsquo;ll enjoy\nthe rest of the course and find it\neducational\u003c/p\u003e","title":"Client Model"},{"content":" Module 15: Create a Netflix Clone\nTranscript for this final part we\u0026rsquo;ll cover the ui of the client which is relatively simple we don\u0026rsquo;t have that many forms but to be fair the basic netflix app doesn\u0026rsquo;t have too many forms either so this isn\u0026rsquo;t too different from the original the one special thing we do here is use the layered toolbar for the ui which i will discuss soon enough css is used for the design i\u0026rsquo;ll introduce the applicable css incrementally when introducing a specific uh ui id i won\u0026rsquo;t go over the entire css and will instead go back to it when introducing a specific ui id i will cover the gener generic concepts first though we have only two constants in the css the first is the include native feature which should be on by default always the second is a standard label gap with between the label and the icon i think one millimeter is generally a good number here we don\u0026rsquo;t have too much in common between the forms at this level of the ui so there is only one method in common the init global toolbar method initializes the toolbar component when global toolbar is turned on which is the default we do two things here we set the toolbar to use the layered mode we do that by passing true to the toolbar constructor next we set the ui id of the toolbar to toolbar gradient which we use to indicate the translucent gradient background to separate the toolbar from the content the toolbar gradient is a gradient in black between 0.6 alpha to almost clear alpha this creates a slight fade effect over the title area so the title will still be visible if the image in the background has the same colors condemned doesn\u0026rsquo;t currently support alpha gradients as a solution the css support generates an image of the gradient during build and uses that the splash form is stupid simple we just place the logo in the center of the form initialize there is only one thing to discuss here and that\u0026rsquo;s the source of the netflix logo png file all images are declared in the css under two dummy ui ids specifically image imports 1 and image import 2. let\u0026rsquo;s just pause all the images into the resource file so we can later make use of them the source dpi is the reason we have two two image import ui ids when source dpi is set to zero it means we want the image imported as is not as a multi image but rather as a single image the logo is the only image where we\u0026rsquo;re interested in a multi-image behavior since most images come from the server we don\u0026rsquo;t need many multi images in the app the home form is the main ui of the application listing the content that the user can select from it\u0026rsquo;s a base form which means the title of the form is overlaid on the content and it uses border layout i\u0026rsquo;ll skip to the bottom first this class is created using a create method that returns the class instance it accepts the content information as the argument to the build to build the ui the actual implementation of the layout is in the init method we see above the edit method creates the entire ui it starts with the logo title we can see here that matches the same image we see in the splash screen that\u0026rsquo;s mostly laziness on my part but isn\u0026rsquo;t too far off from the actual netflix ui by adding a command to the side menu the hamburger menu appears automatically i didn\u0026rsquo;t want to go into the design and implementation of the side menu so i left this effectively blank i also added a search command which is again blank since i didn\u0026rsquo;t implement that technically i just used that for the icon i could have just used add material command to right bar but that would have required a slightly longer line of code so i chose this approach the main ui has a logo image here which is different from the background hero shot now you might be thinking why not have the logo as a part of the background hero shot why do we need a separate image for the logo two reasons we want the logo to appear above the play button exactly if it\u0026rsquo;s a part of the background image we won\u0026rsquo;t be able to tell where that is we want the ability to scale the background and foreground image differently in the background we want a scale to fill so the ui will look good in all resolutions for the foreground we want a scale to fit behavior so the logo text will always be visible regardless of the device resolution we set the uid for the series logo this impacts the following css the margin and padding push the logo to the right location in the middle with the right amount of spacing and the background is defined as transparent so the background image will be visible through the logo the play button looks like this again most of the work is done in the css for the button we use a 1.5 millimeter round border with a gray background and black foreground for the text slash icon the background image comes dynamically from the server so we can\u0026rsquo;t set it from css we create a box layout with the logo play button and the popular on netflix label we then set the background image dynamically using the style object the lead ui id is a special case with a dark gradient background it\u0026rsquo;s overlaid on the title image and needs that gradient to be visible on all image backgrounds the tabs are set to appear at the bottom explicitly to avoid top android style tabs i could have defined this in the theme constants but chose to do it in the code in this case the lead ui is a special case with a dark gradient background it\u0026rsquo;s overlaid on the title image and needs that gradient to be visible on all image backgrounds each list below is created via the movie list method they have a lead label top and reside within a scrollable container so we can scroll through them let\u0026rsquo;s look at the movie list method here i create a box x container that\u0026rsquo;s scrollable on the x-axis every element is a scalable image button that uses the thumb icon uiid when pressed we show the details form finally the tabs themselves are added to the bottom of the form thanks for watching i hope you enjoyed this course and found it educational\n","permalink":"https://www.codenameone.com/courses/course-03-build-real-world-full-stack-mobile-apps-java/143-client-ui/","summary":"\u003cblockquote\u003e\n\u003cp\u003eModule 15: Create a Netflix Clone\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/nImSppBdgkY?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003efor this final part we\u0026rsquo;ll cover the ui\nof the client which is relatively simple\nwe don\u0026rsquo;t have that many forms but to be\nfair the basic netflix app doesn\u0026rsquo;t have\ntoo many forms either\nso this isn\u0026rsquo;t too different from the\noriginal\nthe one special thing we do here is use\nthe layered toolbar for the ui which i\nwill discuss soon enough\ncss is used for the design i\u0026rsquo;ll\nintroduce the applicable css\nincrementally when introducing a\nspecific uh ui id\ni won\u0026rsquo;t go over the entire css and will\ninstead go back to it when introducing a\nspecific ui id\ni will cover\nthe gener generic concepts first though\nwe have only two constants in the css\nthe first is the include native feature\nwhich should be on by default always\nthe second is a standard label gap with\nbetween the label and the icon i think\none millimeter is generally a good\nnumber here\nwe don\u0026rsquo;t have too much in common between\nthe forms at this level\nof the ui so there is only one method in\ncommon\nthe init global toolbar method\ninitializes the toolbar component when\nglobal toolbar is turned on\nwhich is the default\nwe do two things here we set the toolbar\nto use the layered mode we do that by\npassing true to the toolbar constructor\nnext we set the ui id of the toolbar to\ntoolbar gradient which we use to\nindicate the translucent gradient\nbackground to\nseparate the toolbar from the content\nthe toolbar gradient is a gradient in\nblack between 0.6 alpha to almost clear\nalpha\nthis creates a slight fade effect over\nthe title area so the title will still\nbe visible if the image in the\nbackground has the same colors\ncondemned doesn\u0026rsquo;t currently support\nalpha gradients as a solution the css\nsupport generates an image of the\ngradient during build and uses that\nthe splash form is\nstupid simple\nwe just place the logo in the center of\nthe form initialize there is only one\nthing to discuss here and that\u0026rsquo;s the\nsource of the netflix logo png file\nall images are declared in the css\nunder two dummy ui ids specifically\nimage imports 1 and image import 2.\nlet\u0026rsquo;s just pause all the images into the\nresource file so we can later make use\nof them\nthe source dpi is the reason we have two\ntwo image import ui ids\nwhen source dpi is set to zero it means\nwe want the image imported as is\nnot as a multi image but rather as a\nsingle image\nthe logo is the only image where we\u0026rsquo;re\ninterested in a multi-image behavior\nsince most images come from the server\nwe don\u0026rsquo;t\nneed many multi images in the app\nthe home form is the main ui of the\napplication\nlisting the content that the user can\nselect from\nit\u0026rsquo;s a base form which means the title\nof the form is overlaid on the content\nand it uses border layout\ni\u0026rsquo;ll skip to the bottom first\nthis class is created using a create\nmethod that returns the class instance\nit accepts the content information\nas the argument to the build to build\nthe ui\nthe actual implementation of the layout\nis in the init method we see above\nthe edit method creates the entire ui\nit starts with the logo title we can see\nhere\nthat matches the same image we see in\nthe splash screen that\u0026rsquo;s mostly laziness\non my part\nbut isn\u0026rsquo;t\ntoo far off from the actual netflix ui\nby adding a command to the side menu the\nhamburger menu appears automatically i\ndidn\u0026rsquo;t want to go into the design and\nimplementation of the side menu so i\nleft this effectively blank\ni also added a search command which is\nagain blank since i didn\u0026rsquo;t implement\nthat technically i just used that for\nthe icon\ni could have just used add material\ncommand to right bar but that would have\nrequired a slightly longer line of code\nso i chose this approach\nthe main ui has a logo image here which\nis different from the background hero\nshot\nnow you might be thinking why not have\nthe logo as a part of the background\nhero shot why do we need a separate\nimage for the logo\ntwo reasons we want the logo to appear\nabove the play button exactly if it\u0026rsquo;s a\npart of the background image we won\u0026rsquo;t be\nable to tell where that is\nwe want the ability to scale the\nbackground and foreground image\ndifferently in the background we want a\nscale to fill so the ui will look good\nin all resolutions for the foreground we\nwant a scale to fit behavior so the logo\ntext will always be visible regardless\nof the device resolution\nwe set the uid for the series logo this\nimpacts the following css\nthe margin and padding push the logo to\nthe right location in the middle\nwith the right amount of spacing and the\nbackground is defined as transparent so\nthe background image will be visible\nthrough the logo\nthe play button looks like this again\nmost of the work is done in the css for\nthe button\nwe use a 1.5 millimeter round border\nwith a gray background and black\nforeground for the text slash icon\nthe background image comes dynamically\nfrom the server so we can\u0026rsquo;t set it from\ncss\nwe create a box layout with the logo\nplay button and the popular on netflix\nlabel\nwe then set the background image\ndynamically using the style object\nthe lead ui id is a special case with a\ndark gradient background it\u0026rsquo;s overlaid\non the title image and needs that\ngradient to be visible on all image\nbackgrounds\nthe tabs are set to appear at the bottom\nexplicitly to avoid top android style\ntabs\ni could have defined this in the theme\nconstants but chose to do it in the code\nin this case\nthe lead ui is a special case with a\ndark gradient background it\u0026rsquo;s overlaid\non the title image and needs that\ngradient to be visible on all image\nbackgrounds\neach list below is created via the movie\nlist method\nthey have a lead label\ntop and reside within a scrollable\ncontainer so we can scroll through them\nlet\u0026rsquo;s look at the\nmovie list method\nhere i create a box x container that\u0026rsquo;s\nscrollable on the x-axis every element\nis a scalable image button that uses the\nthumb icon uiid\nwhen pressed we show the details form\nfinally the tabs themselves are added to\nthe bottom of the form\nthanks for watching i hope you enjoyed\nthis course\nand found it educational\u003c/p\u003e","title":"Client UI"},{"content":"\nIn today\u0026rsquo;s update, we\u0026rsquo;re finally removing Proguard from the build process with many implications for all of us.\nCompliance Checks without Proguard Codename One only supports a subset of JavaSE\u0026rsquo;s API. While we\u0026rsquo;re constantly trying to expand the supported set of APIs, it would always be a partial list. Initially, this created a lot of problems where developers would send a build and find out that API X wasn\u0026rsquo;t supported.\nTo solve this problem, Steve came up with an ingenious trick. Maven builds run proguard on the finished jar, it implicitly fails if an API is missing and thus fails \u0026ldquo;compliance\u0026rdquo; before reaching the build servers.\nThis works well but has several problems:\nError messages are very obtuse It\u0026rsquo;s a bit slow We could do so much more With this update, we added a new check that replaces proguard with our own custom validator.\nThe amazing thing is that we can now support String.split()!\nThe Problem of String\u0026rsquo;s split() Don\u0026rsquo;t use String.split(). It\u0026rsquo;s a terrible API. I use it myself occasionally, but the feature is deeply problematic, which is why we didn\u0026rsquo;t add it.\nThe crux of the issue is that split() takes up a regex expression. Regex is deeply nuanced, one misplaced character can bring down an application. The parsing of regex is also challenging and fragile.\nThe real problem is that on JavaSE/Android split would have used the Java native version of split(), but on JavaScript/iOS it would use our implementation. That would mean a big difference in performance but also in functionality as a regex might work in the simulator then fail on the device.\nOur new compliance code now rewrites the split() calls in the code and converts them to our API. That means the behavior will be identical in the simulator and the device.\nAs a sidenote we also added broader support for String.format() across runtimes and included StandardCharsets constants, which helps close another gap between standard Java code and what developers expect to work inside Codename One.\nNew Java Versions on Android This also means we will be able to adopt newer versions of Java past 17. Android stopped updating JVMs after JDK 17, which means newer Java language features aren\u0026rsquo;t supported.\nHowever, we can now detect if a class uses newer bytecode and compile it down to JDK 17 levels. This means we can use JDK 25 features while maintaining Android compatibility.\nBug Fixes of Note This week we fixed some interesting bugs in the issue tracker.\nSimulator Location Support LocationSimulation was updated to replace the old JavaFX-based mapping with a JCEF-based implementation, along with follow-up fixes for JCEF detection and graceful fallback behavior.\nIncorporated Text Scale by Default The Initializr now defaults useLargerTextScaleBool to true in the generated theme.css.\nThis is a small change, but it improves the out-of-the-box experience in a very practical way.\nMultiline TextArea Supports Vertical Centering Vertical alignment wasn\u0026rsquo;t for multiline rendering in TextArea wasn\u0026rsquo;t supported for a long time. We now support centering both horizontally and vertically of multiline texts.\nAndroid Video Thumbnail Workaround On Android, a thumbnail sometimes produces a black-frame. This is an Android OS/VM bug unrelated to Codename One.\nA new opt-in workaround was added to improve seek preview behavior. You can enable it using:\nvideo.setVariable(Media.VARIABLE_ANDROID_SEEK_PREVIEW_WORKAROUND, Boolean.TRUE); This is one of my favorite things in Codename One. We can fix device/OS bugs for you.\nJavadoc Playground Links Were Tightened Up Now that the Playground is part of the normal workflow, it made sense to improve the links generated from Javadocs.\nThe “Open in playground” links were updated to use a base64-encoded payload, which makes them more robust and less prone to breaking on larger or more awkward examples.\nAlmost all Java code snippets in the JavaDoc now have an \u0026ldquo;open in playground\u0026rdquo; link next to them. A lot of the code might not work since the playground is still under heavy development. But we\u0026rsquo;ll get there\u0026hellip;\nJavaScript Support in ParparVM This is probably the most important feature this week, but it isn\u0026rsquo;t something most of you would \u0026ldquo;play with.\u0026rdquo; We added support for JavaScript as a target destination in our native VM.\nRight now this has no impact on you. When you send a build or use Playground/Initializr, you would still use TeaVM and its port. So why are we doing this?\nTeaVM is a fantastic project. But it\u0026rsquo;s heading in its own direction, which is different from ours. They are focusing on WASM which is not our choice. WASM makes sense if you want to write deep native code, not if you want to write UIs or front-end. We could fork TeaVM, but that would mean maintaining another port.\nThe value of maintaining a single VM that supports all the non-Java ports is powerful. By using ParparVM for our JavaScript port, we can move our support for Java language features at our own pace.\nClosing Thoughts I spent a lot of time this week on the issue tracker going through old issues. Assigning, closing and classifying stuff. If you opened issues in the past, we would appreciate your help in closing or classifying these.\nIt also stands for issues that are important to you and got buried under the mountain of issues. If there are any of those, then let us know. We won\u0026rsquo;t fix a lot of those. Some issues are just out of scope, and our scope is already huge. A lot are just too old by now, and it\u0026rsquo;s hard to tell what\u0026rsquo;s going on. But we\u0026rsquo;re doing our best to go through that list.\nOver this past week we closed over 30 issues, but there are still over 500 open issues. We\u0026rsquo;d appreciate your help in reducing these.\n","permalink":"https://www.codenameone.com/blog/compliance-improvements-simulator-updates-and-more/","summary":"\u003cp\u003e\u003cimg alt=\"Compliance Improvements, Simulator Updates, and More\" loading=\"lazy\" src=\"/blog/compliance-improvements-simulator-updates-and-more.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIn today\u0026rsquo;s update, we\u0026rsquo;re finally removing Proguard from the build process with many implications for all of us.\u003c/p\u003e\n\u003ch2 id=\"compliance-checks-without-proguard\"\u003eCompliance Checks without Proguard\u003c/h2\u003e\n\u003cp\u003eCodename One only supports a subset of JavaSE\u0026rsquo;s API. While we\u0026rsquo;re constantly trying to expand the supported set of APIs, it would always be a partial list. Initially, this created a lot of problems where developers would send a build and find out that API X wasn\u0026rsquo;t supported.\u003c/p\u003e","title":"Compliance Improvements, Simulator Updates, and More"},{"content":"\nThis week includes two important additions to Codename One.\nThe first is a new Playground, which gives us a much faster way to experiment with UI code, prototype ideas, and share small runnable examples.\nThe second is built-in support for the java.time API, which fills another long-standing gap in modern Java compatibility.\nBoth are useful on their own, and both remove a bit more friction from day-to-day development.\nA New Playground for Rapid UI Prototyping The new Playground is an interactive scripting environment for Codename One UI development.\nYou can try it here:\nOpen the Playground\nThe implementation is built on top of BeanShell, and that choice was very intentional.\nA playground should feel lightweight. It should encourage experimentation. You should be able to try an idea, tweak it, throw it away, and try the next version within seconds. That is very different from the normal compile-run cycle of a full application build.\nThe traditional cycle is still exactly what we want for real projects. But for prototyping, especially UI prototyping, it is often just too heavy. If all you want to do is test a layout, check an interaction, verify a component hierarchy, or try a styling idea, waiting for a full build gets in the way of the creative process.\nThat is why a scripting approach makes sense here.\nInstead of treating every experiment like a full application, the Playground lets you write a small piece of code and see the result immediately. That fits the rapid prototype mentality much better.\nHere is a simple example:\nContainer root = new Container(BoxLayout.y()); Button btn = new Button(\u0026#34;Click me\u0026#34;); btn.addActionListener(e -\u0026gt; Dialog.show(\u0026#34;Hello\u0026#34;, \u0026#34;World\u0026#34;, \u0026#34;OK\u0026#34;, null)); root.add(btn); root; This is exactly the kind of thing that benefits from an instant feedback loop. You are not building an app here. You are testing an idea.\nThe Playground also supports more structured approaches when you want them. You can write loose scripts, use lifecycle-style scripts, or return a component from a build(PlaygroundContext) method. That gives it enough flexibility to be useful for both quick experiments and slightly more realistic prototypes.\nAnother important part of this was making the scripting environment feel familiar to modern Java developers. Since BeanShell does not natively support Java 8 lambdas, the Playground adds transformation support so common listener patterns still work naturally in scripts.\nThat means code in the Playground can still feel close to the way we normally write Codename One code.\nBeyond basic script execution, the Playground includes a few features that make it much more useful in practice:\nshareable URLs for sending examples to other people an inspector tab for viewing the component hierarchy support for common UI and listener patterns pre-imported Codename One packages to reduce setup noise The shareable URL support is especially useful. A playground becomes far more valuable when it is not just a personal scratchpad, but also a communication tool. Being able to send someone a small, runnable UI example is great for demos, bug reports, support, and collaboration.\nIf you want to dig into the details, including architecture notes, supported script styles, lambda handling, inspector support, and current limitations, the full README is here:\nCodename One Playground README\nBuilt-in Support for java.time The other big addition is support for the java.time API.\nThis is another one of those APIs that modern Java developers expect to have available. The older date and time APIs have always been awkward, and java.time gave Java a much better model for representing dates, times, durations, offsets, and zones.\nThat support is now built into Codename One.\nThe implementation includes the core types developers are most likely to use in real code, including:\nInstant LocalDate LocalTime LocalDateTime OffsetDateTime ZonedDateTime Duration Period Clock ZoneId ZoneOffset DateTimeFormatter This matters for a few reasons.\nFirst, it makes shared Java code much easier to bring into Codename One projects. A lot of code written for server-side logic, validation, scheduling, formatting, or general business rules already uses java.time. Supporting that API reduces the amount of adaptation needed.\nSecond, java.time gives us a much clearer way to express time-related logic. It separates concepts that should be separate. A local date is not the same thing as an instant. A duration is not the same thing as a period. A zoned date-time is not the same thing as a local date-time. These distinctions help prevent bugs and make code easier to understand.\nThird, this support improves behavior in areas that are notoriously tricky: leap years, daylight saving transitions, zone offsets, parsing, and formatting. The included tests specifically cover edge cases like DST transitions in America/New_York, leap-day handling, localized formatting, and translator/runtime consistency.\nFor example, code like this now becomes natural in Codename One:\nimport java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; LocalDate today = LocalDate.now(); LocalDateTime meeting = LocalDateTime.of(2026, 4, 2, 14, 30); ZonedDateTime localMeeting = ZonedDateTime.of(meeting, ZoneId.of(\u0026#34;America/New_York\u0026#34;)); See it in the playground\u0026hellip;\nAnd formatting/parsing flows look the way modern Java developers expect:\nimport java.time.LocalDateTime; import java.time.format.DateTimeFormatter; LocalDateTime parsed = LocalDateTime.parse( \u0026#34;2026-03-27 09:45:00\u0026#34;, DateTimeFormatter.ofPattern(\u0026#34;yyyy-MM-dd HH:mm:ss\u0026#34;) ); See it in the playground\u0026hellip;\nThis is a meaningful compatibility milestone because it removes another obvious gap in the Java API surface available inside Codename One.\nClosing Thoughts The Playground gives us a faster and more natural way to prototype UI ideas.\nThe java.time support gives us a better and more modern foundation for date and time code.\nThese are very different additions, but both make everyday development smoother, and both push Codename One further in the right direction.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/playground-and-java-time-support/","summary":"\u003cp\u003e\u003cimg alt=\"Playground and java.time Support in Codename One\" loading=\"lazy\" src=\"/blog/playground-and-java-time-support.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis week includes two important additions to Codename One.\u003c/p\u003e\n\u003cp\u003eThe first is a new \u003ca href=\"/playground/\"\u003ePlayground\u003c/a\u003e, which gives us a much faster way to experiment with UI code, prototype ideas, and share small runnable examples.\u003c/p\u003e\n\u003cp\u003eThe second is built-in support for the \u003cstrong\u003e\u003ccode\u003ejava.time\u003c/code\u003e API\u003c/strong\u003e, which fills another long-standing gap in modern Java compatibility.\u003c/p\u003e\n\u003cp\u003eBoth are useful on their own, and both remove a bit more friction from day-to-day development.\u003c/p\u003e","title":"Playground and java.time Support in Codename One"},{"content":"\nThere are a few updates in Codename One 7.0.229 that are worth discussing together because they all point in the same direction: less legacy friction, more modern Java and iOS workflows, and documentation that reflects how we actually build projects today.\nBuilt-in Support for Java Stream APIs One of the long standing gaps in our Java compatibility story was java.util.stream.\nWe have supported Java 8 language features for a long time, but streams remained one of those APIs that developers would miss the moment they tried to bring modern Java habits or shared code into a Codename One project. That changes now.\nWe now ship built-in support for the core stream API surface, including operations such as filter(), map(), sorted(), distinct(), limit(), skip(), reduce(), collect(), count(), and predicate checks such as anyMatch() and allMatch(). We also include the basic Collectors helpers such as toList() and joining().\nHere is a simple example:\nimport java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; List\u0026lt;String\u0026gt; names = Stream.of(\u0026#34;Shai\u0026#34;, \u0026#34;Steve\u0026#34;, \u0026#34;Chen\u0026#34;, \u0026#34;Shai\u0026#34;) .distinct() .filter(name -\u0026gt; name.length() \u0026gt;= 4) .map(String::toUpperCase) .sorted() .collect(Collectors.toList()); And another example:\nimport java.util.stream.Collectors; import java.util.stream.Stream; String platforms = Stream.of(\u0026#34;iOS\u0026#34;, \u0026#34;Android\u0026#34;, \u0026#34;Desktop\u0026#34;, \u0026#34;Web\u0026#34;) .filter(name -\u0026gt; !name.equals(\u0026#34;Desktop\u0026#34;)) .collect(Collectors.joining(\u0026#34;, \u0026#34;)); Why does this matter?\nFirst, it makes normal Java code much more portable into Codename One. A lot of server side utilities, shared business logic and even ordinary everyday examples now read the way modern Java developers expect them to read.\nSecond, streams are not just shorter syntax. They let us express data transformation more clearly. Filtering, mapping and collecting data is something we do all the time in UI code, networking code and data preparation. Replacing hand-written loops with a more declarative pipeline makes code easier to read and often easier to maintain.\nThird, this removes one of the obvious \u0026ldquo;yes, but\u0026hellip;\u0026rdquo; answers when discussing modern Java support in Codename One. That is an important milestone.\nSwift Package Manager Support The other big update is that we added Swift Package Manager support to Codename One, and documented it in the Working with iOS section of the developer guide.\nThe first thing to understand is that for existing projects, nothing should suddenly change. The default behavior is the compatibility mode, auto, so older projects that already use CocoaPods should just keep working.\nFor non-native developers, a bit of background helps here.\nCocoaPods and Swift Package Manager are both dependency managers for iOS/macOS native libraries. Historically, a lot of Apple ecosystem libraries were distributed with CocoaPods instructions, so that became our integration path too. But CocoaPods is now effectively in maintenance mode, while Apple is pushing the ecosystem toward Swift Package Manager. That means the long term path forward is SPM.\nAlso, despite the name, Swift Package Manager is not \u0026ldquo;only for Swift code\u0026rdquo;. It can manage dependencies for Swift packages, but those packages can expose Swift code, Objective-C code, or mixed native code. From a Codename One developer perspective this is about how native iOS dependencies are resolved and linked. It does not mean your project suddenly needs to become a Swift project.\nThe important build hint is:\nios.dependencyManager=auto In practice, this is the mode most developers should start with because it preserves backward compatibility:\nIf you only define ios.pods, we use CocoaPods. If you only define ios.spm.*, we use SPM. If you define both families of hints, both are applied. We support four modes:\nauto is the default compatibility mode and should make existing projects just work. both applies both CocoaPods and Swift Package Manager. This is the practical migration mode. cocoapods forces CocoaPods only. spm forces Swift Package Manager only. The both mode matters because migration is rarely a one-step event. One native dependency may still document CocoaPods while another has already moved to SPM. Supporting both lets you migrate incrementally instead of blocking on the slowest vendor.\nHere is an SPM-only setup:\nios.dependencyManager=spm ios.spm.packages=swift-collections|https://github.com/apple/swift-collections.git|from:1.1.0 ios.spm.products.swift-collections=Collections The package syntax is:\n\u0026lt;identity\u0026gt;|\u0026lt;url\u0026gt;|\u0026lt;requirement\u0026gt; Supported requirement formats include from:, exact:, branch:, revision: and range:.\nIt also helps to think of the SPM hints as the rough equivalent of the CocoaPods hints:\nCocoaPods Swift Package Manager What it means ios.pods=GoogleMaps ios.spm.products.googlemaps=GoogleMaps The native library or product you want linked Pod source declaration in the Podfile / ios.pods.sources when needed Package URL inside ios.spm.packages Where the dependency comes from Pod version expression inside ios.pods Requirement inside ios.spm.packages How the dependency version is selected ios.pods.platform=... Package requirement and normal Xcode/SPM resolution Platform/version compatibility constraints The mapping is not one-to-one because CocoaPods thinks in terms of pods and pod sources, while SPM thinks in terms of packages and exported products. But conceptually they solve the same problem: bringing an external native dependency into the generated iOS project.\nAnother important detail is debugging. As documented in the native source debugging section, you should now open the .xcworkspace whenever it is generated, not just for CocoaPods builds. That workspace is no longer exclusive to CocoaPods. It can also be the right entry point for SPM-based or mixed dependency setups.\nTutorial Trail Refresh Over March 15-17, 2026 we refreshed a large portion of the tutorial trail and revised the written text across the course material.\nThis is important because some of the original videos are still valuable, but they naturally show the tooling and assumptions of their time. The written lessons now do a better job of acting as the current source of truth for the modern Codename One workflow, especially around Maven, Initializr, CSS and current project structure.\nThe course hubs are here:\nJava for Mobile Devices Deep Dive into Mobile Development with Codename One Build Real World Full Stack Mobile Apps in Java If you want examples of the revised text style, have a look at:\nIntroduction Threading and the EDT 41. Post Image and Video from NewPostForm I like this direction because it treats the older video material honestly. We are not trying to pretend nothing changed. We are preserving the conceptual value of the material while updating the written trail so new developers are not pushed toward obsolete setup steps.\nUWP Removal from the Maven Plugin With Codename One 7.0.229, released on March 20, 2026, we are officially removing the UWP target from the Maven plugin.\nThis is really an acknowledgment of reality more than a sudden functional change.\nThe UWP port has already been treated as historical in the updated documentation, including the developer guide, the historical UWP chapter, and the related notes in push documentation. New Maven templates and current project generation flows should not keep advertising a target that we no longer consider part of the supported day to day path.\nThat said, it is important to highlight one subtle point: the UWP build servers are still functioning for legacy cases. So if you have an older codebase and you absolutely need to keep it alive, this is not a statement that those servers suddenly vanished overnight.\nBut for current work, the better answer on Windows is the desktop Windows build. It fits the present Codename One workflow much better, it is the path we actively support, and for most developers it is simply the more practical alternative.\nThis is exactly the sort of cleanup we need to keep making. Carrying old targets indefinitely in the main tooling creates confusion for new developers and false expectations for existing ones. Preserving legacy infrastructure where practical is good. Presenting that legacy path as a first-class modern target is not.\nClosing Thoughts The theme across all of these changes is pretty simple.\nWe are making Codename One more comfortable for modern Java development, more aligned with the current iOS ecosystem, more honest in the documentation, and more focused in the supported build targets.\nThat is the right direction.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/stream-apis-spm-tutorial-trail-and-uwp/","summary":"\u003cp\u003e\u003cimg alt=\"Stream APIs, Swift Package Manager, Tutorial Trail Refresh, and the UWP Transition\" loading=\"lazy\" src=\"/blog/stream-apis-spm-tutorial-trail-and-uwp.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThere are a few updates in Codename One \u003ccode\u003e7.0.229\u003c/code\u003e that are worth discussing together because they all point in the same direction: less legacy friction, more modern Java and iOS workflows, and documentation that reflects how we actually build projects today.\u003c/p\u003e\n\u003ch2 id=\"built-in-support-for-java-stream-apis\"\u003eBuilt-in Support for Java Stream APIs\u003c/h2\u003e\n\u003cp\u003eOne of the long standing gaps in our Java compatibility story was \u003ccode\u003ejava.util.stream\u003c/code\u003e.\u003c/p\u003e","title":"Stream APIs, Swift Package Manager, Tutorial Trail Refresh, and the UWP Transition"},{"content":"\nWe now have official experimental support for Java 17 in Codename One projects.\nThis is available through the Initializr. To use it you should generate a new project and select Java 17 during project creation.\nSupport for Java 17 required work across the toolchain, the generated projects and several targets. This wasn\u0026rsquo;t just a matter of changing a version number and hoping for the best.\nHow This Works You can use these new Java 17 projects with practically any JDK for the build itself. We tested this with JDK 21 and even JDK 25. In other words, you select Java 17 for the generated project, but your local machine does not need to run on JDK 17 just to build it.\nCaveats There are a few caveats you should know before jumping in:\nThe desktop target is not currently supported for Java 17 projects. If there is demand we can add that. You can still use the jar target to build desktop applications with Codename One, and that works fine with Java 17. UWP will not be supported. That target was already deprecated, so there is no point in doing the extra work there. Other targets should just work. What Java 17 Syntax Works? This support includes modern language syntax that makes day to day code much nicer to write.\nAt the moment this includes features like var, switch expressions and text blocks. Record support is planned for Codename One 7.0.229, slated for release on March 20, 2026.\nFor example, var lets us remove obvious type boilerplate from local variables:\nvar greeting = \u0026#34;Hello\u0026#34;; var target = \u0026#34;Codename One\u0026#34;; Switch expressions are more concise and make it easier to return a value directly from the switch:\nvar message = switch (greeting.length()) { case 5 -\u0026gt; greeting + \u0026#34; \u0026#34; + target; default -\u0026gt; \u0026#34;unexpected\u0026#34;; }; Text blocks are also supported, so multi-line strings are much more readable:\nvar textBlock = \u0026#34;\u0026#34;\u0026#34; Java 17 language features should compile in tests. \u0026#34;\u0026#34;\u0026#34;; Record syntax is also queued for Codename One 7.0.229, slated for release on March 20, 2026, so Java 17 projects will be able to use compact immutable data carriers too.\nFor example, this record will compile once 7.0.229 is available on March 20, 2026:\nrecord Person(String name, int age) {} var person = new Person(\u0026#34;Duke\u0026#34;, 29); System.out.println(person.name()); That means you can start using language improvements that make code cleaner and easier to read, and records will join that list in 7.0.229 on March 20, 2026.\nThis still does not include support for newer JDK APIs such as streams. As mentioned in the previous post, if you need streams today there is already a cn1lib solution for that, and we hope to improve the built-in story over time.\nWhat About Java 21 and 25? Since we mentioned JDK 21 and 25 above, it is worth clarifying the roadmap.\nWe do plan to add support for newer language levels in a coming update. That is a different challenge, because Android only supports up to Java 17 today.\nWe would still like to introduce that support, but at the moment Java 17 is the more important milestone.\nOther Updates Worth Mentioning A few other useful things landed over the past week.\nThe Initializr now includes more advanced CSS theme editing with live preview, and there were several follow-up fixes to make theming behave more reliably. This is relevant if you are starting a fresh project anyway, because the Initializr has become a much stronger starting point than it was even a couple of weeks ago.\nWe also finished updating all macOS build servers to use Xcode 26.\nAnother useful update is a newer version of the Codename One Bluetooth LE cn1lib, available in the bluetoothle-codenameone repository. This library now uses a native Codename One bridge implementation adapted from the original Bluetooth LE plugin lineage.\nIf you are using a Maven-based Codename One project, add it with:\n\u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;com.codenameone\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;cn1-bluetooth-lib\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;1.0.0\u0026lt;/version\u0026gt; \u0026lt;type\u0026gt;pom\u0026lt;/type\u0026gt; \u0026lt;/dependency\u0026gt; If you are using a classic Codename One project, you can still integrate it as a .cn1lib by adding the library to your project\u0026rsquo;s lib/ directory, running Refresh Libs, and rebuilding. The library requires Java 8.\nHere is a small usage sample:\nfinal Bluetooth bt = new Bluetooth(); Form main = new Form(\u0026#34;Bluetooth Demo\u0026#34;); main.setLayout(new BoxLayout(BoxLayout.Y_AXIS)); main.add(new Button(new Command(\u0026#34;enable bluetooth\u0026#34;) { @Override public void actionPerformed(ActionEvent evt) { try { if (!bt.isEnabled()) { bt.enable(); } if (!bt.hasPermission()) { bt.requestPermission(); } } catch (IOException ex) { ex.printStackTrace(); } } })); main.add(new Button(new Command(\u0026#34;initialize\u0026#34;) { @Override public void actionPerformed(ActionEvent evt) { try { bt.initialize(true, false, \u0026#34;bluetoothleplugin\u0026#34;); } catch (IOException ex) { ex.printStackTrace(); } } })); Try Java 17 on a Real Project If you have been waiting for a more modern Java syntax level in Codename One, this is the time to give it a try.\nCreate a new project with the Initializr, select Java 17 and see how it feels in a real application. If you run into issues on Android, iOS, JavaScript or any other target, let us know. That feedback is what will help us polish this support and move it forward.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/official-experimental-java-17-support/","summary":"\u003cp\u003e\u003cimg alt=\"Official Experimental Java 17 Support for Codename One Projects\" loading=\"lazy\" src=\"/blog/official-experimental-java-17-support.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe now have official experimental support for Java 17 in Codename One projects.\u003c/p\u003e\n\u003cp\u003eThis is available through the \u003ca href=\"/initializr/\"\u003eInitializr\u003c/a\u003e. To use it you should generate a new project and select \u003cstrong\u003eJava 17\u003c/strong\u003e during project creation.\u003c/p\u003e\n\u003cp\u003eSupport for Java 17 required work across the toolchain, the generated projects and several targets. This wasn\u0026rsquo;t just a matter of changing a version number and hoping for the best.\u003c/p\u003e","title":"Official Experimental Java 17 Support for Codename One Projects"},{"content":"\nA lot landed since the last update, so I want to give you a practical summary of what changed and what matters.\nXcode 26 Migration Has Started We started the Xcode 26 migration process.\nThis is a staged rollout, which means some iOS builds now run on the newer Xcode and others still run on the previous setup. If you hit a suspicious failure, please report it quickly so we can separate migration fallout from ordinary regressions.\nThe migration is tracked in issue #4456.\nUIScene Support: Start Testing with ios.uiscene We also added initial UIScene support and this is one you should start testing now. The ios.uiscene flag enables this behavior and we expect UIScene support to become an Apple requirement starting with iOS 27, so we are trying to be ready ahead of time instead of scrambling at the last minute.\nInitializr Now Generates Localization Resource Bundles The new Initializr now generates localization bundles as part of project creation, including UI support and preview in the wizard.\nThat means i18n starts as part of the default app flow instead of becoming cleanup work later on. We also fixed follow-up l10n path issues and updated CSS tooling so localization directories are detected and passed correctly to the compiler/watch workflow.\nIf you haven’t looked at localization recently, we now support property resource bundles as part of the standard workflow. This is documented in the Developer Guide, and it aligns much better with modern project structure.\nAnother detail that is easy to miss: Codename One has implicit localization behavior. When a resource bundle is installed, Label text (and subclasses of Label) is localized automatically by key unless you explicitly disable it for a specific component.\nFor day to day work, the simulator has a very useful mode under Simulator \u0026gt; Auto Update Default Bundle. When enabled, missing keys are implicitly added to your default properties bundle while you run the app, which makes it much easier to iterate on UI text and l10n coverage.\nOther Updates Worth Calling Out Android now has support for adaptive icons, with documentation updates to clarify background image path behavior.\nOn iOS we fixed local notification replacement behavior, so newer notifications can override previous ones correctly. If you rely on notifications heavily, check the LocalNotification JavaDoc for the API details.\nIn the UI layer, ImageViewer now supports optional navigation arrows and a thumbnail strip. We also introduced EditableResources and CSSThemeCompiler, which should make theme and resource workflows easier to automate and evolve.\nWe also expanded regex support to include nested POSIX character classes, with additional tests around that behavior.\nLooking Ahead: JDK 17 Support I also want to close with something I have been working on for the past few months: JDK 17 support, tracked in issue #4577.\nThis is a big effort. It requires major rework across platforms and targets. Java 9 introduced serious compatibility breaks for us between the module system, removed packages, and invokedynamic implications, so getting this right is not a small patch.\nNewer VMs beyond 17 will likely need separate tracking because that transition is another major shift by itself. Android already supports 17, so that is our first target milestone.\nRight now CI runs with JDK 11, 17, and 21, but you still can’t build a Codename One application with JDK 17 end-to-end just yet.\nStreams are a special case since they are mostly an API layer issue. We may include that as part of this effort, although there is already a cn1lib for streams: CN1-Stream by Diamond Mubaarak.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/xcode-26-migration-and-localization-bundles/","summary":"\u003cp\u003e\u003cimg alt=\"Xcode 26 Migration, UIScene Rollout, Initializr Localization Bundles, and More\" loading=\"lazy\" src=\"/blog/xcode-26-migration-and-localization-bundles.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA lot landed since the last update, so I want to give you a practical summary of what changed and what matters.\u003c/p\u003e\n\u003ch2 id=\"xcode-26-migration-has-started\"\u003eXcode 26 Migration Has Started\u003c/h2\u003e\n\u003cp\u003eWe started the Xcode 26 migration process.\u003c/p\u003e\n\u003cp\u003eThis is a staged rollout, which means some iOS builds now run on the newer Xcode and others still run on the previous setup. If you hit a suspicious failure, please report it quickly so we can separate migration fallout from ordinary regressions.\u003c/p\u003e","title":"Xcode 26 Migration, UIScene Rollout, Initializr Localization Bundles, and More"},{"content":"\nWe have a few important updates that affect our tooling and build infrastructure.\nThe short version:\nThe new Initializr is now available at /initializr/. We will retire the old Initializr on February 27, 2026. Android build server upgrades start first, beginning the weekend of February 27-28, 2026. iOS (Mac) build server upgrades start on Thursday, March 5, 2026. The New Initializr Is Built with Codename One The new Initializr is implemented using Codename One itself.\nThis is great dogfooding for us: we use our own stack for one of the most important entry points into the platform. It also makes maintenance significantly easier for our team.\nAnother major change is architecture:\nThe new Initializr runs on the client machine. It no longer depends on a backend service for core operation. That gives us a simpler deployment model, fewer moving parts, and less backend operational overhead.\nUX Improvements and Feature Parity The new Initializr includes a better user experience while preserving the existing functionality people rely on.\nImprovements include:\nDark mode support. Basic UI styling support. Existing Initializr features carried forward. Our plan is to take the original Initializr offline on February 27, 2026.\nIf anything feels off in your workflow, please report it right away so we can fix it quickly.\nBuild Server Upgrades: Android First, Then iOS We are also starting staged infrastructure upgrades for our build servers.\nThe relevant tracking issues are:\nMac/iOS build server update: Issue #4456 Android build server update: Issue #4466 We will start with Android on the weekend of February 27-28, 2026.\nThe iOS upgrade starts on March 5, 2026 (Thursday). This part is more challenging because it requires an operating system upgrade on the Mac infrastructure, and unlike Android, it is not something we can trivially roll back once we begin.\nWe might also need coordination with our hosting provider during this stage, which is another reason we are sequencing the rollout carefully.\nPlease Report Problems Immediately As usual, if you notice anything wrong with builds or any other Codename One service, tell us immediately.\nFast reporting helps us isolate and fix issues before they affect more users.\nCommunity Support: Use GitHub Discussions One more important point: GitHub Discussions is now the best place to get community support from us: https://github.com/codenameone/CodenameOne/discussions\nIt is also the same system used for comments under blog posts, so discussions stay in one place. For support, this is now better than Reddit and much better than Stack Overflow for Codename One-specific questions.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-initializr-and-build-server-migrations/","summary":"\u003cp\u003e\u003cimg alt=\"New Initializr and build server migrations\" loading=\"lazy\" src=\"/blog/new-initializr-and-build-server-migrations/new-initializr-and-build-server-migrations.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe have a few important updates that affect our tooling and build infrastructure.\u003c/p\u003e\n\u003cp\u003eThe short version:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eThe new \u003cstrong\u003eInitializr\u003c/strong\u003e is now available at \u003ca href=\"/initializr/\"\u003e/initializr/\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003eWe will retire the old Initializr on \u003cstrong\u003eFebruary 27, 2026\u003c/strong\u003e.\u003c/li\u003e\n\u003cli\u003eAndroid build server upgrades start first, beginning the weekend of \u003cstrong\u003eFebruary 27-28, 2026\u003c/strong\u003e.\u003c/li\u003e\n\u003cli\u003eiOS (Mac) build server upgrades start on \u003cstrong\u003eThursday, March 5, 2026\u003c/strong\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"the-new-initializr-is-built-with-codename-one\"\u003eThe New Initializr Is Built with Codename One\u003c/h2\u003e\n\u003cp\u003eThe new Initializr is implemented using \u003cstrong\u003eCodename One\u003c/strong\u003e itself.\u003c/p\u003e","title":"New Initializr and Build Server Migration Plan"},{"content":"\nFor a long time, the Codename One website ran on WordPress. That was a mistake.\nWordPress was a nightmare for us: clumsy to work with, slow, painful, and constantly getting in the way of basic maintenance. It repeatedly messed things up and made even simple updates harder than they should have been.\nWe have now moved to a static site setup based on Hugo and Cloudflare Pages.\nThis gives us a cleaner publishing pipeline, better performance, and a much easier way to keep content current.\nWhy We Made This Change The biggest goal was to make website updates fast, predictable, and automated.\nWith Hugo + Pages, content updates are now part of our normal Git workflow:\nEdit content in Markdown. Open a pull request. Review changes. Merge and deploy automatically. This removes a lot of manual overhead and lowers the risk of site breakage from plugin/theme drift.\nFaster Site and Faster Iteration Static rendering means less runtime complexity and fewer moving parts.\nIn practice this gives us:\nFaster page loads. Better caching behavior. Simpler, safer deployments. Easier rollbacks when needed. It also makes it practical for us to iterate on the website much more frequently.\nJavaDocs Are Better Now One specific improvement I want to call out is the JavaDocs.\nThey are now significantly better looking, easier to navigate, and much more searchable than before. This has been a long-standing pain point for many users (myself included), and the new setup makes this experience much better.\nNew Light/Dark Mode Toggle We also added a new light/dark mode toggle in the site menu.\nUse it to switch to the theme that is most comfortable for you while reading docs, tutorials, and blog posts.\nComments and Discussion: How Giscus Works We now use Giscus for post discussions.\nGiscus is GitHub Discussions-powered comments embedded directly in each blog post. It keeps conversations in one place and gives us moderation and threading tools that fit our development workflow.\nHow to use it Scroll to the Discussion section at the end of a blog post. Click Sign in with GitHub if prompted. Write your comment and submit. You can reply, edit, react, and follow discussions directly from GitHub as well. If you already use GitHub for Codename One issues or PRs, this should feel very natural.\nWe Need Your Feedback Please tell us what works and what doesn’t on the new website:\nBroken links. Missing pages. Search/navigation problems. Mobile layout issues. Anything unclear in docs/tutorial flow. You can leave feedback in the comments below.\nMigration Timing Right now the new site is available on beta.codenameone.com.\nOver the weekend of February 21-22, 2026, we will flip the switch so the new site becomes the default at www.codenameone.com.\nDuring that window, you might see minor link adjustments and occasional content reshuffling as we finalize the move.\nThanks for your patience, and thanks in advance for helping us polish the new site.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/moving-from-wordpress-to-hugo-cloudflare-pages/","summary":"\u003cp\u003e\u003cimg alt=\"WordPress to Hugo migration hero\" loading=\"lazy\" src=\"/blog/moving-from-wordpress-to-hugo-cloudflare-pages/moving-from-wordpress-to-hugo-cloudflare-pages.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eFor a long time, the Codename One website ran on WordPress. That was a mistake.\u003c/p\u003e\n\u003cp\u003eWordPress was a nightmare for us: clumsy to work with, slow, painful, and constantly getting in the way of basic maintenance. It repeatedly messed things up and made even simple updates harder than they should have been.\u003c/p\u003e\n\u003cp\u003eWe have now moved to a static site setup based on \u003cstrong\u003eHugo\u003c/strong\u003e and \u003cstrong\u003eCloudflare Pages\u003c/strong\u003e.\u003c/p\u003e","title":"Moving from WordPress to Hugo + Cloudflare Pages"},{"content":"Site Map Use this page to quickly navigate the most important parts of the Codename One website.\nStart Here Home Getting Started Introduction Developing in Codename One Documentation Developer Guide (HTML) Developer Guide (PDF) JavaDocs API Overview Build Tools Development Environment Architecture of the GUI Builder Designer Learning and Tutorials Training How do I How do I Archive (All Tutorials) Videos Hello World Course 1: Java for Mobile Devices Course 2: Deep Dive Mobile Development Course 3: Full Stack Mobile Apps in Java Demos and Showcase Demos Landing Page Kitchen Sink Demo Google Maps Demo Charts Demo Camera Demo Chat App Demo Uber Clone Demo Uber Eats Clone Demo SQL Playground Demo Application Gallery Extensions and Tools CN1Libs (Extensions/Plugins) Build Server Cloud Services Advanced Build Signing Product and Business Pricing Compare Comparison Chart About Us Executive Overview Mobile App Development Cost Mobile App Design \u0026amp; Development Services Community and Support Blog Discussion Forum FAQ Issues (GitHub) Search Account and Cloud Dashboard Dashboard (Secure) Build App (Legacy Dashboard Entry) My Account Login / Build Cloud Account Legal and Policies Terms Privacy Related External Resources GitHub Organization Codename One Main Repository Stack Overflow (codenameone tag) Reddit Community ","permalink":"https://www.codenameone.com/site-map/","summary":"\u003ch2 id=\"site-map\"\u003eSite Map\u003c/h2\u003e\n\u003cp\u003eUse this page to quickly navigate the most important parts of the Codename One website.\u003c/p\u003e\n\u003ch2 id=\"start-here\"\u003eStart Here\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/getting-started/\"\u003eGetting Started\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/introduction/\"\u003eIntroduction\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/developing-in-codename-one/\"\u003eDeveloping in Codename One\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"documentation\"\u003eDocumentation\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/developer-guide\"\u003eDeveloper Guide (HTML)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/files/developer-guide.pdf\"\u003eDeveloper Guide (PDF)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/javadoc/\"\u003eJavaDocs\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/api/\"\u003eAPI Overview\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/build-tools/\"\u003eBuild Tools\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/development-environment/\"\u003eDevelopment Environment\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/architecture-of-the-gui-builder/\"\u003eArchitecture of the GUI Builder\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/designer/\"\u003eDesigner\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"learning-and-tutorials\"\u003eLearning and Tutorials\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/training/\"\u003eTraining\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/how-do-i/\"\u003eHow do I\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/howdoi/\"\u003eHow do I Archive (All Tutorials)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/videos/\"\u003eVideos\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/hello-world/\"\u003eHello World\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/course-01-java-for-mobile-devices/\"\u003eCourse 1: Java for Mobile Devices\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/course-02-deep-dive-mobile-development-with-codename-one/\"\u003eCourse 2: Deep Dive Mobile Development\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/course-03-build-real-world-full-stack-mobile-apps-java/\"\u003eCourse 3: Full Stack Mobile Apps in Java\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"demos-and-showcase\"\u003eDemos and Showcase\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/demos/\"\u003eDemos Landing Page\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/demo-kitchen-sink/\"\u003eKitchen Sink Demo\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/demo-google-maps-demo/\"\u003eGoogle Maps Demo\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/demo-charts-demo/\"\u003eCharts Demo\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/demo-camera-demo/\"\u003eCamera Demo\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/demo-chat-app/\"\u003eChat App Demo\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/demo-uberclone/\"\u003eUber Clone Demo\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/demo-ubereats-clone/\"\u003eUber Eats Clone Demo\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/demo-sql-playground-sql-tutorial-in-the-browser-iphone-ios-android-windows/\"\u003eSQL Playground Demo\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/app-gallery/\"\u003eApplication Gallery\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"extensions-and-tools\"\u003eExtensions and Tools\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/cn1libs/\"\u003eCN1Libs (Extensions/Plugins)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/build-server/\"\u003eBuild Server\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/cloud/\"\u003eCloud Services\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/advanced-build/\"\u003eAdvanced Build\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/signing/\"\u003eSigning\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"product-and-business\"\u003eProduct and Business\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/pricing/\"\u003ePricing\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/compare/\"\u003eCompare\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/comparison-chart/\"\u003eComparison Chart\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/about-us/\"\u003eAbout Us\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/executive-overview/\"\u003eExecutive Overview\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/mobile-app-development-cost-codename-one/\"\u003eMobile App Development Cost\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/mobile-app-design-development-services/\"\u003eMobile App Design \u0026amp; Development Services\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"community-and-support\"\u003eCommunity and Support\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/blog/\"\u003eBlog\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/discussion-forum/\"\u003eDiscussion Forum\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/faq/\"\u003eFAQ\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/issues/\"\u003eIssues (GitHub)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/search/\"\u003eSearch\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"account-and-cloud-dashboard\"\u003eAccount and Cloud Dashboard\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://cloud.codenameone.com/secure/index.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDashboard (Secure)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://cloud.codenameone.com/buildapp/index.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eBuild App (Legacy Dashboard Entry)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/my-account/\"\u003eMy Account\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://cloud.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eLogin / Build Cloud Account\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"legal-and-policies\"\u003eLegal and Policies\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/terms/\"\u003eTerms\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/privacy/\"\u003ePrivacy\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"related-external-resources\"\u003eRelated External Resources\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/codenameone\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGitHub Organization\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/codenameone/CodenameOne\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCodename One Main Repository\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://stackoverflow.com/questions/tagged/codenameone\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eStack Overflow (\u003ccode\u003ecodenameone\u003c/code\u003e tag)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.reddit.com/r/cn1/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eReddit Community\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e","title":"Site map"},{"content":"\nThis is the final course released as part of our 2017-2019 courses for Codename One mobile development. Wehope you find it useful. Even though some material is out of date, the vast majority is still very relevant and applicable.\nWe worked with many mobile developers over the years and one common thread is the process of solving the same problems all over again. Everyone is building an Uber clone, a social media app, a restaurant ordering app or some other common template.\nEven if you aren\u0026rsquo;t it\u0026rsquo;s very likely you are building a variation of the same idea e.g. one of my friends has a startups that bills itself as \u0026ldquo;air b\u0026amp;b for eating at peoples homes\u0026rdquo;\u0026hellip; This is common even in corporate applications where we redo the same ideas again \u0026amp; again.\nThis course tries to build the common templates and it\u0026rsquo;s constantly evolving to add more applications!\nIt offers a set of full featured app building tutorials from start to finish without skimming on details\u0026hellip;\nI cover the full stack which is rare in the Java world. We go into the server side, the client side, deployment to the stores, server provisioning in the cloud, database creation, UI design, adapting the design, working with photoshop, coding, security and every other aspect you can think of in this course.\n","permalink":"https://www.codenameone.com/course-03-build-real-world-full-stack-mobile-apps-java/","summary":"\u003cp\u003e\u003cimg alt=\"Hero image\" loading=\"lazy\" src=\"/img/build-real-world-full-stack-mobile-apps-in-java.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is the final course released as part of our 2017-2019 courses for Codename One mobile development. Wehope you find it useful. Even though some material is out of date, the vast majority is still very relevant and applicable.\u003c/p\u003e\n\u003cp\u003eWe worked with many mobile developers over the years and one common thread is the process of solving the same problems all over again. Everyone is building an Uber clone, a social media app, a restaurant ordering app or some other common template.\u003c/p\u003e","title":"Build Real World Full Stack Mobile Apps in Java - Free Course"},{"content":"\nThis is the second part of my online courses from 2017 that are now available for free. In this course we go beyond the developer guide and the online docs to explain how to work with crucial Codename One tools required for building real world apps. We explain everything from device portability to native interfaces (access to native device features) and much more!\nAs part of this course we cover the process of building a simple restaurant ordering system and we cover several complex Codename One API\u0026rsquo;s.\nThe original version of the course included a section created by Chidiebere Okwudire the creator of parse4cn1 which is removed here. I chose to omit it since the status of the Parse project is unclear and I\u0026rsquo;m not sure about IP ownership for that section.\n","permalink":"https://www.codenameone.com/course-02-deep-dive-mobile-development-with-codename-one/","summary":"\u003cp\u003e\u003cimg alt=\"Hero image\" loading=\"lazy\" src=\"/img/deep-dive-into-mobile.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is the second part of my online courses from 2017 that are now available for free. In this course we go beyond the developer guide and the online docs to explain how to work with crucial Codename One tools required for building real world apps. We explain everything from device portability to native interfaces (access to native device features) and much more!\u003c/p\u003e\n\u003cp\u003eAs part of this course we cover the process of building a simple restaurant ordering system and we cover several complex Codename One API\u0026rsquo;s.\u003c/p\u003e","title":"Deep Dive into Mobile Development with Codename One - Free Online Course Material"},{"content":"\nFollowing is the full text and videos of an online course hosted historically on teachable.\nThe full course includes videos, slides and transcripts comprising roughly 25 hours of material. It\u0026rsquo;s somewhat out of date by the \u0026ldquo;latest and greatest\u0026rdquo; in Codename One, e.g. it predated Maven support and was created before we decided to focus on CSS. However, most of the concepts still apply and would probably work out of the box.\nThe first course covers all the basics of mobile development, how to build an app, etc. The followups cover the more advanced materials culminating in full scale app development of clones of popular apps such as Facebook, Uber, Whatsapp, etc. These clones also cover the server component briefly so they include portions covering Spring Boot and other full stack concepts.\n","permalink":"https://www.codenameone.com/course-01-java-for-mobile-devices/","summary":"\u003cp\u003e\u003cimg alt=\"Hero image\" loading=\"lazy\" src=\"/img/java-for-mobile-devices.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eFollowing is the full text and videos of an online course hosted historically on teachable.\u003c/p\u003e\n\u003cp\u003eThe full course includes videos, slides and transcripts comprising roughly 25 hours of material. It\u0026rsquo;s somewhat out of date by the \u0026ldquo;latest and greatest\u0026rdquo; in Codename One, e.g. it predated Maven support and was created before we decided to focus on CSS. However, most of the concepts still apply and would probably work out of the box.\u003c/p\u003e","title":"Java for Mobile Devices - Free online course"},{"content":"\nWe have made some upgrades to our push notification server API. If you deploy apps to Android and use push notifications, you will need to make a small change to the server-side code that sends the HTTP request to our push server. If you do not send push notifications to Android devices, you can ignore this PSA.\nThe Short Version Our Push API now requires a JSON key instead of the old FCM API key. For example, the following is a template for a push notification, (copied from the push cheatsheet).\nhttps://push.codenameone.com/push/push?token=PUSH_TOKEN \u0026amp;device=DEVICE_ID1\u0026amp;device=DEVICE_ID2\u0026amp;...\u0026amp;device=DEVICE_IDN \u0026amp;type=PUSH_TYPE{1|2|3|4|5|99|100|101} \u0026amp;auth=FCM_SERVER_API_KEY \u0026amp;certPassword=ITUNES_CERT_PASSWORD \u0026amp;cert=ITUNES_CERT_URL \u0026amp;body=MESSAGE_BODY \u0026amp;production=ITUNES_PRODUCTION_PUSH{true|false} \u0026amp;sid=WNS_SID \u0026amp;client_secret=WNS_CLIENT_SECRET Currently, the auth parameter will be set to an FCM API key, it might look something like auth=AAAABbbbCccDddEeeeFfffGGggHhhhIiiiJjjjKkkkLlllMmmmNnnnOooPppQqqRrrrSsssTttUuuuVvvvWxxxYyyyZzzz\nYou will need to change this parameter to be a URL (reachable by the Codename One push server) to a the JSON key for your service. It will look something like:\nauth=https%3A%2F%2Fexample.com%2Fsecret%2Fpath%2Fto%2Fservice-account-file.json You can find instructions on how to generate this service-account-file.json (your JSON key) in the Firebase documentation here. The following instructions are copied from there:\nTo generate a private key file for your service account:\nIn the Firebase console, open Settings \u0026gt; Service Accounts.\nClick Generate New Private Key , then confirm by clicking Generate Key.\nSecurely store the JSON file containing the key.\nThe Slightly Longer Version Google deprecated their legacy FCM APIs on June 20, 2023, and will be removing them on June 21, 2024. Our push servers use this API for all push notifications to Android devices, so we were required to migrate to their new \u0026ldquo;v1 HTTP API\u0026rdquo;. This migration involved some non-trivial changes to our push infrastructure, including, but not limited to, changing from using an FCM API key for authentication, to using OAuth2.\nThe OAuth2 authentication is more complicated than the old API key flow, as it involves multiple pieces of information, including the client ID, client secret, and project ID. To simplify this, Google encapsulates all of these credentials inside a single JSON file which can be used in an opaque manner via its Firebase SDKs.\nOn our side, we wanted to avoid unnecessary changes to our API to make this transition as seamless as possible for our users, so we haven’t added or removed any parameters from the request. We just changed the auth parameter to include the URL to your service-account-file.json, instead of an FCM API key. We chose not to include the whole JSON file contents in each request because the JSON file tends to be quite large and presents unnecessary a network overhead.\nWe may iterate on this approach in a non-breaking way based on user feedback.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/android-push-changes/","summary":"\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/blog/android-push-changes/4191c4440219cf07f21cdbfd7524bf49.webp-copy.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe have made some upgrades to our push notification server API. If you deploy apps to Android and use push notifications, you will need to make a small change to the server-side code that sends the HTTP request to our push server. If you do not send push notifications to Android devices, you can ignore this PSA.\u003c/p\u003e\n\u003ch2 id=\"the-short-version\"\u003eThe Short Version\u003c/h2\u003e\n\u003cp\u003eOur Push API now requires a JSON key instead of the old FCM API key. For example, the following is a template for a push notification, (copied from the \u003ca href=\"https://www.codenameone.com/files/push-cheatsheet.pdf\"\u003epush cheatsheet\u003c/a\u003e).\u003c/p\u003e","title":"Android Push Changes"},{"content":"This library provides a wrapper over the Android shared files API to allow your Codename One apps to read and write shared files (i.e. files accessible to other apps).\nSee this on GitHub.\nSee example app using this API here.\nSee use cases for accessing documents and other files here. Background Accessing documents and other files from shared storage (including external and cloud storage). In the past, we used to be able to access files on external storage directly using FileSystemStorage, but more recent android versions block this, requiring you to use theirShared Document APIs. a.k.a Share Files API and Storage Access Framework.\nOn Android devices from version 4.4 and above, apps can use the Storage Access Framework to let users choose documents and files for the app without needing special permissions. This enhances user privacy and control, and the accessed files remain on the device even after uninstalling the app.\nThe new Codename One Shared Files Library provides a wrapper over the Android shared files API to allow your Codename One apps to read and write shared files (i.e. files accessible to other apps).\nThis is a clean, secure and well-supported way to save and open files that could also be accessed by other applications.\nBasic Usage This API provides two abstractions:\nSharedFile – Represents a single file or directory.\nSharedFileManager – Provides access to the shared file system. Includes UI abstractions to select directories and files.\nFirst step is to request access to a file:\n// Open a directory // Will open a file chooser for user to access a directory SharedFileManager.getInstance().openDirectory().ready(sharedDirectory -\u0026gt; { // sharedDirectory is a SharedFile object }); // Open a file SharedFileManager.getInstance().openFile().ready(sharedFile -\u0026gt; { // sharedFile is a SharedFile object }); // Open file of specific type SharedFileManager.getInstance().openFile(\u0026#34;text/plain\u0026#34;).ready(sharedFile -\u0026gt; { // sharedFile is a SharedFile object }); Reading and Writing Files Use SharedFile.openInputStream() and SharedFile.openOutputStream(String mimetype) for reading and writing files.\nE.g.\nString textContents = Util.readToString(sharedFile.openInputStream()); textContents += \u0026#34;Modified\u0026#34;; try (OutputStream output = sharedFile.openOutputStream(sharedFile.getMimetype())) { output.write(textContents.getBytes(\u0026#34;UTF-8\u0026#34;)); } Creating New Files Open a directory\nCall directory.getChild(relativePath) to get reference to file.\nCall child.openOutputStream(mimetype)\nBookmarking For Later Use By default, the files you obtain will no be accessible the next time you load the app. You need to create a bookmarked file which will provide you with a persistent path that you can use to access the file.\nUse SharedFile.createBookmark() to create a bookmark.\nUse SharedFile.deleteBookmark() do remove a bookmark.\nUse SharedFile.isBookmark() to check if the file is a bookmarked file.\nUse SharedFileManager.openBookmark(String) to open a file given its bookmarked path. (i.e. bookmarkedFile.getPath())\nUse SharedFileManager.getBookmarks() for a list of all current bookmarks.\nInstallation Add the following maven dependency to your common/pom.xml file\ncom.codenameone sharedfiles-lib 0.1.0 pom Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nWits ICT — August 1, 2023 at 10:26 pm (permalink) Wits ICT says:\nThanks for this. And good to see blogs returning after a while.\nMobi Tribe — October 10, 2023 at 12:49 pm (permalink) Mobi Tribe says:\nThanks @Steve Hannah. This is awesome. Very useful… As @Wits ICT has said, glad to see you guys back. Hopefully you, Chen and Shai and the rest of the cn1 family still have good stuff in store.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-shared-files-library/","summary":"\u003cp\u003eThis library provides a wrapper over the Android shared files API to allow your Codename One apps to read and write shared files (i.e. files accessible to other apps).\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"codename-one-shared-files-library\" loading=\"lazy\" src=\"/blog/codename-one-shared-files-library/Shared-Files-Library-1024x536.jpg\"\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eSee this on \u003ca href=\"https://github.com/shannah/cn1-shared-files-lib\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGitHub.\u003c/a\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eSee example app using this API \u003ca href=\"https://github.com/shannah/cn1-shared-files-lib-demo/tree/master/common/src/main/java/com/codename1/shfltest\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere.\u003c/a\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eSee use cases for accessing documents and other files \u003ca href=\"https://developer.android.com/training/data-storage/shared/documents-files#use-cases\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere.\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003ch3 id=\"background\"\u003eBackground\u003c/h3\u003e\n\u003ch4 id=\"accessing-documents-and-other-files-from-shared-storage-including-external-and-cloud-storage\"\u003eAccessing documents and other files from shared storage (including external and cloud storage).\u003c/h4\u003e\n\u003cp\u003eIn the past, we used to be able to access files on external storage directly using \u003cstrong\u003e\u003cstrong\u003eFileSystemStorage\u003c/strong\u003e\u003c/strong\u003e, but more recent android versions block this, requiring you to use their\u003ca href=\"https://developer.android.com/training/data-storage/shared/documents-files\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eShared Document APIs\u003c/a\u003e. a.k.a Share Files API and Storage Access Framework.\u003c/p\u003e","title":"Codename One Shared Files Library"},{"content":"\nLearn how to build and publish iOS apps with Java or Kotlin without a Mac or Xcode in this comprehensive guide.\nIn this guide, we will get to know everything about iOS app development with Java.\nWe will discuss the development process, technology involved, prerequisites and general FAQs for building apps for iPhone/iPad using Java.\nHere are the major topics we’ve covered in this Java iOS app development guide.\nJava is one of the most popular programming languages around the world for everything from mobile development to enterprise and server-side applications.\nBeing a general-purpose, object-oriented and cross-platform programming language, Java enables developers Write Once, Run Anywhere (WORA), meaning that a Java program could be developed on any device and can be expected to run on any hardware that has a JVM (Java Virtual Machine).\nBefore we delve any further on how to code in Java for building iOS apps, we need to understand two most common approaches for app development…\nNative App Development Developing a platform specific app using its native programming language is called native app development.\nFor example, using Java or Kotlin for Android and Swift or Obj-C for iOS.\nCross-Platform App Development Developing apps using a single codebase that runs on multiple platforms refers to cross-platform app development.\nSome common cross-platform frameworks include Flutter, React Native and Codename One.\nRelated 📝 Top 10 Best Cross-Platform App Development Frameworks in 2023\nOn Android, Java or Kotlin are the native languages whereas Apple\u0026rsquo;s iOS platform relies on Swift and Obj-C as its native languages.\niOS App Development How are iOS apps made? If you want to get into writing iOS apps for the iPhone, iPads etc, you have two options:\nCode native iOS apps with Swift or Objective-C If you want to develop native apps for iOS, the official iOS SDK combined with Xcode allows you to write apps with Swift or Obj-C.\nUse a cross-platform framework For those who don’t know or want to learn Swift, a suitable cross-platform app development framework can compile your code to native iOS executable.\nJava vs Swift What language to choose for iOS development? Java is the native language for Android while Swift is the native language for Apple devices (iOS, macOS, watchOS, tvOS).\nBoth Java and Swift are static-type, object oriented and compiled programming languages.\nSwift is one of the newer programming languages while Java has been around for years.\nDifference between Java and Swift: Factors Java Swift Platform Java is not platform dependent Swift is dependent on iOS and MacOS Syntax Java is verbose and has complex syntax and code readability Swift has easy syntax and code readability Performance Modern Java is quite fast. A well optimized Java app can be as fast as a native app Swift is fast as it was built with performance in mind for Apple ecosystem Security Java is more secure compared to Swift with its byte-code verifier, JVM and security API\u0026rsquo;s Swift was designed to be memory safe. Swift can call Objective-C code which makes it prone to overflows Popularity Java is a mature and popular programming language. Tiobe and Redmonk ranks Java at number 3 by popularity Swift is reasonably popular for mobile development. Tiobe and Redmonk ranks Swift at number 10 and 11 respectively Both Java and Swift are quite different in terms of methods, syntax, code usability etc.\nSwift is obviously a preferred choice to develop apps specifically for the Apple ecosystem while Java is a preferred choice for Android development or cross-platform reusability.\nThe opportunity cost involved in learning Swift outweighs the benefits since its a platform dependant language.\nJava on Apple Hardware Why doesn\u0026rsquo;t Apple support Java? By now you might be thinking ‘if Java code can run on any platform, why can’t Java run on iOS?’\nJava can run on any platform that has a compatible Java Virtual Machine (JVM). Since Apple doesn’t support JVM for iOS, Java can’t run on iPhones and iPads.\nApple makes sure that only Swift and Objective-C has 100% vendor support on iOS by forbidding alternative runtimes from being deployed on it.\nJava developers have long been out in the cold with Apple when it comes to porting their apps on Apple devices.\nDevelop iOS apps with Java iOS app development using Java is easier than you think. Everything we have discussed so far is not to say that you cannot develop iOS apps in Java.\nThe only way to develop iOS apps in Java is to have a compiler that will compile your Java code down to native iOS binary.\nWith Codename One, Java developers can build apps that run on iOS devices such as the iPhone and iPad. Not only that, your app will work beyond iOS devices i.e Android, Windows and JavaScript.\nWant to utilize your existing Java/Kotlin skills to develops iOS apps? You can do that with Codename One!\nIf you’re not using Codename One yet, then sign up now:\nSign Up - It\u0026rsquo;s Free!\nHow Does It Work? Underlying technology that enables Codename One to develop iOS apps with Java. Native iOS development requires a Mac with Xcode. To make matters worse, Apple makes changes to their tools on a regular basis.\nCodename One has a built-in simulator when running and debugging an app. For native iOS builds, Codename One build cloud uses Macs running Xcode (the native Apple tool) to build the app.\nThis removes the need to install/update complex toolchains and simplify the process of building a native iOS app.\nCodename One - iOS Architecture\nThe process works seamlessly and makes Codename One apps native as they are literally compiled by the native platform.\nJava bytecode is dynamically translated to a native iOS Xcode project and seamlessly compiled to a native binary. This binary can be installed on iOS devices or uploaded to App Store.\n• With Codename One, you don\u0026rsquo;t need to have a Mac to develop iOS apps.\n• Codename One also provides an option to build offline.\n• To understand how Codename One works, check our developer guide.\nPrerequisites What you need to get started. To run and build the project, you should be running a modern version of Mac OS, Windows, or Linux with JDK 11 installed.\nYou don’t need to install anything other than the Codename One plugin. You can work with Mac, Windows or Linux and everything should \u0026ldquo;just work\u0026rdquo;.\nLet’s dig in.\nGetting Started Tutorial to walk you through the steps of building a Hello World app. Codename One initializer\nOpen in IDE\nDevelop \u0026amp; Debug App\nCreate iOS Build\nStep 1: Generate a new project with Codename One initializr The easiest and quickest way to create a new project is to use the Codename One initializr.\nThis online tool will allow you to choose from a growing selection of project templates in Java or Kotlin, and download a starter project that you can open in your preferred IDE or build directly on the command-line using Maven.\nCodename One initializr\nImportant: The package name you select for your app can’t be changed once the app is submitted to a store!\n• Go to Codename One initializr, select the Java Bare-bones Project from the Template select box.\n• Enter a Package and Main Class for your app. The Package will be used both for your App ID, when you submit your app to the App Store, and for your Maven project’s groupID. The Main Class is the name of the main Java class for your app.\n• Press Download and save the project as a .zip file.\n• After the download completes, extract the zip file.\nResources: • Getting Started with the Bare-bones Java App Template.\n• Online Tool to Generate iOS Starter Project\n• Codename One Maven Developer Guide.\nStep 2: Open the project in your preferred IDE You can run the project directly from the command-line or you can open it in your preferred IDE (e.g. IntelliJ or NetBeans).\nFor this tutorial, I’m going to use IntelliJ.\nAs this is a Maven project, IntelliJ can open this project and work with it natively without requiring any special plugins.\n• Open the extracted project in IntelliJ (or your preferred IDE).\n• Press the green icon to run the app in the simulator.\n• Wait while Maven downloads the build dependencies. It will open the Codename One simulator with the simple Hello World app.\nStep 3: Develop \u0026amp; Debug your app If you run this project in the Codename One Simulator without making any modifications to the app, it will look something like this:\nThe simulator makes it easy to develop and debug your app without having to build and deploy to a real device.\nIt includes a number of useful features aimed at streamlining the development process.\nGenerally, you would work exclusively in the simulator until you have a near finished product that you want to share with your beta-testers.\nResources: • For more information about the Codename One simulator, see this page.\n• More information about the project structure, project files, editing Java code and CSS stylesheet can be found in this detailed guide.\nStep 4: Build the project for iOS Finally, we can build a native app for iOS by running the Xcode iOS project target.\nWhen building for iOS, you can either build locally or via build server.\nTip: We recommend using the build server as it doesn’t require installing any special development tools on the computer beyond the standard JDK.\nBuild Server With Codename One build server, iOS apps can be built on Windows, Linux, or Mac with no special requirements beyond Maven and the JDK. All you need is a free Codename One account.\nFor iOS builds, there are two build targets that use the build server:\n• iOS Debug Build (for testing and debugging)\n• iOS Release Build (to submit to the iOS App store)\nNote: Before you can submit an iOS build to the build server, you need to go through a few of Apple’s requirements. See iOS Prerequisites for more information about these steps.\n• Click on the configuration menu in the upper right toolbar, and select Build Server \u0026gt; iOS Debug Build/iOS Release Build as shown below:\nBuilding for iOS via Build Server\n• Press the button to build the project.\n• After you submit the build, you can track and install them via Build Server, Control Center or the Android Build app.\nResources: • Build Server.\n• Control Center.\n• Android Build App.\nLocal iOS builds The Local iOS build target generates an Xcode iOS project that you can open and build directly in Xcode.\nNote: This target necessarily requires a Mac with Xcode installed. See Building for iOSfor more information.\n• Click on the Configuration menu in the upper right toolbar, and select Local Builds \u0026gt; Xcode iOS Project as shown below:\nBuilding locally for iOS\n• Press the button to build the project.\n• If all goes well, the project will be found in the ios/target directory.\n• You can proceed to open the Xcode project (.xcworkspace file) in Xcode, and build the project.\nTip: To build a native app, Codename One supports a variety of different target platforms:\nㅤAndroid\nㅤ iOS\nㅤ Windows\nㅤ Mac\nㅤJavaScript\nㅤJavaSE\nTLDR (Too Long Didn\u0026rsquo;t Read) All of the above is shown in this tutorial by Steve Hannah In this quick video, Steve Hannah uses the bare-bones Java project generated by Codename One initializr, which he’s running in IntelliJ, to build for iOS.\nHe also gives a brief tour of the project structure and build targets.\nResources There are several online sources for iOS app development tutorials using Java or Kotlin with Codename One.\nHere are some useful links:\n• Codename One Docs: The first steps, guides, tutorials and resources you need.\n• Compare Codename One: Codename One’s comparison with other cross-platform frameworks.\n• Codename One Maven Developer Guide\n• Getting Started with the Bare-bones Java App Template\n• Building a Codename One project for iOS (Video)\n• Build Cross-Platform Native Mobile Apps Using Java/Kotlin for iOS, Android, Desktop and Web\nThe Community Codename One is backed by a vibrant community of more than 100k developers in over 200 countries.\nCodename One 1.0 was released in 2012 by ex-Sun engineers. It was the first solution to build native iOS apps in Java and it’s still the most mature, performant and stable cross-platform mobile toolkit for Java/Kotlin developers.\nCodename One Community:\nㅤGitHub\nㅤ StackOverflow\nㅤ Reddit\nQuick Start with Codename One initializr​ Build your first iOS app with Java/Kotlin now.​ Get Started\nFrequently Asked Questions (FAQs) Can I run Java on iOS?\nJava code can\u0026rsquo;t run on iPhone and iPad since there is no Java Virtual Machine (JVM) for iOS. However, Codename One can compile Java code to native iOS binary.\nCan I develop iOS apps without Swift?\nYes, you can develop iOS apps without Swift using a compiler that can compile your code down to native iOS binary.\nCan I develop iOS apps with Java?\nYes, if you are a Java developer, you don’t need to learn Swift or Objective-C to develop iOS apps. You can use Codename One to develop iOS apps using Java or Kotlin.\nIs Java good for iOS development?\nJava is a good choice for iOS app development if you:\n• Don’t know or want to learn Swift or Objective-C\n• Want to build a cross-platform app\n• Want easy deployment \u0026amp; maintenance\n• Want to save costs \u0026amp; resources\nCan I develop iOS apps without Xcode?\nYes, you can build iOS apps without Xcode using Codename One, an open-source cross-platform framework for building native apps with Java/Kotlin.\nDo I need a Mac to develop iOS apps?\nNo, with Codename One, you can develop and distribute iOS apps without a Mac, macOS or Xcode.\nCan I build iOS apps on Windows?\nYes, you can build iOS apps on Windows using Codename One without using a Mac, macOS or Xcode.\nIs it legal to develop iOS apps on Windows?\nYes, it\u0026rsquo;s legal to develop iOS apps on non-Apple hardware or software as it does not violate the Apple Developer Agreement.\nHow to build iOS apps with Java?\nYou can build native iOS apps with Java using Codename One. Just sign up for a free Codename One account, go to Codename One initializr, and generate a starter project that you can open, run, debug, and build in your preferred IDE.\nHow to build iOS apps with Kotlin?\nYou can build native iOS apps with Kotlin using Codename One. Just sign up for a free Codename One account, go to Codename One initializr, and generate a starter project that you can open, run, debug, and build in your preferred IDE.\nFinal Thoughts Building iOS apps with Swift is the obvious route if you want to develop specifically for iOS only.\nBut if you are a Java developer and don’t know Swift, Codename One is your best bet to develop iOS apps using Java or Kotlin.\nGetting started with Codename One is easy. Just sign up for a free Codename One account, go to Codename One initializr, and generate a starter project that you can open, run, debug, and build in your preferred IDE.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/how-to-build-ios-apps-with-java/","summary":"\u003cp\u003e\u003cimg alt=\"How to Build iOS Apps with Java\" loading=\"lazy\" src=\"/blog/how-to-build-ios-apps-with-java/Build-iOS-apps-with-Java-1024x536.png\"\u003e\u003c/p\u003e\n\u003cp\u003eLearn how to build and publish iOS apps with Java or Kotlin without a Mac or Xcode in this comprehensive guide.\u003c/p\u003e\n\u003cp\u003eIn this guide, we will get to know everything about iOS app development with Java.\u003c/p\u003e\n\u003cp\u003eWe will discuss the development process, technology involved, prerequisites and general FAQs for building apps for iPhone/iPad using Java.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e\u003cstrong\u003eHere are the major topics we’ve covered in this Java iOS app development guide.\u003c/strong\u003e\u003c/strong\u003e\u003c/p\u003e","title":"How to Build iOS Apps with Java"},{"content":"We have added support for IntelliJ’s asynchronous code debugging feature, so that you can more easily debug your asynchronous code.\nWhen debugging your apps in IntelliJ, stack-traces will include the \u0026ldquo;async\u0026rdquo; context’s stack frames so that you can see the stack trace of the code that scheduled your asynchronous code. For example, methods like callSerially() are notoriously prickly to debug because the \u0026ldquo;logical\u0026rdquo; stack trace includes the stack frame in which callSerially(Runnable) is called, and also the frame in which the Runnable‘s run() method is called. It is very difficult to walk up this \u0026ldquo;logical\u0026rdquo; stack from a break-point inside the run() method.\nTo demonstrate this point, consider the following code:\npackage com.codenameone.devmode; import com.codename1.ui.Button; import com.codename1.ui.Form; import com.codename1.ui.events.ActionEvent; import com.codename1.ui.layouts.BorderLayout; import static com.codename1.ui.CN.callSerially; public class TestAsyncDebugForm extends Form { public TestAsyncDebugForm() { super(new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE)); Button btn = new Button(\u0026#34;Hello 1\u0026#34;); btn.addActionListener(this::button1Clicked); Button btn2 = new Button(\u0026#34;Hello 2\u0026#34;); btn2.addActionListener(this::button2Clicked); add(BorderLayout.CENTER, btn); add(BorderLayout.SOUTH, btn2); } private void button1Clicked(ActionEvent evt) { callSerially(printHello); } private void button2Clicked(ActionEvent evt) { callSerially(printHello); } Runnable printHello = () -\u0026gt; { printHello(); }; private void printHello() { System.out.println(\u0026#34;Hello\u0026#34;); } } This creates a form with two buttons: \u0026ldquo;Hello 1\u0026rdquo; and \u0026ldquo;Hello 2\u0026rdquo;. Clicking on either button will ultimately trigger an async call to the printHello() method, but they follow different code paths to get there. Clicking \u0026ldquo;Hello 1\u0026rdquo; triggers the button1Clicked() method, and clicking \u0026ldquo;Hello 2\u0026rdquo; triggers the button2Clicked() method – both triggering an async call to printHello().\nLet’s set a break point inside the printHello() method:\nIf we debug the app and press \u0026ldquo;Hello 1\u0026rdquo;, we will see a stack trace like the following:\nThere is no way to tell from this stack trace which button was pressed to trigger it. If we walk up the stack we hit a dead end at executeSerialCall(). This is because the break-point occurs in the asynchronous callback of callSerially(), so the original stack frame for the call to callSerially() is already \u0026ldquo;gone\u0026rdquo; by the time we hit our break-point.\nNow, let’s try this again with async debugging enabled. The stack trace this time will look like:\nWe can now trace this break-point back to \u0026ldquo;Button 1\u0026rdquo; definitively because it displays both the \u0026ldquo;execution\u0026rdquo; stack frame’s trace, and the scheduler’s stack frame’s trace.\nEnabling Async Debugging Async debugging requires:\nThat you are using IntelliJ IDEA\nThat your project is using Maven\nThat your cn1.version property is set to 7.0.65 or higher.\nThat your project is configured to use the com.codename1.annotations.Async annotations for the async stack traces feature. All projects created using the Codename One initializr after April 18th will include this configuration \u0026ldquo;out of the box\u0026rdquo;, so it should \u0026ldquo;just work\u0026rdquo;.\nConfiguring the Async Annotations As mentioned above, new projects created with Codename One initializr after April 18th, should include async stack traces out of the box. If you have an existing project on which you want to enable async traces, you just need to tell IntelliJ to use the Codename One annotations for async stack traces. The easiest way is to simply copy the debugger.xml file from the cn1app-archetype into the .idea directory of your project.\nPlace the following into the .idea/debugger.xml file of your project to enable async stack-traces. xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34;? Alternatively you can follow the IntelliJ documentation for configuring custom annotations here. You should add com.codename1.annotations.Async.Schedule to the list of Async Schedule annotations, and com.codename1.annotations.Async.Execute to the list of Async Execute annotations. The configuration dialog is shown below.\nFigure 1. The Async Annotations configuration dialog in IntelliJ.\nFor More Information For more information about IntelliJ’s asynchronous debugging feature, see the IntelliJ documentation on the subject. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nAntonio Rios — April 14, 2022 at 3:20 am (permalink) Antonio Rios says:\nWonderful new features! Great job guys! I’m literally impress every time I visit the blog and see some new cool feature added. Keep those cool useful features coming please.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/async-debugging-with-intellij-idea/","summary":"\u003cp\u003eWe have added support for IntelliJ’s asynchronous code debugging feature, so that you can more easily debug your asynchronous code.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Async Debugging with IntelliJ IDEA - Codename One\" loading=\"lazy\" src=\"/blog/async-debugging-with-intellij-idea/Async-Debugging-with-IntelliJ-IDEA-Codename-One-1024x536.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen debugging your apps in IntelliJ, stack-traces will include the \u0026ldquo;async\u0026rdquo; context’s stack frames so that you can see the stack trace of the code that scheduled your asynchronous code. For example, methods like \u003ccode\u003ecallSerially()\u003c/code\u003e are notoriously prickly to debug because the \u0026ldquo;logical\u0026rdquo; stack trace includes the stack frame in which \u003ccode\u003ecallSerially(Runnable)\u003c/code\u003e is called, and also the frame in which the \u003cstrong\u003eRunnable\u003c/strong\u003e‘s \u003ccode\u003erun()\u003c/code\u003e method is called. It is very difficult to walk up this \u0026ldquo;logical\u0026rdquo; stack from a break-point inside the \u003ccode\u003erun()\u003c/code\u003e method.\u003c/p\u003e","title":"Async Debugging with IntelliJ IDEA"},{"content":"We have added a new property sheet and a JavaDocs button to the toolbar of the Properties panel.\nTo continue the theme of improving the development experience in the simulator, you will find a few new features landing on Friday.\nFirstly, we have added a new property sheet that shows you the value of all of the properties of the selected component in the component tree. This is useful for checking whether a container is scrollable, or what text property of a button is set to, or pretty much anything else you’d like to know about a component’s state.\nFigure 1. The new property sheet is visible in the right panel of this screenshot.\nThe above screenshot shows the property sheet in the right panel, displaying properties of the selected label.\nCurrently the values are read-only. Editing support will be added soon.\nFiltering Properties The property sheet includes all properties that have a public accessor. For some classes, there can be an awful lot of properties, which can be unwieldy to sift through, so we have included the ability to filter them, with a query.\nIn the above screenshot, I am filtering the properties so that only the ones containing the word \u0026ldquo;Width\u0026rdquo; are shown.\nJavaDocs We’ve also added a JavaDocs button to the toolbar of the Properties panel that will open the JavaDocs for the class of the currently selected component.\nCurrently this only works for Maven projects, as it uses the -javadoc.jar files that accompany Maven packages.\nTIP Depending on your IDE settings, you may need to explicitly download the JavaDocs for your project dependencies in order for this feature to work properly. In IntelliJ, you can do this by right-clicking on the pom.xml file, and selecting Maven \u0026gt; Download Documentation\nIf JavaDocs are not available for the specific class of the selected component, it will traverse the superclass hierarchy until it finds a class that does have JavaDocs available.\nForce \u0026ldquo;Revalidate\u0026rdquo; We have also added a smaller niche feature that you may never need, but can come in handy: Revalidate\nIf you’re debugging layout issues, you may not be sure if, perhaps the container just needed to be revalidated, or re-laid-out.\nNow, you can trigger a revalidation directly in the simulator by right-clicking the container’s node in the component tree, and selecting Revalidate from the context menu.\nMore To Come We’re not done yet. You’ll see more improvements trickling in over the next couple of weeks. If you have any pet requests, you can post them in the comments, or in the issue tracker. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nAntonio Rios — April 9, 2022 at 7:32 pm (permalink) Antonio Rios says:\nExcellent work guys! This new feature will definitely help me troubleshoot a problem I’m having with the SpanLabel not taking the width I’m setting. For some reason it seems that I can’t resize the width through the css styling nor the setPreferredW() method on the spanlabel I made. I’m having a lot of fun learning the API, reading the developer guide, and learning from the kitchen sink example and the other samples. Every day I impressed by all the cool features. Thanks for all your hard work!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-property-sheet-and-javadocs/","summary":"\u003cp\u003eWe have added a new property sheet and a JavaDocs button to the toolbar of the Properties panel.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Property Sheet and JavaDocs - Codename One\" loading=\"lazy\" src=\"/blog/new-property-sheet-and-javadocs/Property-Sheet-and-JavaDocs-Codename-One-1024x536.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eTo continue the theme of improving the development experience in the simulator, you will find a few new features landing on Friday.\u003c/p\u003e\n\u003cp\u003eFirstly, we have added a new property sheet that shows you the value of all of the properties of the selected component in the component tree. This is useful for checking whether a container is scrollable, or what text property of a button is set to, or pretty much anything else you’d like to know about a component’s state.\u003c/p\u003e","title":"New Property Sheet and JavaDocs"},{"content":"Learn how to convert the old Codename One \u0026ldquo;ANT\u0026rdquo; project structure demos to Maven projects using the Maven Migration Tool.\nSince migrating to Maven, the recommended way to create a new Codename One project is using the Codename One initializr tool. It will generate a fresh, new Maven project for you based on a template of your choosing. In order to not overwhelm you, we have thus far kept the template selections in this tool to a minimum. At the time of this writing you can choose one of:\nBare-bones template: This will set you up with a simple \u0026ldquo;hello world\u0026rdquo; app, that you can customize as required. This is available in both Java and Kotlin flavours.\nGRUB: A complete sample restaurant delivery app. (Java only)\nCodeRAD MVC Starter Project: A template based on the CodeRAD MVC library.\nTweet App: A template for a Twitter-style app. Also uses the CodeRAD MVC library.\nThere are many other demos and templates that have been developed over the years that are not listed here. For example, there are several projects listed in the Codename One demos section of the website.\nFigure 1. Demos listed in the Codename One demos section.\nMany other demos can be found amongst our GitHub repositories, and there are a smattering of older demos in the codenameone-demos repository as well.\nMost of these use the old \u0026ldquo;ANT\u0026rdquo; project structure, so they require some surgery to convert them to the modern Maven structure. In this article I will describe how to convert these demos to Maven projects using the Maven Migration Tool.\nStep 1: Install the Codename One Maven Migration Tool The Maven migration tool is a GUI application that converts Codename One ANT-based projects into Maven projects.\nDownload it for Mac, Windows, and Linux here.\nStep 2: Download the Demo Project Once you have installed the migration tool, you should download the demo project that you wish to use as the basis for your app. As an example, I’ll use the MSUIKit demo.\nFigure 2. The MSUIKit demo\nYou can download this demo by clicking the Source link, then click the \u0026ldquo;Code\u0026rdquo; menu in the upper right, and select \u0026ldquo;Download ZIP\u0026rdquo;.\nAfter you have downloaded the ZIP, extract it, so that you have the project in a folder on your local machine.\nStep 3: Convert the Project in Maven Migration Tool Open up the Maven migration tool application that you installed in Step 1.\nFigure 3. The Maven migration tool window\nYou can select the project you want to convert by pressing the \u0026ldquo;Browse…​\u0026rdquo; button next to the \u0026ldquo;Source Project Path\u0026rdquo; field. Then select the \u0026ldquo;MaterialScreensUIKit\u0026rdquo; directory in the file dialog.\nAfter you have selected this project, the migration tool form should be updated to reveal fields to edit the \u0026ldquo;Main Class Name\u0026rdquo;, and \u0026ldquo;Package Name\u0026rdquo;. They will be pre-populated with the original values from the project you are migrating, but you can change these values as appropriate for your application.\nFigure 4. The \u0026ldquo;App Details\u0026rdquo; section allows you to enter a package name and Main class name for your application.\nBefore moving on, you should check that the \u0026ldquo;Destination Directory\u0026rdquo; field is set to the location where you want your new project to be saved.\nIf all of your settings look good, press the \u0026ldquo;Create Project\u0026rdquo; button. After about ten seconds, you should see a message indicating that your project was created successfully.\nWhen you click the \u0026ldquo;OK\u0026rdquo; button, it should open Finder (Mac) or Explorer (Windows) to the directory where the project was saved. You can now proceed to open this project in your preferred IDE. Personally I recommend IntelliJ, but NetBeans, Eclipse, and VSCode should all work fine also. For this article, I will use IntelliJ.\nStep 4: Open the Project in your IDE Depending on your operating system, the steps to open the project in IntelliJ may vary. For example, on Mac, you can just drag the folder itself onto the IntelliJ icon in your Dock (assuming you have the IntelliJ icon in your Dock). Alternatively, you can open a command prompt and do:\ncd /path/to/theproject idea Alternatively, you can just open IntelliJ, and then use the \u0026ldquo;File\u0026rdquo; \u0026gt; \u0026ldquo;Open\u0026rdquo; menu to open the project directory.\nAfter the project opens, you should expand the \u0026ldquo;Maven\u0026rdquo; tab on the right side of the window to see all of the build targets available to you.\nFigure 5. The \u0026ldquo;Maven\u0026rdquo; side bar includes build targets available.\nYou should also see these build targets listed in the \u0026ldquo;Run\u0026rdquo; menu on the toolbar. \u0026ldquo;Run in Simulator\u0026rdquo; will be selected by default. If you press the \u0026ldquo;Run\u0026rdquo; button on the toolbar, it should launch the project in the simulator as shown below:\nReferences For more information about Codename One’s Maven support, see the Codename One Maven developers guide.\nYou might also check out the Bare-bones project getting started tutorial for an introduction to working with Maven projects. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nBryan Buchanan — June 10, 2022 at 7:48 am (permalink) Bryan Buchanan says:\nExcellent tool. Works really well.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/creating-new-projects-with-old-templates/","summary":"\u003cp\u003eLearn how to convert the old Codename One \u0026ldquo;ANT\u0026rdquo; project structure demos to Maven projects using the Maven Migration Tool.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Creating New Projects with Old Templates - Codename One\" loading=\"lazy\" src=\"/blog/creating-new-projects-with-old-templates/Creating-New-Projects-with-Old-Templates-Codename-One-1024x536.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSince migrating to Maven, the recommended way to create a new Codename One project is using the \u003ca href=\"https://start.codenameone.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCodename One initializr\u003c/a\u003e tool. It will generate a fresh, new Maven project for you based on a template of your choosing. In order to \u003cstrong\u003enot\u003c/strong\u003e overwhelm you, we have thus far kept the template selections in this tool to a minimum. At the time of this writing you can choose one of:\u003c/p\u003e","title":"Creating New Projects with Old Templates"},{"content":"We’ve added support for \u0026ldquo;Inspect Component\u0026rdquo;, which is similar to the \u0026ldquo;Inspect Element\u0026rdquo; feature available in Chrome.\nContinuing in the direction of improving the development experience inside the Codename One simulator, we have made another batch of small improvements this week. Notably, we’ve added support for \u0026ldquo;Inspect Component\u0026rdquo;, which is similar to the \u0026ldquo;Inspect Element\u0026rdquo; feature available in Chrome. Now, if you right-click on a component in the simulator, it will provide you with a context menu.\nFigure 1. The \u0026ldquo;Inspect Component\u0026rdquo; option in the context menu.\nIf you select the \u0026ldquo;Inspect Component\u0026rdquo; option in this menu, it will select the selected component in the \u0026ldquo;Components\u0026rdquo; panel, and in the \u0026ldquo;Component details\u0026rdquo;.\nThe \u0026ldquo;Component Inspector\u0026rdquo; has been available as part of the simulator for a long time, but selecting a particular component used to require you to expand the component tree nodes manually until you found the component you were looking for.\nThe simulator would help you a little bit by placing a translucent red highlight over the currently selected node’s corresponding component, but it could still be a little bit tedious to have to manually walk through the tree to find the component you wanted.\nFigure 2. After choosing \u0026ldquo;Inspect Component\u0026rdquo;, the \u0026ldquo;Components\u0026rdquo; panel auto-expands and selects the corresponding node, and the \u0026ldquo;Component details\u0026rdquo; panel is populated with the selected component details.\nYou’ll notice also, that the \u0026ldquo;Component Details\u0026rdquo; will automatically populate with the details of your selected component. Most for the fields in the component details form are read only, but the UIID field can be edited, allowing you to experiment with different styles for your elements directly in the simulator.\nDisabling the Context Menu If your application needs to handle \u0026ldquo;Right Mouse-click\u0026rdquo; events, then the context menu may interfere with your app. In such cases you can disable the context menu by toggling the button found on the toolbar of the Components panel. Once toggled off, the button icon will change to .\nFigure 3. The \u0026ldquo;Components\u0026rdquo; panel toolbar, which includes a toggle button to enable/disable the context menu. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nplumberg — March 29, 2022 at 5:28 pm (permalink) plumberg says:\nTested it out for a bit yesterday. Looks great and very convenient!\nThomasH99 — April 5, 2022 at 11:21 am (permalink) ThomasH99 says:\nIt is really great with these improvements! While you’re at it, Steve, improving the testing (test automation) would also make a huge difference. The old support is promising but misses some small things to be really useful. Let me know if this migth make it to your todo list and I’d be happy to provide input and feedback 🙂\nSteve Hannah — April 5, 2022 at 11:15 pm (permalink) Steve Hannah says:\nWe are making a push right now to improve the development experience in the simulator. No promises, filing an RFE in the issue tracker is where to start the ball rolling.\nThomasH99 — April 10, 2022 at 12:30 pm (permalink) ThomasH99 says:\nGreat, I hope for the best :-). The TestRecorder has a lot of potential and would make the Simulator UI even more powerful and impressive. I’ve filed an RFE here: https://github.com/codenameone/CodenameOne/issues/3575\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/inspect-component/","summary":"\u003cp\u003eWe’ve added support for \u0026ldquo;Inspect Component\u0026rdquo;, which is similar to the \u0026ldquo;Inspect Element\u0026rdquo; feature available in Chrome.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Inspect Component - Codename One\" loading=\"lazy\" src=\"/blog/inspect-component/Inspect-Component-Codename-One-1024x536.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eContinuing in the direction of improving the development experience inside the Codename One simulator, we have made another batch of small improvements this week. Notably, we’ve added support for \u0026ldquo;Inspect Component\u0026rdquo;, which is similar to the \u0026ldquo;Inspect Element\u0026rdquo; feature available in Chrome. Now, if you right-click on a component in the simulator, it will provide you with a context menu.\u003c/p\u003e","title":"New Feature: Inspect Component"},{"content":"With the latest Maven update (7.0.61), you will notice a few changes to the Codename One simulator that should improve your development experience.\nWe have consolidated the user interface inside a single window so that the component inspector, network monitor, and other tools feel more integrated.\nThe window has four regions (Left, Center, Right, and Bottom), and you are free to place any of the UI panels into any of these regions. The default configuration places the simulator in the center, the component tree on the left, and the component details and network monitor in the bottom, but you can change this using the \u0026quot;Move To\u0026quot; menu, and it will remember your preferences the next time you run the simulator.\nFigure 1. The default simulator window configuration, with component tree on the left, the simulator in the center, and the component details on the bottom.\nFor example, if you wanted the component tree to appear in the \u0026ldquo;right\u0026rdquo; region, you could click on the panel menu in the upper right of the Components panel.\nAnd the resulting configuration would look like the following:\nIf you prefer to break out a panel into a separate window, you can do that also. When you close the window, it will automatically be returned to its original region inside the main simulator window.\nFor example, if we wanted to move the simulator itself to a separate window, we could select the panel menu in the uper right of the Simulator panel, and select \u0026quot;Move To\u0026quot; \u0026gt; \u0026quot;New Window\u0026quot;\nThe result would be the simulator in its own window as shown below:\nYour configuration will be remembered for your next run, so you wan’t have to repeat yourself.\nMenu Changes As part of this change, we have moved some of the items from the Simulator menu onto a new toolbar in the Simulator panel. For example instead of a \u0026quot;Simulator\u0026quot; \u0026gt; \u0026quot;Rotate\u0026quot; menu item, there are toggle buttons on the toolbar for \u0026quot;Portrait\u0026quot; and \u0026quot;Landscape\u0026quot;. And instead of \u0026quot;Simulator\u0026quot; \u0026gt; \u0026quot;Zoom\u0026quot;, there are Zoom In and Zoom Out buttons on the toolbar.\nMore to come…​ Over the next few updates we will be doing some more reorganization of menu items and panels to make the experience more cohesive. We will also be adding a few new features to enhance the dev experience. Stay tuned…​ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nDiamond Mubaarak — March 22, 2022 at 6:22 am (permalink) Diamond Mubaarak says:\nConsolidating the simulating tools is excellent. I know this is a work in progress but some functionalities are off or could be improved.\n– Network monitor has no records.\n– Components are not selectable on UI with MapContainer. The tree could be expanded, though. Only the root form is selectable.\n– Selection of a component in the Components pane should switch to the Component Details tab automatically.\n– Rotating a device should automatically increase and decrease in size the Simulator pane to show the whole device.\n– \u0026ldquo;Always on Top\u0026rdquo; functionality should apply to secondary windows like \u0026ldquo;Push Simulation\u0026rdquo; or when I set the Simulator pane to show as a new window, as these windows are hidden behind the main window until it’s unchecked.\n– The \u0026ldquo;Move To\u0026rdquo; overflow menu appears behind the Simulator until you hover on it.\n– Zooming in or out is great, however, zoom in should come with the ability to pan the screen.\nI’m running the new Simulator on a Linux OS.\nSteve Hannah — March 22, 2022 at 6:59 pm (permalink) Steve Hannah says:\nThanks for the feedback. I have moved this into an issue and am working through the points one by one. You can follow the progress at https://github.com/codenameone/CodenameOne/issues/3566\nSteve Hannah — March 28, 2022 at 1:46 pm (permalink) Steve Hannah says:\nAll of these issues are resolved in the latest version (7.0.62). You can follow the specific changes in the issue tracker issue that I opened for this at https://github.com/codenameone/CodenameOne/issues/3566\nplumberg — March 28, 2022 at 8:23 pm (permalink) plumberg says:\nHi,\nI tried opening Network Monitor after last update (just updated cn1 few min ago), but Network monitor window is not opening. Nothing is happening\nI’ll appreciate your help!\nplumberg — March 28, 2022 at 8:27 pm (permalink) plumberg says:\nNevermind, I just found it in the same window on the bottom.\nSteve Hannah — March 28, 2022 at 11:06 pm (permalink) Steve Hannah says:\nThanks for sharing that you had trouble find it. I’ll see what I can do to make this more intuitive.\nAbdelaziz Makhlouf — March 25, 2022 at 1:00 pm (permalink) Abdelaziz Makhlouf says:\nHello,\nDue to this update, all components are very small now : https://prnt.sc/YEkeZp_XWEdP\nHow to fix this please or how to get back to the older version ? We can’t even read the text.\nSteve Hannah — March 25, 2022 at 2:16 pm (permalink) Steve Hannah says:\nThe changes to the simulator shouldn’t have any effect on component sizes in your app. One way to confirm this is to revert the version to 7.0.58. If you change the cn1.version property to 7.0.58 in your project’s pom.xml file, does that \u0026ldquo;fix\u0026rdquo; the issue?\nFawaz Qamhawi — March 26, 2022 at 8:39 pm (permalink) Fawaz Qamhawi says:\nThis is happening with me.\nIf I will need to save the css file again after each run, it will compile again. That will fix the problem.\nBy the way, I lost all my skins and there is no way to upload other skins as it used to be before this update.\nSteve Hannah — March 27, 2022 at 12:37 pm (permalink) Steve Hannah says:\nBy the way, I lost all my skins and there is no way to upload other skins as it used to be before this update.\nYou can still add skins in exactly the same way that you added skins before. \u0026ldquo;Skins\u0026rdquo; \u0026gt; \u0026ldquo;More\u0026rdquo;. or \u0026ldquo;Skins\u0026rdquo; \u0026gt; \u0026ldquo;Add New\u0026rdquo;. This functionality is unchanged.\nIf I will need to save the css file again after each run, it will compile again. That will fix the problem.\nI’m not sure I understand the issue? Are you saying that your problem with styles is fixed after you recompile the CSS file?\nSteve Hannah — March 28, 2022 at 1:44 pm (permalink) Steve Hannah says:\nI have opened an issue in the issue tracker at https://github.com/codenameone/CodenameOne/issues/3572\nIf you experience this issue, please update that issue with details to help reproduce it.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-simulator-facelift/","summary":"\u003cp\u003eWith the latest Maven update (7.0.61), you will notice a few changes to the Codename One simulator that should improve your development experience.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Simulator Facelift - Codename One\" loading=\"lazy\" src=\"/blog/codename-one-simulator-facelift/Simulator-Facelift-Codename-One-1024x536.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe have consolidated the user interface inside a single window so that the component inspector, network monitor, and other tools feel more integrated.\u003c/p\u003e\n\u003cp\u003eThe window has four regions (Left, Center, Right, and Bottom), and you are free to place any of the UI panels into any of these regions. The default configuration places the simulator in the center, the component tree on the left, and the component details and network monitor in the bottom, but you can change this using the \u003ccode\u003e\u0026quot;Move To\u0026quot;\u003c/code\u003e menu, and it will remember your preferences the next time you run the simulator.\u003c/p\u003e","title":"Codename One Simulator Facelift"},{"content":"Our next update to the Codename One application archetype (7.0.59) includes some VSCode-specific config files to help improve integration for Maven Projects.\nSwitching to Maven has been a good thing over all. Maven’s dependency management allows projects to work more consistently out of the box. No more missing dependencies, for the most part. Just clone the repo, build the project and go.\nMaven’s dependency management and standard project structure results in one standard project structure that should work in any IDE that supports Maven. Unfortunately, each IDE still requires a little bit of fine-tuning to wire up our Maven goals to the IDEs’ menus.\nFor the initial transition, we focused most of our attention on the experience in IntelliJ and NetBeans. IntelliJ, because it is the most widely used, and NetBeans, because it provides (arguably) the best Maven integration, and therefore, didn’t require us to do very much.\nWe did our best with Eclipse, but will need to take a second pass at it, as it uses a very different model for its launch actions than NetBeans and IntelliJ.\nWe left VSCode users on their own to do the link-ups, for the most part, because they’re such a clever bunch, and we knew they’d be able to figure it out 🙂\nNow that the dust has settled on the migration, we’re circling back to try to tighten it up. Our next update to the Codename One application archetype (7.0.59) includes some VSCode-specific config files to help improve integration.\nOpening Projects in VSCode I’ll demonstrate this integration by creating a new Codename One Application project in Codename One initializr.\nPoint your browser to https://start.codenameone.com\nIn the left panel, select the \u0026ldquo;Bare-bones Java App\u0026rdquo; template, enter a package and Main Class, and select \u0026ldquo;VSCode\u0026rdquo; in the IDE drop-down. Then press the Download button.\nIt will prompt you to save the project, which will then download as a zip file. Extract the zip file, then open the resulting project folder in VSCode.\nThe project window should look like the following screenshot:\nNOTE You may be prompted to install the Java Extension Pack in one of the notices in the lower-right corner. If so, you should follow these prompts to install that extension.\nRunning the Project Unfortunately VSCode \u0026ldquo;Run\u0026rdquo; button doesn’t work to run the project in the simulator. We’re working on that. To run the project in the Codename One simulator, you’ll need to use the \u0026ldquo;Run in Simulator\u0026rdquo; command which is available in the Maven favorites menu.\nIn the left \u0026ldquo;Explorer\u0026rdquo; panel, you should see a \u0026ldquo;Maven\u0026rdquo; option at the bottom. Expand this to show all of the modules in the application. The first module listed is the \u0026ldquo;root\u0026rdquo; module, and is also the module on which all of the core actions are registered.\nRight click on this module, then select \u0026ldquo;Favorites…​\u0026rdquo; in the context menu as shown below:\nThis will reveal a menu with all of the important actions you’ll need to perform on your project.\nIMPORTANT If this is your first time running the project, you should select \u0026ldquo;Tools \u0026gt; Update Codename One\u0026rdquo; to force the project to download all of the dependencies. If you don’t do this, it is possible you’ll get an error when you try to run the app, due to missing dependencies.\nSelect the \u0026ldquo;Run in Simulator\u0026rdquo; option to build and launch your app in the Codename One simulator.\nStill Work To Do Currently, debugging is still a bit of a challenge in VSCode. We are working on improving that process, and should have that sorted out soon. If you use VSCode, please let us know what you think, on one of our channels: Reddit, StackOverflow, the mailing list, or in the comment section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nBryan Buchanan — June 7, 2022 at 11:22 am (permalink) Bryan Buchanan says:\nTrying this out. Followed all the steps, and get to\nIf this is your first time running the project, you should select \u0026ldquo;Tools \u0026gt; Update Codename One\u0026rdquo; to force the project to download all of the dependencies\nUnder Tools there is no Update option ?\nBryan Buchanan — June 9, 2022 at 12:50 am (permalink) Bryan Buchanan says:\nOops – was looking at the wrong Tools location. All good now !\nBryan Buchanan — June 10, 2022 at 7:53 am (permalink) Bryan Buchanan says:\nHaving played around with quite a few projects (after using the Maven conversion tool) I have to say the VSCode integration is excellent. Well done.\nN P — August 22, 2023 at 8:23 pm (permalink) N P says:\nVScode is telling me \u0026ldquo;found no favorite commands\u0026rdquo; when I click on favorites\nShai Almog — August 23, 2023 at 2:00 am (permalink) Shai Almog says:\nDid you download the VSCode version of the project from start or did you get a project from a different source?\nRaphael Lacuna — September 23, 2023 at 12:02 am (permalink) Raphael Lacuna says:\nI have the same issue, and I downloaded it from the VSCode version of the project\nSteve Hannah — September 23, 2023 at 12:50 pm (permalink) Steve Hannah says:\nJust tested on a fresh project and seemed to work.\nIn the Explorer, expand \u0026ldquo;Maven\u0026rdquo;\nYou’ll see:\nyour-app\nyour-app-anroid\nyour-app-common\nyour-app-ios\nyour-app-javascript\n…\nExpand the \u0026ldquo;your-app\u0026rdquo; one.\nThen expand \u0026ldquo;Favourites\u0026rdquo;\nYou should see all of the key build and run commands there.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/better-vscode-support-for-maven-projects/","summary":"\u003cp\u003eOur next update to the Codename One application archetype (7.0.59) includes some VSCode-specific config files to help improve integration for Maven Projects.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"VSCode configs - Codename One\" loading=\"lazy\" src=\"/blog/better-vscode-support-for-maven-projects/VSCode-configs-Codename-One-1024x536.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSwitching to Maven has been a good thing over all. Maven’s dependency management allows projects to work more consistently out of the box. No more missing dependencies, for the most part. Just clone the repo, build the project and go.\u003c/p\u003e\n\u003cp\u003eMaven’s dependency management and standard project structure results in one standard project structure that should work in any IDE that supports Maven. Unfortunately, each IDE still requires a little bit of fine-tuning to wire up our Maven goals to the IDEs’ menus.\u003c/p\u003e","title":"Better VSCode Support for Maven Projects"},{"content":"In the latest plugin update, we’ve added a Build-Hints Editor that accessible from a menu item inside the Codename One simulator. This is intended to make it easier to edit your app’s build hints, and also inform you of build hints that you may need to configure.\nUnlike the existing mechanisms for editing build hints (in Codename One Settings, or directly editing the codenameone_settings.properties file), this editor can integrate the requirements of installed cn1libs to help guide you through their configuration.\nThe latest release of the Google Maps cn1lib is the first module to make use of the build-hint editor. If you are developing a cn1lib that requires users to set specific build hints for its proper functioning, then you should follow the instructions in this article to integrate your library into the build hints editor.\nUsage Instructions In order to use the build-hints editor, you should launch your app in the Codename One simulator.\nOnce your app is running, select Tools \u0026gt; Edit Build Hints…​.\nThis will launch the build-hints editor in a new window as shown below.\nTIP The \u0026ldquo;Google Maps\u0026rdquo; tab appears in the above screenshot because the Google Maps cn1lib is installed in this app. If your app doesn’t use Google Maps, then it won’t include this tab.\nOne nice feature of this editor vs using Codename One settings is that some build hints include help text and example content, as well as buttons to perform complementary actions. For example, take a look at the field for the ios.afterFinishLaunching build hint:\nIt includes a text field for entering the build hint, some help text to let you know what this build hint is for and some example input to show you the proper format.\nIn this case it also includes a \u0026ldquo;Get Key\u0026rdquo; button that will open the webpage for creating an API key.\nThe old way to set up Google maps was to follow the README, and look manually walk through the required steps.\nIMPORTANT You should still read the installation instructions in the README for all cn1libs you are using. The Build-hints editor just provides a simpler way to deal with the build-hints portion of this.\nAfter making changes to your build hints, press Apply or Save. The difference is that Apply won’t close the build-hints editor. Save will.\nInstructions for CN1lib Developers If you are developing a cn1lib that requires users to add custom build hints to their app, consider adding a tab for your cn1lib in the build-hints editor. This can be done by defining some Display properties in your cn1lib.\nNOTE You can also define java.lang.System properties directly if you are working in JavaSE native code. When running in the simulator, calling CN1.setProperty(\u0026ldquo;foo\u0026rdquo;, \u0026ldquo;bar\u0026rdquo;) will ultimately call System.setProperty(\u0026ldquo;foo\u0026rdquo;, \u0026ldquo;bar\u0026rdquo;) under the hood.\nBefore I walk through the intricacies of the syntax, let’s look at the real-world example of the Google Maps library.\nSystem.setProperty( \u0026quot;codename1.arg.{{#googlemaps#javascript.googlemaps.key}}.label\u0026quot;, \u0026quot;Javascript API Key\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#javascript.googlemaps.key}}.description\u0026quot;, \u0026quot;Please enter your Javascript API key.\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#javascript.googlemaps.key}}.link\u0026quot;, \u0026quot;https://developers.google.com/maps/documentation/javascript/get-api-key Get Key\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#android.xapplication}}.label\u0026quot;, \u0026quot;android.xapplication\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#android.xapplication}}.description\u0026quot;, \u0026quot;Your android.xapplication build hint must inject your Android API key\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#android.xapplication}}.hint\u0026quot;, \u0026quot;\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#android.xapplication}}.link\u0026quot;, \u0026quot;https://developers.google.com/maps/documentation/android-sdk/get-api-key Get Key\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#ios.afterFinishLaunching}}.label\u0026quot;, \u0026quot;ios.afterFinishLaunching\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#ios.afterFinishLaunching}}.description\u0026quot;, \u0026quot;Your ios.afterFinishLaunching hint must inject your IOS API Key\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#ios.afterFinishLaunching}}.hint\u0026quot;, \u0026quot;[GMSServices provideAPIKey:@\\\u0026quot;YOUR_IOS_API_KEY\\\u0026quot;];\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#ios.afterFinishLaunching}}.link\u0026quot;, \u0026quot;https://developers.google.com/maps/documentation/ios-sdk/get-api-key Get Key\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#android.min_sdk_version}}.label\u0026quot;, \u0026quot;Android Minimum SDK Version\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#android.min_sdk_version}}.description\u0026quot;, \u0026quot;Your Android Minimum SDK Version must be at least 19\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#android.min_sdk_version}}.hint\u0026quot;, \u0026quot;19\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{@googlemaps}}.label\u0026quot;, \u0026quot;Google Maps\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{@googlemaps}}.description\u0026quot;, \u0026quot;The following build hints are required for the Google Maps cn1lib to operate correctly.\u0026quot; ); Allow me to unpack this a little bit. By defining these properties, the build-hints editor will know to generate the appropriate fields for the user to edit these build hints.\nThe general syntax is:\ncodename1.arg.{{ BUILD_HINT_NAME }}.PROPERTY_NAME where BUILD_HINT_NAME is the name of the build hint that this pertains to, and PROPERTY_NAME is the specific metadata property that we are setting.\nSome property names that you can define include:\nlabel The label for this build hint as it will be rendered in the built-hints editor.\ndescription The help text. A short blurb to let the user know what the build hint is for.\nhint Some example input for this build hint.\nlink An optional link to learn more about this build hint, or perform an associated action. This will be rendered as a button next to the help text for the build hint. You can optionally include a label for this button after the URL by leaving a \u0026ldquo;space\u0026rdquo; between them. E.g. \u0026ldquo;http://example.com/foobar Go to Foobar\u0026rdquo;\ntype The widget type to use for editing this build hint. Supported values include \u0026ldquo;textfield\u0026rdquo;, \u0026ldquo;textarea\u0026rdquo;, \u0026ldquo;checkbox\u0026rdquo;, and \u0026ldquo;select\u0026rdquo;\nvalues A list of options to use when the type property is \u0026ldquo;select\u0026rdquo;. Values should be delimited by a character, and the delimiter is defined by the trailing character. E.g. red, green, blue, or red; green; blue;. The import part is that the delimiter is included at the end as the build-hints editor will check the last character to find out what the delimiter is.\nWith this in mind, let’s take a look at the ios.afterFinishLaunching field settings:\nSystem.setProperty( \u0026quot;codename1.arg.{{#googlemaps#ios.afterFinishLaunching}}.label\u0026quot;, \u0026quot;ios.afterFinishLaunching\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#ios.afterFinishLaunching}}.description\u0026quot;, \u0026quot;Your ios.afterFinishLaunching hint must inject your IOS API Key\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#ios.afterFinishLaunching}}.hint\u0026quot;, \u0026quot;[GMSServices provideAPIKey:@\\\u0026quot;YOUR_IOS_API_KEY\\\u0026quot;];\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{#googlemaps#ios.afterFinishLaunching}}.link\u0026quot;, \u0026quot;https://developers.google.com/maps/documentation/ios-sdk/get-api-key Get Key\u0026quot; ); NOTE The `googlemaps prefix to the build hint causes the field to be rendered inside its own \u0026ldquo;Google Maps\u0026rdquo; tab of the build-hints editor.\nConfiguring Custom Tabs Notice that the Google maps build hints are all rendered inside a nice \u0026ldquo;Google Maps\u0026rdquo; tab. This is accomplished by defining a \u0026ldquo;googlemaps\u0026rdquo; group, and then assigning each property to that group. The portion that defines the \u0026ldquo;googlemaps\u0026rdquo; group is shown below:\nSystem.setProperty( \u0026quot;codename1.arg.{{@googlemaps}}.label\u0026quot;, \u0026quot;Google Maps\u0026quot; ); System.setProperty( \u0026quot;codename1.arg.{{@googlemaps}}.description\u0026quot;, \u0026quot;The following build hints are required for the Google Maps cn1lib to operate correctly.\u0026quot; ); The property name follows the same syntax as for regular properties: \u0026ldquo;codename1.arg.{{ @GROUP_NAME }}.PROPERTY_NAME\u0026rdquo;, except that the GROUP_NAME here must be prefixed with @. This signifies that the property pertains to the group as a whole rather than a particular build hint.\nThe second part of ensuring that properties render in the googlemaps group is that the build hint name needs to be prefixed with GROUPNAME. In this case it would be googlemaps.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/build-hints-editor/","summary":"\u003cp\u003eIn the latest plugin update, we’ve added a Build-Hints Editor that accessible from a menu item inside the Codename One simulator. This is intended to make it easier to edit your app’s build hints, and also inform you of build hints that you may need to configure.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"codename one - build hint editor\" loading=\"lazy\" src=\"/blog/build-hints-editor/cn1-build-hint-editor-1024x536.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eUnlike the existing mechanisms for editing build hints (in Codename One Settings, or directly editing the \u003ccode\u003ecodenameone_settings.properties\u003c/code\u003e file), this editor can integrate the requirements of installed cn1libs to help guide you through their configuration.\u003c/p\u003e","title":"Build-Hints Editor"},{"content":"We recently released a makeover to the iOS certificate wizard that makes it much easier to generate your certificates and provisioning profiles for your iOS deployments.\nThe key improvements in this new certificate wizard are:\n• Fewer Steps: A single form with checkboxes to select which items you want to generate, and then a login prompt. That’s it.\n• Much Faster: Generate all your certs in 60 seconds. Give or take a few.\n• More Reliable: We’ve taken steps to avoid network failures, which sometimes occurred due to the long-running back-end generation process.\nLaunching The Wizard The Certicate Wizard can be accessed in the same way as usual. Open Codename One Settings, and select Device Settings \u0026gt; iOS \u0026gt; Certificate Wizard.\nFigure 1. Access the certificate wizard under Device Settings \u0026gt; iOS \u0026gt; Certificate Wizard.\nScreenshots Select items to generate Figure 2. The first form in the wizard. Select which items to generate.\nTip If your project doesn’t have push enabled, then you won’t see the \u0026ldquo;Push Certificates\u0026rdquo; options.\nLog in with Apple Developer credentials Figure 3. Of course you still need to log in using your Apple Developer username and password so that the certificate wizard can generate the certificates for you.\nCertificate generation process Figure 4. You still need to wait for a minute while the server generates your certificates and profiles. If all goes well, this screen will remain for about a minute, though in the case of a failure (e.g. login failure), it should inform you sooner.\nResults and instructions Figure 5. The results and instructions appear when generation is complete.\nInstallation Location The certificates, profiles, and instructions will be saved in the iosCerts directory of your Codename One project. If you are using a Maven project structure this means they will be in common/iosCerts.\nFigure 6. Results are saved in the iosCerts directory of your project. See the readme.txt file for push instructions.\nYou can also see the results in the Device Settings \u0026gt; iOS \u0026gt; Signing section as shown below.\nFigure 7. The iOS signing section will automatically be updated to reflect the locations of the generated certificates and profiles.\nTip The new certificate wizard also generates a provisioning profile for the Notification Service Extension, which is used in the case that you are using rich push notifications.\nArchived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nThomasH99 — March 27, 2022 at 6:48 pm (permalink) ThomasH99 says:\nHello, it’s great with this kind of improvements, the certificate wizard is a huge help. However, I just tried this new version to regenerate my certificates and the first steps work fine, I confirm the access with the 6 digit code and it’s running, but then I get an error \u0026ldquo;Certification generation failed. null\u0026rdquo;. First I thought it was because my credit card had expired, but it’s fixed and I still can’t generate. Any suggestions for what may be going wrong?\nThomasH99 — March 27, 2022 at 7:16 pm (permalink) ThomasH99 says:\n(Sorry just posted this on an unrelated issue in reddit, it should be here:) I connected to my account and noticed I needed to approve the new license conditions (hadn’t see that on my last connect). After approving it, the error message is different: now it says I need to update to Xcode 7.3. I wonder if that is on my side (I guess not)? As a side note, the Certificate error window is too small to show the entire error message and it’s not possible to copy the text which would have been nice.\nSteve Hannah — March 28, 2022 at 1:43 pm (permalink) Steve Hannah says:\nI have opened an issue for this. https://github.com/codenameone/CodenameOne/issues/3571\nI cannot reproduce this issue myself, so it would be helpful if you would update that issue with some more details that might help to reproduce the issue.\nPaul Beardow — September 17, 2023 at 9:32 am (permalink) Paul Beardow says:\nIs there an easy way to generate ad-hoc builds? I want to test my app on a few friendly users but when I select the ad-hoc option the build fails. It seems the production certificate/profile created by the wizard isn’t the one that includes ad-hoc releases, only app store, so there is a mismatch and an error.\nShai Almog — September 18, 2023 at 2:25 am (permalink) Shai Almog says:\nThe release certificate is the same for ad-hoc builds. You might need to make changes to the provisioning profile which you can do on apples site. The wizard creates a simple one for you but you don’t need it for editing that.\nThe main reason the wizard is needed is for certificates.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-ios-certificate-wizard/","summary":"\u003cp\u003eWe recently released a makeover to the iOS certificate wizard that makes it much easier to generate your certificates and provisioning profiles for your iOS deployments.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"New iOS Certificate Wizard - Codename One\" loading=\"lazy\" src=\"/blog/new-ios-certificate-wizard/New-iOS-Certificate-Wizard-1024x536.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe key improvements in this new certificate wizard are:\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e\u003cstrong\u003e• Fewer Steps\u003c/strong\u003e\u003c/strong\u003e: A single form with checkboxes to select which items you want to generate, and then a login prompt. That’s it.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e\u003cstrong\u003e• Much Faster\u003c/strong\u003e\u003c/strong\u003e: Generate all your certs in 60 seconds. Give or take a few.\u003c/p\u003e","title":"New iOS Certificate Wizard"},{"content":"We\u0026rsquo;re adjusting pricing for paid plans for new users signing up after December 31st, 2021. Learn how you can keep the old price.\nSince we launched Codename One in 2012, we only raised our prices once and only on the Basic account which was priced ridiculously low at $9.\nTo this day, we have dozens of Basic plan subscribers on that $9 per month plan. They are some of my favorite subscribers. Their loyalty to the platform is admirable and we want to repay that loyalty.\nWhy the price increase? As you know the prices for hosting, living etc have increased globally. The current price structure is just untenable moving forward with our current cost structure.\nAs such we decided to do our first \u0026ldquo;real\u0026rdquo; pricing change. Even after this change we’re still one of the most affordable options in our field and we still have the free account which we plan to keep forever.\nFor current subscribers If you sign up before December 31st and keep the account (don’t suspend or cancel). Your price point will remain the same as it is today.\nJust to be 100% clear: recurring renewal of subscriptions will use the existing prices and not the newer prices.\nSo the price changes we’re announcing right now only apply to users signing up after December 31st.\nIf you have been looking for a sign to sign-up or upgrade, this might be it!\nHere are the new tiers The new prices starting January 1st, 2022 will be:\nPlan Monthly Price Annual Price Basic $29 $300 ($25/month) Pro $99 $1020 ($85/month) Enterprise $499 $5400 ($450/month) We will also introduce an annual basic account as part of these changes.\nAgain, if you sign up before December 31st you can keep using the current prices indefinitely.\nTo summarize ****• If you’re on a free plan, these changes will not affect you.\n• Current recurring subscription renewals will use the existing prices and not the newer prices.\n• This price change only apply to users signing up to any paid plan after December 31st.\n• If you subscribe to any paid plan before December 31st, you’ll keep the current pricing forever (as long as you stay subscribed).****\nHave any questions or concerns? Just reach out via the live chat on our website.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/we-are-raising-prices/","summary":"\u003cp\u003eWe\u0026rsquo;re adjusting pricing for paid plans for new users signing up after December 31st, 2021. Learn how you can keep the old price.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Pricing Change - Codename One\" loading=\"lazy\" src=\"/blog/we-are-raising-prices/cn1-new-pricing-1024x536.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSince we launched Codename One in 2012, we only raised our prices once and only on the Basic account which was priced ridiculously low at $9.\u003c/p\u003e\n\u003cp\u003eTo this day, we have dozens of Basic plan subscribers on that $9 per month plan. They are some of my favorite subscribers. Their loyalty to the platform is admirable and we want to repay that loyalty.\u003c/p\u003e","title":"We’re Raising Prices! Here’s how you can keep the old Price"},{"content":"It’s Hacktoberfest time! 🎃 Contribute to Codename One for Hacktoberfest to give back to open-source this October.\nWe’re excited that Codename One is participating in Hacktoberfest this year. Now in its eighth year, Hacktoberfest is a global online festival aiming to drive contribution and involvement in open source projects.\nWe encourage contributions from the Hacktoberfest community. People of all backgrounds and skill levels are welcome!\nWhat is Hacktoberfest? Hacktoberfest is a month-long global celebration of open source software run by DigitalOcean with a strong focus on encouraging contributions to open source projects.\nFrom senior developers to students learning to code; open source enthusiasts of all skill levels can participate.\nThe rules are simple: create a minimum of 4 quality Pull Requests on GitHub to any open source project repo during the whole month of October and have them accepted by a maintainer.\nBy completing this challenge, you will earn your Hacktoberfest 👕 swag or help plant a 🌲 tree. Just make sure to register first!\n👉 Learn more about Hacktoberfest here.\nWhy Contribute to Codename One? History Codename One is a revolutionary mobile development solution started by ex-Sun Microsystems developers based on work that started within Sun. Codename One delivers the Write Once Run Anywhere (WORA) promise of Java for mobile devices by intelligently cross compiling to native code.\nEstablished \u0026amp; Mature Codename One version 1.0 was released in 2012. It was the first solution to build native iPhone apps in Java and is still the most mature, performant and stable cross-platform mobile toolkit on the market.\nIt is now being used by many well-known organizations including banks, government agencies and startups.\nFree \u0026amp; Open Source The core of Codename One is free and open source. GPL + CE licensed so it is free to use with commercial projects.\nCommunity Codename One has a consolidated and active community of developers and enthusiasts.\nIf you are a true believer in Java and the power of cross-platform, you can help make Codename One even better! 🙌\nHow to Contribute to Codename One? Before you start working on something, we would suggest talking to us in the cn1 subreddit or asking a question on stack overflow with the codenameone tag. You can also contact us via the chat widget on our website.\nTo make it easier to start contributing to Codename One, we’ve outlined some guidelines in our CONTRIBUTING.md file available at our GitHub repository.\nSteps to Contribute: • Visit Hacktoberfest website and sign in with your GitHub account ✅\n• Choose your favorite Codename One issue and submit your Pull Request 👨‍💻\n• Wait for your PR to be reviewed and merged 💕\nNote To make issues easier to discover, we have tagged them with relevant labels 🏷️ i.e. Hacktoberfest, good first issue etc.\nBest of luck and Happy Hacktoberfest! 🎃\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/contribute-to-codename-one-during-hacktoberfest/","summary":"\u003cp\u003eIt’s Hacktoberfest time! 🎃 Contribute to Codename One for Hacktoberfest to give back to open-source this October.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Codename One - Hacktoberfest 2021\" loading=\"lazy\" src=\"/blog/contribute-to-codename-one-during-hacktoberfest/Hacktoberfest-2021-1024x536.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’re excited that Codename One is participating in Hacktoberfest this year. Now in its eighth year, Hacktoberfest is a global online festival aiming to drive contribution and involvement in open source projects.\u003c/p\u003e\n\u003cp\u003eWe encourage contributions from the Hacktoberfest community. People of all backgrounds and skill levels are welcome!\u003c/p\u003e","title":"Contribute to Codename One during Hacktoberfest"},{"content":"We have moved the support to Reddit on the subreddit r/cn1 for open discussion, support and also to allow the users to help each other.\nWe used Google Groups as our main/secondary support channel for a while now. It sucked, but it was a shortcut to get things going and like many things, it just stuck.\nA couple of weeks ago we made the decision to create a new subreddit r/cn1 and move our support to that sub.\nThis has multiple advantages for us and for the community. As such we’re asking you to join that group. Don’t just visit it, register and press the \u0026ldquo;Join\u0026rdquo; button to be a part of it.\nWhy Leave Google Group? The Google Group sucked because of bad spam detection. Over zealous auto-moderation. Horrible UI and constant changes to that UI.\nThis even included removal of important features such as code highlighting and post pinning. Those two were the final straws.\nWhy Reddit? With Reddit there are multiple advantages we can leverage out of the box. Decent native apps, integrations, code highlighting, state of the art moderation and threaded discussions, image embedding, links, advanced styling and more.\nTo be fair there are a couple of things that don’t work as nicely, namely email digests and attachments.\nSome Tips for Reddit You can enable a daily email digest on Reddit in your user email settings page. This isn’t the same as an automatic email on every post but it’s good enough. I personally use Feedly which includes the ability to track a subreddit and that’s pretty useful for keeping track of r/cn1 as well as other interests I have.\nAttachments shouldn’t be in the discussion forum. There’s images which you can add using an image post (which I encourage doing).\nFor short amounts of code/logs you can add a comment with source code.\nFor longer sources, file an issue in GitHub, include a link to a GitHub gist file or something similar to that.\nSupport Us Please take the time to:\n✅ Join the Subreddit ✅ Follow the codenameone tag on StackOverflow ✅ Star us on GitHub These things take a moment of your time but go a long way to demonstrate our traction to new Codename One developers.\nThank you! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nFrancesco Galgani — August 23, 2021 at 6:32 am (permalink) Francesco Galgani says:\nAre there any situations where we should prefer Reddit to Stack Overflow or vice versa?\nShai Almog — August 24, 2021 at 1:43 am (permalink) Shai Almog says:\nThey are pretty distinct. Stack overflow is strictly for \u0026ldquo;worthy questions\u0026rdquo; and that might be a gray area. If you feel less confident then our subreddit aims to be more welcoming. Since we’re the moderators of the subreddit we have more control over things posted and won’t moderate you aggressively like stackoverflow sometimes does (unfortunately).\nI like SO, it takes getting used to though.\nFrancesco Galgani — August 24, 2021 at 7:28 pm (permalink) Francesco Galgani says:\nThanks for the clarification. I like Stack Overflow which I’ve gotten used to by now and I think I’ll continue to use it, but as you told the moderation is a bit too aggressive. By the way, there are borderline issues, such as asking for advice, for which Stack Overflow is not suitable and neither is Github. So I understand the choice of Reddit.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/moving-the-support-to-reddit/","summary":"\u003cp\u003eWe have moved the support to Reddit on the subreddit r/cn1 for open discussion, support and also to allow the users to help each other.\u003c/p\u003e\n\u003cp\u003eWe used Google Groups as our main/secondary support channel for a while now. It sucked, but it was a shortcut to get things going and like many things, it just stuck.\u003c/p\u003e\n\u003cp\u003eA couple of weeks ago we made the decision to create a new subreddit \u003cstrong\u003e\u003cstrong\u003e\u003ca href=\"https://www.reddit.com/r/cn1/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003er/cn1\u003c/a\u003e\u003c/strong\u003e\u003c/strong\u003e and move our support to that sub.\u003c/p\u003e","title":"Moving the Support to Reddit"},{"content":"We are proud to announce the immediate availability of the CodeRAD 2.0 developer preview. CodeRAD is a modern MVC framework for building truly native, mobile-first, pixel-perfect applications in Java and Kotlin.\nCodeRAD 2 builds upon the solid foundation of CodeRAD 1.0, and adds several new features aimed at increasing component reuse, and improving developer experience.\nDeclarative View Syntax First among the long list of new features included in CodeRAD 2 is the ability to write your View classes in XML.\nFor example, consider this simple login form component written in Java:\npackage com.example.mybareapp; import com.codename1.ui.*; import com.codename1.ui.layouts.BoxLayout; import com.codename1.ui.layouts.FlowLayout; public class LoginForm extends Container { public MyJavaForm() { super(BoxLayout.y()); Label loginHeading = new Label(\u0026#34;Login\u0026#34;); loginHeading.setUIID(\u0026#34;LoginHeading\u0026#34;); TextField username = new TextField(); username.setMaxSize(30); username.setConstraint(TextField.USERNAME); username.setUIID(\u0026#34;LoginField\u0026#34;); username.setHint(\u0026#34;Enter username\u0026#34;); username.getHintLabel().setUIID(\u0026#34;LoginFieldHint\u0026#34;); TextField password = new TextField(); password.setConstraint(TextField.PASSWORD); password.setUIID(\u0026#34;LoginField\u0026#34;); password.setHint(\u0026#34;Enter password\u0026#34;); password.getHintLabel().setUIID(\u0026#34;LoginFieldHint\u0026#34;); Label usernameLabel = new Label(\u0026#34;Username:\u0026#34;); usernameLabel.setUIID(\u0026#34;LoginFieldLabel\u0026#34;); Label passwordLabel = new Label(\u0026#34;Password:\u0026#34;); passwordLabel.setUIID(\u0026#34;LoginFieldLabel\u0026#34;); Button login = new Button(\u0026#34;Login\u0026#34;); login.setUIID(\u0026#34;LoginButton\u0026#34;); Button reset = new Button(\u0026#34;Reset\u0026#34;); reset.setUIID(\u0026#34;ResetButton\u0026#34;); Container buttons = FlowLayout.encloseCenter( reset, login ); addAll(loginHeading, usernameLabel, username, passwordLabel, password, buttons ); } } You could write the same component as a CodeRAD view using the following:\nxml version=1.0\u0026#34; ? Login Username: Password: Reset Login The XML view is automatically transformed into a Java class by the CodeRAD annotation processor so that performance is on par with the hand-coded Java version.\nThis example demonstrates the primary benefit of using XML as a language for writing view classes: It is declarative! The XML representation maps directly to way the view will be presented in the app.\nThis example is just the tip of the iceberg, however, as CodeRAD’s XML views also include many other features aimed at making your development experience as smooth as possible. They have built-in support for property binding, for example, making it easy to maintain a clean separation between your View and Controller logic.\nHot Reload When building user interfaces, the biggest pain point, by far, is the \u0026ldquo;test-edit-reload\u0026rdquo; cycle. e.g. Load app in simulator, add label to your form, reload app in simulator, navigate back to form, repeat…​\nHaving to wait while the app is recompiled, and the simulator is reloaded each time you make a change is an excruciating productivity killer.\nCodeRAD 2 takes a giant step toward alleviating this problem with its introduction of Hot Reload. When this feature is enabled, the simulator will update in near real time (1-2 second delay) as you make changes to your application source.\nThere are two modes for Hot Reload:\nReload Simulator – This will restart your app at your \u0026ldquo;start form\u0026rdquo; when changes are detected.\nReload Current Form – This will restart your app, and automatically load the current Form, to save you from having to manually navigate there.\nNote This is actually a pseudo \u0026ldquo;hot\u0026rdquo; reload, as it restarts your app rather than just patching code in place like the existing \u0026ldquo;Apply code changes\u0026rdquo; feature in most Java IDEs does. The \u0026ldquo;apply code changes\u0026rdquo; feature is very limited as it doesn’t apply to code that has already been run in your app, and it doesn’t support things like adding methods or classes. If you are trying to test changes to a UI form using \u0026ldquo;apply code changes\u0026rdquo;, you would typically need to navigate away from your form, and navigate back after code changes are applied to see the changes. And this would still be insufficient in cases where the UI depends on \u0026ldquo;bootstrap\u0026rdquo; code in the app. A full app restart is necessary to reliably see the result of code changes, and this is what CodeRAD’s hot reload feature provides.\nCodeRAD 2 Intro Video This introduction to CodeRAD 2 video is a good starting point if you want to learn more about the features and concepts of CodeRAD.\nGetting Started We have added a \u0026ldquo;CodeRAD (MVC) Starter Project\u0026rdquo; option to the Codename One initializr, which will give you a starting point for developing apps with CodeRAD 2.\nThe \u0026ldquo;Tweet App\u0026rdquo; template is also a CodeRAD 2 project that provides a twitter-style app template, with login forms, and a tweet list view.\nLearn More We have developed a wealth of resources to help you get started with CodeRAD. After watching the intro Video, you can check out these other resources:\nThe CodeRAD Developers Guide This includes an introduction to the key concepts, as well as two tutorials: 1. Getting Started and companion screencast.\n2. Building a Twitter Clone\nThe CodeRAD Wiki The best source for reference documentation on CodeRAD components. The CodeRAD Javadocs JavaDocs for CodeRAD. Github Repository All the source for CodeRAD. Sample Projects 1. CodeRAD2 Samples – Includes a growing set of samples demonstrating the use of CodeRAD components. Views are located in the src/main/rad/views directory.\n2. Tweet App – A partial twitter clone.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/announcing-coderad-2-0-preview/","summary":"\u003cp\u003eWe are proud to announce the immediate availability of the CodeRAD 2.0 developer preview. CodeRAD is a modern MVC framework for building truly native, mobile-first, pixel-perfect applications in Java and Kotlin.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"CodeRAD 2.0\" loading=\"lazy\" src=\"/blog/announcing-coderad-2-0-preview/CodeRAD-2.0-1024x576.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodeRAD 2 builds upon the solid foundation of CodeRAD 1.0, and adds several new features aimed at increasing component reuse, and improving developer experience.\u003c/p\u003e\n\u003ch3 id=\"declarative-view-syntax\"\u003eDeclarative View Syntax\u003c/h3\u003e\n\u003cp\u003eFirst among the long list of new features included in CodeRAD 2 is the ability to write your \u003cstrong\u003eView\u003c/strong\u003e classes in XML.\u003c/p\u003e","title":"Announcing CodeRAD 2.0 Preview"},{"content":"Learn how we debug our backend servers and provide fast updates without breaking deployments.\nMark Zuckerberg famously quipped that Facebook works under the \u0026ldquo;Move fast and break things\u0026rdquo; motto. We can write all the unit tests in the world, have the largest QA pipeline but still bugs slither into production. That’s just a fact of life which he chose to celebrate.\nWhen dealing with an incredibly complex system like we have in Codename One this can be the difference between releasing an update and doing nothing.\nIf you are a visual learner check out the following video: Disaster Strikes The problem with this approach becomes apparent when we have a bug in production. Normally, a bug that would go through staging, QA and tests wouldn’t be too horrible… But since it’s a production only bug you’re often faced with two options:\n• Revert — That might not be an option for all cases • Find/Implement a Fix Notice that I left out \u0026ldquo;reproduce it locally\u0026rdquo;. This is often not an option for production bugs which work on a separate DB in \u0026ldquo;real world\u0026rdquo; conditions. In our case local debugging is very difficult due to the multiple separate servers that hand off tasks to one another.\nThe second option is usually best but it includes a huge risk: what if the fix fails?\nSince production deployment is often a slow process that requires a QA cycle this compounds the problem. You make a fix then have to wait for hours only to find out that you got it wrong… This used to be us.\nEnter Lightrun So a couple of years ago I met two young founders who had an idea on how to solve this problem. Essentially, it’s a new kind of debugger that works very differently from a regular debugger.\nThe gist of this is that your app constantly runs in a production debugging mode, the overhead is barely noticeable. A secure agent connects the app to the cloud and lets you debug in a special way.\ne.g. instead of breakpoints you have snapshots. They don’t \u0026ldquo;break\u0026rdquo;. They provide you with a stack trace of the thread and the variable state at the given time. You can also inject log statements, count executions and even do simple profiling on methods or blocks of code.\nI was so impressed by this idea that I decided to join the team and now hold two jobs (at Codename One and at Lightrun). The cool thing is that my job at Codename One is now much easier thanks to Lightrun.\nBugs in Production… 90% of my work at Codename One is putting out fires. A subscriber writes to our support complaining about a failure of a build or push servers etc. This used to be very hard to debug. We would spend hours reading huge logs and guessing\nThen we’d deploy additional logs, ask the user to send a new build and then reread the logs to figure out what the hell went wrong. Some of the guessing is always there but with Lightrun the whole process is practically instant.\nWith Lightrun we can just set a conditional snapshot e.g.\nDebugging a failure in push\nIn the case above I can grab a snapshot when a specific user sends a push. This is a conditional breakpoint, that’s a useful tool when debugging locally. It’s an indispensable tool when debugging in production. We only want to see the information related to a specific user and not all users…\nWhen the snapshot hits we end up with a stack trace similar to this one (I blacked out private information in the image).\nSnapshot Stack\nNotice that a Snapshot looks just like a regular breakpoint. It’s missing the threads and you can’t step over. But you can walk the stack and inspect the values of fields/variables etc. when the application is still running… Pretty darn useful!\nInstead of stepping over you can just add multiple snapshots or even inject logs to print information when hitting a specific line. Including simple expressions such as: The value is {obj.getValue()}.\nMy immediate thought was \u0026ldquo;won’t this be expensive?\u0026rdquo;.\nIt isn’t. If we have a very complex/expensive expressions that prints too much per second or uses problematic (e.g. recursive) logic, Lightrun is smart enough to limit itself so the expression won’t take too much CPU. It protects you from shooting yourself in the foot…\nAs a result of that there’s no noticeable performance overhead and you can work without worrying. But I digress, lets go back to the push server example above.\nUnexpected Bug When I started this post I wanted to reproduce a debugging session for a user problem but as I was grabbing the screenshots for the session I noticed something weird in the stack. The value of subscriptionLevel was gibberish. It was way too large.\nTurns out we had a bug in reading the user subscription level when sending push messages. That meant that quotas and rate limits weren’t applied at all in our push server!\nI’m sure we lost income because of this bug, users whose subscription elapsed could still send push messages at volume without a problem. Ugh!\nThis is one of the coolest benefits of Lightrun, it lets you see clearly into the running system and verify your expectations.\nExpected User Problem The real problem I debugged relates to that line above. A user stopped getting iOS push messages. I just placed a Snapshot (AKA breakpoint) with his token, then inspected the values sent to the push server.\nI could then see the URL of the push certificate and could instantly verify that it expired. This was easier to do than debugging locally!\nThe Deeper Pipeline User issues are very important but issues that no one is aware of are possibly even more important…\nException Monitoring\nLightrun also provides a way to detect exceptions (caught or uncaught). We can review the stack traces periodically to see if there are errors that we didn’t detect.\nThis isn’t a unique feature to Lightrun, but it fits perfectly as you can easily trace a problem you saw in the stack traces.\nMetrics Lightrun also includes metrics such as counters, tictocs and method duration measurements.\nThis is super useful for micro-benchmarks in production but we don’t need this as much in Codename One. Our backend is relatively simple and these never came up.\nInstalling Lightrun So, there has to be a downside right?\nInstalling the plugin in the IDE and signing up is very easy… But agent setup is still challenging. I spent a lot of time trying to get it to work on all our servers.\nAdmittedly the Codename One architecture is pretty complex filled with a lot of legacy and pre-docker deployment choices. Prepare yourself for a bit of work. It might be trivial but you might need some help from the web chat support channel (which is super responsive).\nSignup Page on app.lightrun.com\nOnce you sign up at https://app.lightrun.com/ you get a wizard that verifies you performed the steps correctly:\nInstall the Plugin and Login\nTo pass the first step you need to install the IntelliJ plugin from the marketplace.\nYou then need to restart the IDE, open the Lightrun tool window on the right hand side and press the login button.\nOnce logged in, the Next button in the wizard will become enabled and you could move on to the agent installation step. This is the hard part…\nAgent Install instructions, notice I erased private information\nThe agent is typically installed on your server and not on your local machine. So when I reached this page \u0026ldquo;Mac\u0026rdquo; was selected. I had to explicitly select the Linux page and copy the script that installs the agent on Linux machines.\nThe next step is to SSH to the machine and run the script. It creates an \u0026ldquo;agent\u0026rdquo; directory which we’ll use when binding the agent.\nThe gist of this is that we need to add the -agentpath argument to the JVM. That’s very simple if your deployment has a \u0026ldquo;java\u0026rdquo; command invocation at some point but if your running as a service or within a container that might not be so simple.\nOnce you do that the \u0026ldquo;Next\u0026rdquo; option will be enabled and you would be able to use Lightrun.\nBut there are more complex cases, I would recommend reviewing the list here.\nOne example is our older Tomcat server used for push. I had to edit catalina.sh and add something like this:\nJAVA_OPTS=\u0026#34;$JAVA_OPTS -agentpath:/home/username/agent/lightrun_agent.so= --lightrun_extra_class_path=/home/username/apache-tomcat/webapps/myapp.war\u0026#34; Notice the extra option of --lightrun_extra_class_path (that’s 2 minus signs) which we use to explicitly state the classpath. You might need that if things aren’t auto-detected properly. This let the agent run but I got no variables in my stack traces… Turns out I had to recompile the code with full debug options turned on -g. This was a bit of a challenge in Maven. The solution was to add these properties:\n... true true lines,vars,source lines,vars,source You can test that -g is missing using code like this:\njavap -classpath Project/target/classes -v pkg.ClassName | grep LocalVariableTable If this prints nothing then the class doesn’t contain debug information.\nAgain, this is an involved process. I strongly suggest engaging support while going through it.\nTL;DR The reason we don’t rush to production is the tedious and slow process of fixing production issues. But this creates an overly complex multi-branch support structure that ends up making matters worse.\nIf we can debug quickly in the production and fix right away our overall stability increases while keeping a low overhead.\nIMO Deploying a server today without debugging tools is akin to coding without an IDE. You can do that but you’re missing out on modern advancements in our field.\nAt Codename One, our user support tasks are resolved much faster and more effectively thanks to Lightrun.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/debugging-in-production-how-to-move-fast-without-breaking-things/","summary":"\u003cp\u003eLearn how we debug our backend servers and provide fast updates without breaking deployments.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Debugging in Production - How to move fast without breaking things\" loading=\"lazy\" src=\"/blog/debugging-in-production-how-to-move-fast-without-breaking-things/Debugging-in-Production-How-to-move-fast-without-breaking-things-1024x280.jpeg\"\u003e\u003c/p\u003e\n\u003cp\u003eMark Zuckerberg famously quipped that Facebook works under the \u0026ldquo;Move fast and break things\u0026rdquo; motto. We can write all the unit tests in the world, have the largest QA pipeline but still bugs slither into production. That’s just a fact of life which he chose to celebrate.\u003c/p\u003e","title":"Debugging in Production – How to move fast without breaking things"},{"content":"We’ve added some new units that you can use for specifying things like margin, padding and font sizes. You can use each of these units directly in your CSS stylesheets.\nWe’ve added some new units that you can use for specifying things like margin, padding, and font sizes.\nThese units are rem, vh, vw, vmin, and vmax.\nYou can use each of these units directly in your CSS stylesheets, and there are corresponding style constants for each of these so that you can use them directly in your Java code.\nThese units were inspired by their CSS counterparts, so if you are familiar with these units from CSS, they have the same meaning (except for rem, which is a little bit different).\nrem 1rem is the line height of the default font. i.e. 1rem == Font.getDefaultFont().getHeight(). This unit is particularly useful if you would like to set your font size relative to the system’s default font size.\nrem examples in CSS /* A label that 1.5x bigger than the line height of the default font. */ MyBigLabel { font-size: 1.5rem; } /* A label roughly size of default font. */ MyNormalLabel { font-size: 0.7rem; } /* 1 line height padding */ MyPaddedContainer { padding: 1rem; } Converting rem to pixels in Java // Padding 1.5x line height of default font int padding = CN.convertToPixels(1.5, Style.UNIT_TYPE_REM); // Create a Truetype Font with REM sizing Font myFont = Font.createTruetypeFont(CN.NATIVE_MAIN_REGULAR, 1.5f, Style.UNIT_TYPE_REM); // Deriving font to smaller size Font mySmallFont = myFont.derive(0.5f, Style.UNIT_TYPE_REM); Note Since 1rem is equal to the line height of the default font, it is slightly bigger than the actual default font size. Usually around 0.7rem will give you a font with the same size as the default font.\nvw and vh 1vw and 1vh are 1 percent of the viewport width and height respectively. These differ from the existing percent unit in Codename One because the percent unit is contextual. i.e. If it is applied to the top or bottom padding, it will be relative to the viewport height, and if it is applied to the left or right padding, it will be relative to the viewport width. vw and vh, by contrast, are explicitly relative to the viewport width (for vw) or height (for vh).\nUsing vw unit from CSS MyContainer { /* Make right margin 10% of screen width */ margin-right: 10vw; } Setting margin in Java using UNIT_TYPE_VW constant // Set right margin of this Style object to 10% of screen width. myStyle.setMarginUnitRight(Style.UNIT_TYPE_VW); myStyle.setMarginRight(10); vmin and vmax 1vmin is 1 percent of the minimum of viewport width and viewport height. i.e. 1vmin=Math.min(CN.getDisplayWidth(), CN.getDisplayHeight())/100f\n1vmax is 1 percent of the maximum of viewport width and viewport height. i.e. 1vmax=Math.max(CN.getDisplayWidth(), CN.getDisplayHeight())/100f\nUsing vw unit from CSS MyContainer { /* Make right margin 10% either screen width or height - whichever is smaller */ margin-right: 10vmin; } Setting margin in Java using UNIT_TYPE_VW constant. // Set right margin of this Style object to 10% of smaller of screen width or height. myStyle.setMarginUnitRight(Style.UNIT_TYPE_VMIN); myStyle.setMarginRight(10); Overriding the Default Font Size When trying to make a design look \u0026ldquo;good\u0026rdquo; across multiple platforms it can be difficult to deal with the differing default font sizes on different platforms. You may spend hours tweaking your UI to look perfect on iPhone X, only to find out that the fonts are too small when viewed on an android device. We have now added theme constants to explicitly set the the default font size in \u0026ldquo;screen-independent-pixels\u0026rdquo;.\nNote In this case, 1 screen-independent-pixel is defined as 1/160th of an inch on a device, and 1/96th of an inch on desktop. These values correspond to Android’s definition on device, and Windows\u0026rsquo; definition on the desktop.\nIf you add the following to your stylesheet, it will set the default font size to 18 screen-independent pixels (or 18/160th of an inch), which corresponds to the Android native default \u0026ldquo;medium\u0026rdquo; font size.\n#Constants { defaultFontSizeInt: 18; } Tip I have found that a value of 18 here gives optimum results across devices.\nDesktop and Tablet Default Font sizes On the desktop, you may find that 18 is too big. You can additionally define a default font size for for tablet and desktop using defaultDesktopFontSizeInt and\ndefaultFontSizeDesktopInt respectively. I have found that a defaultDesktopFontSizeInt gives results that closely match the Mac OS default font size.\n#Constants { defaultFontSizeInt: 18; defaultDesktopFontSizeInt: 14; } Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-css-units-in-codename-one-apps/","summary":"\u003cp\u003eWe’ve added some new units that you can use for specifying things like margin, padding and font sizes. You can use each of these units directly in your CSS stylesheets.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"New CSS Units in Codename One Apps\" loading=\"lazy\" src=\"/blog/new-css-units-in-codename-one-apps/New-CSS-Units-in-Codename-One-Apps-1024x576.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve added some new units that you can use for specifying things like margin, padding, and font sizes.\u003c/p\u003e\n\u003cp\u003eThese units are \u003ccode\u003erem\u003c/code\u003e, \u003ccode\u003evh\u003c/code\u003e, \u003ccode\u003evw\u003c/code\u003e, \u003ccode\u003evmin\u003c/code\u003e, and \u003ccode\u003evmax\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eYou can use each of these units directly in your CSS stylesheets, and there are corresponding \u003ccode\u003estyle\u003c/code\u003e constants for each of these so that you can use them directly in your Java code.\u003c/p\u003e","title":"New CSS Units in Codename One Apps"},{"content":"We will update the build servers to target Android API level 30 this Friday.\nThe API level change should be seamless to most of you but might impact some edge case functionality and cause some native/cn1libs to fail in odd ways.\nSo be sure to do extra checks on Android when building a new release.\nThis change is mandated by Google who require that you target the latest Android version by August of this year.\nYou can set the build hint android.buildToolsVersion=29 as a temporary workaround if things break for your app. Please let us know in that case so we can help resolve those issues. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nplumberg — July 13, 2021 at 8:18 pm (permalink) plumberg says:\nThe geofence is not firing (or firing sometimes, in unpredictable way) unless I add android.buildToolsVersion=29 build hint. (Tested on Android 10 API 29 and Android 8.1 API 27).\nShai Almog — July 14, 2021 at 1:15 am (permalink) Shai Almog says:\nThanks for the headsup. We’ll look into it\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/moving-to-api-level-30/","summary":"\u003cp\u003eWe will update the build servers to target Android API level 30 this Friday.\u003c/p\u003e\n\u003cp\u003eThe API level change should be seamless to most of you but might impact some edge case functionality and cause some native/cn1libs to fail in odd ways.\u003c/p\u003e\n\u003cp\u003eSo be sure to do extra checks on Android when building a new release.\u003c/p\u003e\n\u003cp\u003eThis change is mandated by Google who require that you target the latest Android version by August of this year.\u003c/p\u003e","title":"Moving to API Level 30"},{"content":" Home Websites and service recommended by Codename One.\n• Linode: Our preferred hosting provider (free $100 in hosting credit via this link)\n• Crisp: Our preferred live chat and email provider.\n• Mac Mini Vault: Our preferred Mac build server.\n","permalink":"https://www.codenameone.com/recommended-sites/","summary":"\u003cul\u003e\n\u003cli\u003eHome\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eWebsites and service recommended by Codename One.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e\u003ca href=\"https://www.linode.com/?r=57ffeef90ab49b35f5bdc2a8658a413515d8b3ca\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e• Linode:\u003c/a\u003e\u003c/strong\u003e Our preferred hosting provider (free $100 in hosting credit via this \u003cstrong\u003e\u003ca href=\"https://www.linode.com/?r=57ffeef90ab49b35f5bdc2a8658a413515d8b3ca\" target=\"_blank\" rel=\"noopener noreferrer\"\u003elink\u003c/a\u003e\u003c/strong\u003e)\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e\u003ca href=\"https://crisp.chat/en/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e• Crisp:\u003c/a\u003e\u003c/strong\u003e Our preferred live chat and email provider.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e\u003ca href=\"https://www.macminivault.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e• Mac Mini Vault:\u003c/a\u003e\u003c/strong\u003e Our preferred Mac build server.\u003c/p\u003e","title":"Recommended Sites"},{"content":"This blog post contain tips for working with the Javascript port of Codename One apps.\nSending Messages to Outside Webpage Problem You want to send a message from your Codename One app to the webpage that contains it.\nSolution You can use CN.postMessage(), in Codename One to send the message. The message will be dispatched to Javascript event listeners in the outside webpage that register to receive cn1outbox events.\nSending a message from Codename One to the outside webpage: // The Java side MessageEvent message = new MessageEvent( null, // event source... we\u0026#39;ll leave it null \u0026#34;Hello\u0026#34;, // The message to deliver 0 // Optional message code. ); //Dispatch the message CN.postMessage(message); Receiving messages from Codename One in outside webpage: // The javascript side window.addEventListener(\u0026#39;cn1outbox\u0026#39;, function(evt) { var message = evt.detail; var code = evt.code; ... }); Discussion The CN.postMessage() method allows you to send a message to the native platform. When deploying as a Javascript app, these messages are converted to custom DOM events and dispatched on the window object. The event name is \u0026ldquo;cn1outbox\u0026rdquo;, so you can receive events like this from the \u0026ldquo;javascript\u0026rdquo; side by registering an event listener for these types of events on the window object.\nReceiving Messages from the Outside Webpage Problem You want to send messages from Javascript (i.e. the page containing the app) to the Codename One app.\nSolution From Javascript, you can dispatch a custom event named ‘cn1inbox’ on the window object. You can receive these events in Codename One using the CN.addMessageListener() method.\nSending Message from Javascript that can be received inside Codename One app: // The javascript side var message = new CustomEvent(\u0026#39;cn1inbox\u0026#39;, {detail: \u0026#39;Hello\u0026#39;, code: 0}); window.dispatchEvent(message); Receiving Event in Codename One // The Java side CN.addMessageListener(evt-\u0026gt;{ String message = evt.getMessage(); int code = evt.getCode(); ... }); Discussion The CN.addMessageListener() and CN.removeMessageListener() methods allow you to register listeners to receive messages from the native platform. When the app is deployed as a Javascript app, the webpage can target these listeners using a custom DOM event named ‘cn1inbox’. The Codename One app will receive all events of this type, and dispatch them to the listeners that were registered using CN.addMessageListener().\nNotify Webpage When App is Started Problem You want to notify the outside page when the app is finished loading. If the webpage needs to communicate with the app, it is very helpful to know when the app is ready.\nSolution Register a DOM event listener on the window object for the aftercn1start event.\nwindow.addEventListener(\u0026#39;aftercn1start\u0026#39;, function(evt) { console.log(\u0026#34;The Codename One app has started...\u0026#34;); ... }); Discussion Codename One broadcasts its lifecycle events as DOM events so that the webpage can stay synchronized with its status. The following events are currently supported:\nTable 4. Supported DOM events Event Description beforecn1init Fired before the init() method is run. aftercn1init Fired after the init() method is run. beforecn1start Fired before the start() method is run. aftercn1start Fired after the start() method is run. NOTE: Currently The stop() and destroy() lifecycle methods are not used in the Javascript port, as there doesn’t seem to be a logical place to fire them. This may change in the future.\nIn addition to these DOM events, you can also check window.cn1Initialized and window.cn1Started for true to see if the init() and start() methods have already run.\nDeploying as a \u0026ldquo;Headless\u0026rdquo; Javascript App Problem You want to deploy your app inside a webpage \u0026ldquo;headlessly\u0026rdquo;. i.e. You don’t want the user to see the app. This might be useful if you just want to use your app as a javascript library.\nSolution Embed the app inside a 1-pixel iframe.\n... .. Rest of webpage.. NOTE: By trial and error, we have determined that displaying the iframe with 1px width and height is the best solution. Using display:none causes the browser to not load the iframe at all. Positioning the iframe outside the viewport, causes some APIs to be turned off (e.g. microphone).\nDiscussion If you are deploying your app as a headless app, then you are likely expecting to be able to communicate between the webpage and your app. You will also need to be notified of lifecycle events in your app so you know when it has finished loading. Be aware of CORS (cross-origin-resource-sharing) browser policies if the page containing the \u0026lt;iframe\u0026gt; is loaded from a different domain than your app.\nCORS Checklist If the app (inside the iframe) is hosted at a different domain than the parent page (the page with the \u0026lt;iframe\u0026gt; tag), then you need to jump through some hoops to get things working.\nMake sure that you are not sending the X-Frame-Options response header with your app. This header prevents your page from being displayed inside an iframe. Many web hosts add this header automatically.\nIf you want to use features like \u0026ldquo;camera\u0026rdquo; and \u0026ldquo;microphone\u0026rdquo;, you’ll need to add the \u0026ldquo;allow\u0026rdquo; attribute to your iframe tag. e.g. \u0026lt;iframe allow=\u0026ldquo;camera;microphone\u0026rdquo; …​/\u0026gt;. For more information about this attribute, see This article.\nIf you need to communicate between the parent window and the iframe document (i.e. the window with your app, you’ll need to use Window.postMessage(). You can access the iframe’s \u0026ldquo;window\u0026rdquo; object using myIframe.contentWindow.\nPlaying Audio in a Headless App Problem In some cases Codename One apps may be deployed as \u0026ldquo;headless\u0026rdquo; apps. This can be achieved by simply embedding the app inside an iframe and positioning the iframe outside the main view port (e.g. x=-1000, y=-1000). If you are deploying the app this way, you may run into cases where the app requires user interaction. For example, if you try to play audio in the app, and you are running on iOS, then the app may require some user interaction in order for Safari to allow the audio. Codename One apps deal with this situation by prompting the user to play the audio. However, if the app is off screen, the user won’t see this prompt, so the audio will just not play.\nNOTE: The user will only be prompted for the first audio clip that the app tries to play. Subsequent clips can be played unimpeded.\nSolution Codename One broadcasts a custom DOM event named \u0026ldquo;cn1userprompt\u0026rdquo; when a prompt is displayed that the user needs to interact with. You can register an event listener in the outside webpage to listen for this event, and display the iframe in such cases.\nThe \u0026ldquo;cn1userpromptresponse\u0026rdquo; custom DOM event will be dispatched after the user has finished the interaction.\nmyIframe.contentWindow.addEventListener(\u0026#39;cn1userprompt\u0026#39;, function(evt) { // The app requires user interaction.. display the iframe }); myIframe.contentWindow.addEventListener(\u0026#39;cn1userpromptresponse\u0026#39;, function(evt) { // The user has finished their interaction... you can hide the iframe }); Displaying Custom Prompt to Play Audio Background On some browsers (e.g. Safari), your app can only play audio as a direct response to user interaction. e.g. The user needs to actually click on the screen to initiate audio play. This is only required for the first audio clip that your app plays. If the app is ever denied permission to play an audio clip by the browser, it will display a prompt to the user saying \u0026ldquo;Audio Ready\u0026rdquo;, with a \u0026ldquo;Play Now\u0026rdquo; button. When the user presses that button, the audio will begin to play.\nProblem You want to customize the dialog prompt that is displayed to ask the user for permission to play audio.\nSolution Register a message listener using CN.addMessageListener(), and call isPromptForAudioPlayer() on the received MessageEvent object to see if it is a prompt to play audio.\nIf isPromptForAudioPlayer() returns true, then you can consume() the event to signal that you’ll be displaying a custom dialog, and then you can display your own dialog as shown in the example below.\nWhen the user has accepted or rejected the permission prompt, you must call the complete() method on the promise that you obtain using the getPromptPromise() method.\ncomplete(true) indicates that the user decided to play the audio. complete(false) indicates that the user decided not to play the audio.\nExample: CN.addMessageListener(evt-\u0026gt;{ if (evt.isPromptForAudioPlayer()) { (1) System.out.println(\u0026#34;Received a prompt for the audio player... audio is ready\u0026#34;); // This is a prompt that is shown when there is audio ready to play // but the user needs to interact. This is javascript-only to get around // restrictions that only allow audio in direct response to user interaction // We should display some kind of UI to let the user know that the audio is ready // and they need to press a button to play it. evt.consume(); (2) CN.callSerially(()-\u0026gt; { (3) MessageEvent.PromptPromise res = evt.getPromptPromise(); (4) if (Dialog.show(\u0026#34;Audio Ready\u0026#34;, \u0026#34;The audio is ready.\u0026#34;, \u0026#34;Play\u0026#34;, \u0026#34;Cancel\u0026#34;)) { res.complete(true); (5) } else { res.complete(false); (6) } return; }); return; } }); isPromptForAudioPlayer() tells us that this event is a prompt to play audio.\nImportant: You must call evt.consume() to let Codename One know that you are going to handle this prompt. Otherwise, the default permission prompt will still be shown.\nBecause we are using a modal dialog which will block the event dispatch, we wrap the dialog in callSerially() so this event dispatch won’t be blocked. This is not absolutely necessary, but it will make it easier to follow the app’s logic, as these prompts are designed to by asynchronous.\nObtain the PromptPromise from the event which we will use to convey the user’s response back to the app. YOU MUST call the complete() on this promise no matter what, or the app will lock up.\nIf the user elected to \u0026ldquo;Play\u0026rdquo; the audio, then call res.complete(true) on the promise.\nIf the user elected not to play the audio, then call res.complete(false) on the promise.\nTIP: You can also use the isPromptForAudioRecorder() method to detect a request for the audio recorder prompt.\nDiscussion In this example we used a modal dialog to prompt the user, but you can use any UI mechanism you like for prompting the user. A Sheet, an interaction dialog, or a separate Form. You just need to remember to call complete() on the promise after the user has made their choice. If you forget to call complete() it could lock up the app.\nImportant Calling complete(true) directly without actually displaying a dialog to the user won’t work. It is the \u0026ldquo;click\u0026rdquo; that satisfies the browsers \u0026ldquo;media engagement index\u0026rdquo; restrictions so that it will allow the app to play audio. The user can click anywhere in the app; but they need to click. If you call complete(true) without the user clicking, then the app will try to play the audio and just fail.\nFurther Reading: Chrome Autoplay Policy (2017-09) Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nFrancesco Galgani — June 6, 2021 at 1:03 pm (permalink) Francesco Galgani says:\nThis is just a theoretical curiosity of mine: in which real use cases could a Codename One project like «\u0026ldquo;Headless\u0026rdquo; Javascript App» be useful? Could you give some concrete examples?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tips-for-the-javascript-port-of-codename-one-apps/","summary":"\u003cp\u003eThis blog post contain tips for working with the Javascript port of Codename One apps.\u003c/p\u003e\n\u003ch3 id=\"sending-messages-to-outside-webpage\"\u003eSending Messages to Outside Webpage\u003c/h3\u003e\n\u003ch2 id=\"problem\"\u003eProblem\u003c/h2\u003e\n\u003cp\u003eYou want to send a message from your Codename One app to the webpage that contains it.\u003c/p\u003e\n\u003ch2 id=\"solution\"\u003eSolution\u003c/h2\u003e\n\u003cp\u003eYou can use \u003ccode\u003eCN.postMessage()\u003c/code\u003e, in Codename One to send the message. The message will be dispatched to Javascript event listeners in the outside webpage that register to receive cn1outbox events.\u003c/p\u003e\n\u003ch2 id=\"sending-a-message-from-codename-one-to-the-outside-webpage\"\u003eSending a message from Codename One to the outside webpage:\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-java\" data-lang=\"java\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\t\t\t\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\t\t\t\t\u003cspan style=\"color:#75715e\"\u003e// The Java side\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eMessageEvent message \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003enew\u003c/span\u003e MessageEvent(\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#66d9ef\"\u003enull\u003c/span\u003e,        \u003cspan style=\"color:#75715e\"\u003e// event source... we\u0026#39;ll leave it null\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;Hello\u0026#34;\u003c/span\u003e,     \u003cspan style=\"color:#75715e\"\u003e// The message to deliver\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    0            \u003cspan style=\"color:#75715e\"\u003e// Optional message code.\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e);\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e//Dispatch the message\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eCN.\u003cspan style=\"color:#a6e22e\"\u003epostMessage\u003c/span\u003e(message);\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\t\t\t\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\t\t\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"receiving-messages-from-codename-one-in-outside-webpage\"\u003eReceiving messages from Codename One in outside webpage:\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\t\t\t\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\t\t\t\t\u003cspan style=\"color:#75715e\"\u003e// The javascript side\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ewindow.\u003cspan style=\"color:#a6e22e\"\u003eaddEventListener\u003c/span\u003e(\u003cspan style=\"color:#e6db74\"\u003e\u0026#39;cn1outbox\u0026#39;\u003c/span\u003e, \u003cspan style=\"color:#66d9ef\"\u003efunction\u003c/span\u003e(\u003cspan style=\"color:#a6e22e\"\u003eevt\u003c/span\u003e) {\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#66d9ef\"\u003evar\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003emessage\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eevt\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003edetail\u003c/span\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#66d9ef\"\u003evar\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003ecode\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eevt\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003ecode\u003c/span\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    ...\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e});\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\t\t\t\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\t\t\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"discussion\"\u003eDiscussion\u003c/h2\u003e\n\u003cp\u003eThe \u003ccode\u003eCN.postMessage()\u003c/code\u003e method allows you to send a message to the native platform. When deploying as a Javascript app, these messages are converted to custom DOM events and dispatched on the window object. The event name is \u0026ldquo;cn1outbox\u0026rdquo;, so you can receive events like this from the \u0026ldquo;javascript\u0026rdquo; side by registering an event listener for these types of events on the window object.\u003c/p\u003e","title":"Tips for the Javascript port of Codename One apps"},{"content":"The following recipes relate to security of Codename One apps. This includes detecting Jailbroken or Rooted device and hiding sensitive data when entering background.\nThe following recipes include tips on making your Codename One apps more secure.\nDetecting Jailbroken/Rooted Device Problem You want to detect whether the device your app is running on is Jailbroken or Rooted.\nSolution While there is no way to know whether the device is rooted with 100% certainty, you can use the CN1JailbreakDetect cn1lib to to make a good guess.\nThis cn1lib acts as a thin wrapper around the RootBeer Android library, and DTTJailbreakDetection iOS library, which employ heuristics to determine whether the device has likely been jailbroken.\nExample package com.codename1.samples; import com.codename1.ext.jailbreak.JailbreakDetect; import static com.codename1.ui.CN.*; import com.codename1.ui.Display; import com.codename1.ui.Form; import com.codename1.ui.Dialog; import com.codename1.ui.Label; import com.codename1.ui.plaf.UIManager; import com.codename1.ui.util.Resources; import com.codename1.io.Log; import com.codename1.ui.Toolbar; import java.io.IOException; import com.codename1.ui.layouts.BoxLayout; import com.codename1.io.NetworkEvent; import com.codename1.ui.Button; import com.codename1.ui.Command; public class JailbreakDetectionSample { private Form current; private Resources theme; public void init(Object context) { // use two network threads instead of one updateNetworkThreadCount(2); theme = UIManager.initFirstTheme(\u0026#34;/theme\u0026#34;); // Enable Toolbar on all Forms by default Toolbar.setGlobalToolbar(true); // Pro only feature Log.bindCrashProtection(true); addNetworkErrorListener(err -\u0026gt; { // prevent the event from propagating err.consume(); if(err.getError() != null) { Log.e(err.getError()); } Log.sendLogAsync(); Dialog.show(\u0026#34;Connection Error\u0026#34;, \u0026#34;There was a networking error in the connection to \u0026#34; + err.getConnectionRequest().getUrl(), \u0026#34;OK\u0026#34;, null); }); } public void start() { if(current != null){ current.show(); return; } Form hi = new Form(\u0026#34;Jailbreak Detection\u0026#34;, BoxLayout.y()); Button detect = new Button(\u0026#34;Detect Jailbreak\u0026#34;); detect.addActionListener(evt-\u0026gt;{ if (JailbreakDetect.isJailbreakDetectionSupported()) { if (JailbreakDetect.isJailbroken()) { Dialog.show(\u0026#34;Jailbroken\u0026#34;,\u0026#34;This device is jailbroken\u0026#34;, new Command(\u0026#34;OK\u0026#34;) ); } else { Dialog.show(\u0026#34;Not Jailbroken\u0026#34;, \u0026#34;Probably not jailbroken. But can\u0026#39;t be 100% sure.\u0026#34;, new Command(\u0026#34;OK\u0026#34;)); } } else { Dialog.show(\u0026#34;No Idea\u0026#34;, \u0026#34;No support for jailbreak detection on this device.\u0026#34;, new Command(\u0026#34;OK\u0026#34;)); } }); hi.add(detect); hi.show(); } public void stop() { current = getCurrentForm(); if(current instanceof Dialog) { ((Dialog)current).dispose(); current = getCurrentForm(); } } public void destroy() { } } Tip: This sample is part of the Codename One samples project, and can be run directly from the Codename One SampleRunner.\nDiscussion The CN1JailbreakDetect provides two useful static methods for jailbreak detection:\nisJailbreakDetectionSupported() – This checks if the jailbreak detection is even supported on this platform.\nisJailBroken() – This checks if the device is jailbroken. If detection is not supported, then this will always return false.\nCurrently jailbreak detection is only supported on Android and iOS.\nImportant: There is NO way to know with 100% certainty whether or not a device has been jailbroken.\nFurther Reading CN1JailbreakDetect github project RootBeer project (Used on Android) DTTJailbreakDetection project (Used on iOS) Hiding Sensitive Data When Entering Background Problem iOS will take a screenshot of your app when it enters the background that it uses for various previews of the app state. You want to hide sensitive data in your app’s UI to prevent this information from leaking out via these screenshots.\nSolution You can use the ios.blockScreenshotsOnEnterBackground=true build hint to prevent iOS from taking screenshots app goes into the background. This will cause the canvas on which the Codename One UI is drawn to be hidden in the didEnterBackground hook and unhidden in the willEnterForeground hook.\nWarning: This will cause your app to appear as a blank white rectangle when the user is browsing through opened apps.\nFigure 1. Notice the app in the middle is blank white because it has been set to block iOS screenshots.\nDiscussion You might have been tempted to try to modify the UI inside the stop() lifecycle method of your app, since it is called itself by the didEnterBackground hook.\nThis strategy will work in some platforms, but not on iOS because the screenshot call is made immediately upon the didEnterBackground method returning – and the stop() method runs on the EDT (a different thread), so this is not possible. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nJavier Anton — May 24, 2021 at 11:06 am (permalink) Javier Anton says:\nVery useful. There are lots of rooted users that hack in-app purchases and get things for free. I wonder how effective RootBeer is, I know there are tools available to hide the root at the moment\nJavier Anton — May 24, 2021 at 12:30 pm (permalink) Javier Anton says:\nJust looked at the RootBeer code and it looks great. It even checks natively in cpp, which I read was the safest way to bypass root masks\nJavier Anton — May 24, 2021 at 12:45 pm (permalink) Javier Anton says:\nIs there any reason RootBeer version 0.0.8 is used and not 0.0.9?\nJavier Anton — May 24, 2021 at 2:49 pm (permalink) Javier Anton says:\nNevermind, I just added the native bits myself. Wish I could delete/edit my posts on here, maybe that could be enabled at some point\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/how-to-detect-jailbroken-or-rooted-device-and-hide-sensitive-data-in-background/","summary":"\u003cp\u003eThe following recipes relate to security of Codename One apps. This includes detecting Jailbroken or Rooted device and hiding sensitive data when entering background.\u003c/p\u003e\n\u003cp\u003eThe following recipes include tips on making your Codename One apps more secure.\u003c/p\u003e\n\u003ch3 id=\"detecting-jailbrokenrooted-device\"\u003eDetecting Jailbroken/Rooted Device\u003c/h3\u003e\n\u003ch2 id=\"problem\"\u003eProblem\u003c/h2\u003e\n\u003cp\u003eYou want to detect whether the device your app is running on is Jailbroken or Rooted.\u003c/p\u003e\n\u003ch2 id=\"solution\"\u003eSolution\u003c/h2\u003e\n\u003cp\u003eWhile there is no way to know whether the device is rooted with 100% certainty, you can use the \u003ca href=\"https://github.com/shannah/CN1JailbreakDetect\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCN1JailbreakDetect\u003c/a\u003e cn1lib to to make a good guess.\u003c/p\u003e","title":"How to detect Jailbroken or Rooted device and hide sensitive data in background?"},{"content":"We have added Android App Bundle support which will become the required format for submitting apps to Google Play.\nA few months ago, we added Android App Bundle support and forgot to tell anyone\u0026hellip; These things sometimes happen in a fast-moving startup… Well, better late than never.\nTo try the App Bundle support, use the build hint: android.appBundle=true\nThis will produce the regular APK and the app bundle file which you should be able to upload to Google.\nWhat is Android App Bundle? For those who aren’t aware… Android App bundle is a new format designed by Google to replace the venerable APK.\nIt isn’t much different but is generally better suited for splitting so different versions can be sent to different devices more easily.\nThis makes sense for very fat applications, not so much for Codename One apps which are usually leaner than native Android apps.\nIn August, Android App Bundle will become the required format for submitting to Google Play. In a couple of weeks we will flip the default so the app bundle build hint will be true implicitly. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nFrancesco Galgani — June 6, 2021 at 12:57 pm (permalink) Francesco Galgani says:\nSince the aab format is not installable on an Android smartphone but can only be used to publish in the store, you will always continue to provide the apk format, right?\nShai Almog — June 6, 2021 at 2:01 pm (permalink) Shai Almog says:\nI won’t say \u0026ldquo;always\u0026rdquo; since things change but as long as AAB isn’t installable you will need an APK and we’ll provide it.\nChris Vorster — September 11, 2021 at 12:56 am (permalink) Chris Vorster says:\nTrying to upload a new version of the AAB on Google Dev Console results in signing error. Cannot find a way to fix this, tried support also.\n\u0026ldquo;Your Android App Bundle is signed with the wrong key. Ensure that your App Bundle is signed with the correct signing key and try again. Your App Bundle is expected to be signed with the certificate with fingerprint:…\u0026rdquo;\nCan’t seem to find any solutions on how to deal with this.\nLianna Casper — September 11, 2021 at 4:12 am (permalink) Lianna Casper says:\nYou need to pick the right keystore in Codename One Settings. How did you sign the app you first uploaded?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/android-app-bundle-support/","summary":"\u003cp\u003eWe have added Android App Bundle support which will become the required format for submitting apps to Google Play.\u003c/p\u003e\n\u003cp\u003eA few months ago, we added Android App Bundle support and forgot to tell anyone\u0026hellip; These things sometimes happen in a fast-moving startup… Well, better late than never.\u003c/p\u003e\n\u003cp\u003eTo try the App Bundle support, use the build hint: \u003ccode\u003eandroid.appBundle=true\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003eThis will produce the regular APK and the app bundle file which you should be able to upload to Google.\u003c/p\u003e","title":"Android App Bundle Support"},{"content":"Apple updated their requirements for App Store submissions so new apps must be built with Xcode 12. As a result we’ve updated our build servers to the latest Xcode 12.4 release.\nThis isn’t on by default yet so if you need it this week you’ll need to use the build hint: ios.xcode_version=12.4\nAfter the weekend this will be the default so if you don’t need to submit a build to Apple this week you can just ignore this.\nIf this will trigger a regression in your code (possible if you have a native dependency) you can temporarily workaround it by using the build hint: ios.xcode_version=11.3\nNote Older versions are no longer supported and were removed from our servers.\nArchived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nJulio Valeriron Ochoa — October 7, 2021 at 1:28 pm (permalink) Julio Valeriron Ochoa says:\nI thing that you must start to migrate to xcode 13 to compile app to IOS 15.https://github.com/codenameone/CodenameOne/issues/3510\nShai Almog — October 7, 2021 at 1:35 pm (permalink) Shai Almog says:\nThe build hint in the issue resolves that problem\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/moving-to-xcode-12/","summary":"\u003cp\u003eApple updated their requirements for App Store submissions so new apps must be built with Xcode 12. As a result we’ve updated our build servers to the latest Xcode 12.4 release.\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://www.codenameone.com/wp-content/uploads/2021/04/Moving-to-Xcode-12.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis isn’t on by default yet so if you need it this week you’ll need to use the build hint: ios.xcode_version=12.4\u003c/p\u003e\n\u003cp\u003eAfter the weekend this will be the default so if you don’t need to submit a build to Apple this week you can just ignore this.\u003c/p\u003e","title":"Moving to Xcode 12"},{"content":"Learn how to build Codename One from source and use this \u0026ldquo;local\u0026rdquo; version in your Codename One projects.\nTip This post is targeted at experienced Codename One users. If you haven’t built an app with Codename One before, I recommend you start with this Getting Started tutorial (for Java) or this tutorial (for Kotlin).\nOne of the benefits of moving to Maven is improved project hygiene. It is now trivial to build Codename One from source.\nIn this video, I show you how to build Codename One from source and use this \u0026ldquo;local\u0026rdquo; version in your Codename One projects.\nTLDW (Too Long Didn’t Watch) Here’s the gist of what happens in the video.\nClone the Codename One repository, then run mvn install in the maven subdirectory: git clone https://github.com/codenameone/CodenameOne cd CodenameOne/maven mvn install\tThis will take a few minutes, but at the end of the tunnel you should see \u0026ldquo;SUCCESS\u0026rdquo; as shown below:\nNOTE: Due to wordpress issues the images in this blogpost were lost.\nClone the cn1-maven-archetypes repository, then run mvn install in its root directory: git clone https://github.com/shannah/cn1-maven-archetypes cd cn1-maven-archetypes mvn install\tThis will take another minute or so, but at the end of the tunnel you should see \u0026ldquo;SUCCESS\u0026rdquo;:\n\u0026hellip;\nAfter completing these steps, Codename One will be installed in the local maven repository. A key point I make in this video is the version number of the sources that I checked out of Github. If you are cloning the project from the master branch, then the version will usually be a SNAPSHOT version. E.g. 7.0.21-SNAPSHOT. This is a Maven convention. Release versions will not have the -SNAPSHOT suffix.\nIn the video, you can see that the version number is \u0026ldquo;7.0.21-SNAPSHOT\u0026rdquo;.\nUsing the Local Version in Your Application Project Now that Codename One is installed in your local Maven repo, you can use that version in your application instead of the release version.\nI demonstrate this in the video by creating a new project with the Codename One initializr.\n\u0026hellip;\nTip Check out my Video tutorial on Codename One initializr if you haven’t seen it yet.\nAfter downloading and extracting the project, I open its pom.xml file and and look for the \u0026lt;cn1.version\u0026gt; and \u0026lt;cn1.plugin.version\u0026gt; properties:\n\u0026hellip;\nI then change these to point to the version that I installed into my local maven repository: 7.0.21-SNAPSHOT.\n\u0026hellip;\nWhy Build From Source? Because you can, and because it is the first step toward taking control of your own destiny. It gives you early access to features that may not be available on Maven Central, and it also enables you to make your own changes, and potentially contribute them to the Codename One core.\nGetting Started If you haven’t built an app yet, it’s easy to get started. Just go to Codename One initializr and press \u0026ldquo;Download\u0026rdquo;. You could be up and running in only a few minutes.\nIf you want to dig deeper into Codename One’s Maven support, check out the Codename One Maven Developers Guide. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nDave Dyer — July 20, 2023 at 10:07 pm (permalink) Dave Dyer says:\nsomething is out of date. in codenameone\\maven, mvn install\n[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project\njava-runtime: Compilation failure: Compilation failure:\n[ERROR] Source option 5 is no longer supported. Use 7 or later.\nDave Dyer — July 21, 2023 at 7:35 pm (permalink) Dave Dyer says:\nThis is somehow related to the java version in use. I fixed this by\ndowngrading my default java from java-16 to and older jdk, jdk-1.8\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/building-codename-one-from-source-maven-edition/","summary":"\u003cp\u003eLearn how to build Codename One from source and use this \u0026ldquo;local\u0026rdquo; version in your Codename One projects.\u003c/p\u003e\n\u003ch2 id=\"tip\"\u003eTip\u003c/h2\u003e\n\u003cblockquote\u003e\n\u003cp\u003eThis post is targeted at experienced Codename One users. If you haven’t built an app with Codename One before, I recommend you start with this \u003ca href=\"https://shannah.github.io/cn1-maven-archetypes/cn1app-archetype-tutorial/getting-started.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGetting Started tutorial\u003c/a\u003e (for Java) or \u003ca href=\"https://shannah.github.io/cn1app-archetype-kotlin-template/getting-started.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ethis tutorial\u003c/a\u003e (for Kotlin).\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eOne of the benefits of \u003ca href=\"/blog/moving-to-maven/\"\u003emoving to Maven\u003c/a\u003e is improved project hygiene. It is now trivial to build Codename One from source.\u003c/p\u003e","title":"Building Codename One From Source – Maven Edition"},{"content":"One of the cool things about Maven is Maven Central - the repository that contains every version of every Java library (that has been published on Maven central at least). Once your library is published, it can be used by other projects by copying and pasting an XML snippet into their pom.xml file. In this article, I describe how to publish your Codename One libraries to Maven central so that app developers can use them in their projects.\nThe Old Way Up until now, Codename One library projects were distributed as .cn1lib files, which app developers could add to their projects either manually (by copying the .cn1lib file into their project’s lib directory), or via Codename One Settings, which would automate the download of the cnl1ibs off of GitHub.\nIf you had developed a .cn1lib and wanted to add it to the Extensions directory of Codename One Settings, you would fork the CodenameOneLibs repository, add your cn1lib to the cn1libs directory, add a corresponding entry into the CN1Libs.xml file, and then submit a pull request.\nThis process works fine, but has some limitations. Publishing your library to Maven central, won’t replace this process, but it will provide a robust alternative method of deployment that may be preferable to some users.\nThe New Way Using the Codename One Library project archetype, you can deploy your library to Maven central and build a .cn1lib file which can be deployed manually. The process for adding your library to Codename One Settings is unchanged, except that you can now include a Maven dependency snippet in your entry in the CN1Libs.xml file. See the entry for the GoogleMaps library as an example:\nCodename One Google Native Maps Support Allows Codename One developers to embed native Google Maps on iOS, Android, and Javascript. Uses Google maps in BrowserComponent on simulator and falls back to Codename One\\n MapComponent on UWP. https://github.com/codenameone/codenameone-google-maps 44 Apache 2.0 utilities,maps iOS, Android, Javascript CodenameOne com.codenameone googlemaps-lib 1.0.1 pom Notice the \u0026lt;maven\u0026gt; tag which contains the XML dependency snippet that can be added to a project’s pom.xml file. If a user chooses to install the GoogleMaps lib from inside Codename One Settings in a Maven project, it will add the library using this Maven dependency. If the project is an Ant project, it will, instead fall back to the old way (downloading the cn1lib to the project’s lib directory).\nCurrently there are still many libraries that aren’t on Maven central. These libraries can still be used by Maven projects. You are using Codename One Settings to install the library, then the process is seamless. If want to install the cn1lib \u0026ldquo;manually\u0026rdquo;, you can use the install-cn1lib Maven goal.\nGetting Started Getting started building Codename One libraries is quite easy. You can start a new library project using the cn1lib-archetype as described in in the Codename One Maven Developer’s guide chapter on Creating a Library Project.\nPreparing the Project for Maven Central Maven Central is quite strict about the content of your project’s pom.xml file. It must contain , , and sections. These sections may not be part of your project initially. You’ll need to add them. Use the pom.xml file for the GoogleMaps cn1lib project as a reference to see how and where these tags should be added.\nThese are the values as they appear in that file:\nThe \u0026lt;licenses\u0026gt;, \u0026lt;developers\u0026gt;, and \u0026lt;scm\u0026gt; sections of your pom.xml file are required. This is a sample adapted from the GoogleMaps lib.\nGPL v2 With Classpath Exception https://openjdk.java.net/legal/gplv2+ce.html repo A business-friendly OSS license jsmith John Smith jsmith@example.com +4 https://github.com/codenameone/codenameone-google-maps scm:git:git@github.com:codenameone/codenameone-google-maps.git In addition, Maven central requires that your project deploys javadoc and source jars. You’ll need to add the maven-javadoc-plugin and maven-source-plugin to the section of the pom.xml file.\nHere is a snippet from the GoogleMaps lib that can be more-or-less just copied and pasted into your pom.xml file.\nIncluding the javadoc and sources plugins as required by Maven Central.\norg.apache.maven.plugins maven-javadoc-plugin 3.0.1 build-javadoc jar post-integration-test true 1.8 protected false org.apache.maven.plugins maven-source-plugin attach-sources jar Request Access to Maven Central If this is your first time publishing on Maven Central, you’ll need to on create an account on Sonatype JIRA, then create a new issue.\nYou can check out the issue I filed to request access for Codename One as a sample here.\nSigning Artifacts with GPG Maven Central also requires that you sign all of your artifacts using GPG, so you’ll need to install GPG.\nIf this is your first Rodeo, you may need to create and publicize your GPG key.\nGenerating a GPG Key The following is an example readout for generating a keypair with gpg.\n$ gpg --full-gen-key gpg (GnuPG) 2.1.15; Copyright (C) 2016 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. gpg: keybox \u0026#39;/path/to/gnupg/pubring.kbx\u0026#39; created Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 1 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) Requested keysize is 2048 bits Please specify how long the key should be valid. 0 = key does not expire = key expires in n days w = key expires in n weeks m = key expires in n months y = key expires in n years Key is valid for? (0) Key does not expire at all Is this correct? (y/N) y GnuPG needs to construct a user ID to identify your key. Real name: John Smith Email address: jsmith@example.com Comment: You selected this USER-ID: \u0026#34;John Smith \u0026#34; Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. gpg: /path/to/gnupg/trustdb.gpg: trustdb created gpg: key 27835B3BD2A2061F marked as ultimately trusted gpg: directory \u0026#39;/path/to/gnupg/openpgp-revocs.d\u0026#39; created gpg: revocation certificate stored as \u0026#39;/path/to/gnupg/openpgp-revocs.d\\5694AA563793429557F1727835B3BD2A223A.rev\u0026#39; public and secret key created and signed. pub rsa2048 2016-08-29 [SC] 5694AA563793429557F1727835B3BD2A223A uid John Smith sub rsa2048 2016-08-29 [E] $ You may also need to manage the expiration dates of your keys.\nYou’ll also need to distribute your public key to a few keyservers.\nThis is a short list of key servers you should send your key to:\nhkp://pool.sks-keyservers.net https://pgp.key-server.io/ https://keyserver.ubuntu.com/ https://pgp.mit.edu/ http://keys.gnupg.net/ Importnat: Remember your GPG Passphrase!\nAnd now that you have GPG installed and set up, you should add section to your pom.xml to enable the signing of artifacts.\nA snippet from the GoogleMaps lib pom.xml file that enables signing artifacts using GPG.\nsign-artifacts org.apache.maven.plugins maven-gpg-plugin 1.4 sign-artifacts verify sign ${gpg.passphrase} This snippet defines a maven profile that will cause GPG to sign all artifacts in the project during the \u0026ldquo;verify\u0026rdquo; phase, which is run any time you execute the verify, package, install, or deploy goals. You can activate this profile by adding -Psign-artifacts to Maven’s command-line arguments. e.g. mvn deploy -Psign-artifacts.\nBut we’re not quite ready yet. There are still a couple more ducks we need to line up.\nYou’ll notice that the above XML snippet references the ${gpg.passphrase} property, which we haven’t yet defined. We don’t want to store the GPG passphrase inside the pom.xml file since this is a secret, and your pom.xml file should be considered public. This is where our maven settings.xml file comes in.\nOpen your settings.xml file (located at $HOME/.m2/settings.xml). If you don’t have one, then create it. The settings file should look like:\nxml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34;? ... sign-artifacts true YOUR_PASSPHRASE Make sure your file includes the \u0026lt;profiles\u0026gt; snippet shown above. This defines the gpg.passphrase property so that it will be present for your Maven builds.\nImportnat: Substitute your passphrase for the YOUR_PASSPHRASE text.\nAdding Distribution Management Settings There is one last thing we need to do before we can publish our project to Maven Central. We need to add a \u0026lt;distributionManagement\u0026gt; section to our pom.xml file with a \u0026lt;repository\u0026gt; entry pointing to the Sonatype staging repository.\nThis section should be as follows:\nnexus-staging Nexus Release Repository https://oss.sonatype.org/service/local/staging/deploy/maven2/ And finally we need to add a \u0026lt;server\u0026gt; tag to our settings.xml file that includes your sonatype username and password (that you obtained a few steps back when you created a Sonatype JIRA account).\ne.g.\nnexus-staging YOUR_USERNAME YOUR_PASSWORD Deploying a Release to Maven Central Deploying a release requires a few steps.\nUpdate the project version to a release version. Deploy The Project Close the Staging Repository Release the Staging Repository Update the project version to a new Snapshot version. Updating the Project Version to a Release Version When you are developing a project, it will usually have a SNAPSHOT version, meaning that the \u0026lt;version\u0026gt; tag in the project ends with \u0026ldquo;-SNAPSHOT\u0026rdquo;. When you perform a release, you should change the version to a release version. Basically this means simply removing the \u0026ldquo;-SNAPSHOT\u0026rdquo; from the end of the version number.\nSince this is a multi-module Maven project, the version hard-coded into each module, so updating the version by hand is both tedious and error-prone. Luckily Maven can automate this process for us.\nEnter the following at the command prompt:\nmvn versions:set -DnewVersion=YOUR_NEW_VERSION Where YOUR_NEW_VERSION is the new version you want to set in your app. e.g.\nmvn versions:set -DnewVersion=1.0 Then you need to commit this version change by running:\nmvn versions:commit At this point, if you look at your pom.xml files, you’ll notice that the \u0026lt;version\u0026gt; tag has been changed to \u0026ldquo;1.0\u0026rdquo;.\nDeploying the Project To deploy the project to Maven central, now we run:\nmvn deploy -Psign-artifacts Note: If this is your first time around, expect this to error out. You may need to add the -e or -X flags to add more verbose logging to Maven so you can track down the problems. If you do experience build errors, they will likely be related to the GPG signing step, and are probably caused by a typo in the password or configuration for GPG.\nClosing the Repository If the deployment completes successfully, you should log into the nexus repository manager. It will look something like the following image:\nYour repository should be listed in the main frame. You should be able to browse the contents of it in the south frame. If it looks good, click on the \u0026ldquo;Close\u0026rdquo; button on the toolbar (with your repository selected). This will start a validation process on the server that will take a minute or so.\nReleasing the Repository Click refresh after a minute or two. If the \u0026ldquo;Close\u0026rdquo; action was successful, the \u0026ldquo;Release\u0026rdquo; button should be enabled.\nClick \u0026ldquo;Release\u0026rdquo; to release your library.\nIt typically takes a few hours before your new version is available on Maven central. You can check on https://search.maven.org/ to see if it is listed.\nUpdating Project Version to Snapshot Version One last thing remains before we can hang up our hat. We need to set the project version to a new snapshot version.\nUsually, before I do that, I’ll commit and tag my \u0026ldquo;release\u0026rdquo; version in git.\ngit commit -a -m \u0026#34;v1.0\u0026#34; git tags -a \u0026#34;v1.0\u0026#34; -m \u0026#34;Version 1.0\u0026#34; Then I’ll update the versions:\nmvn versions:set -DnewVersion=1.0.1-SNAPSHOT mvn versions:commit And then I’ll commit this change in git too.\ngit commit -a -m \u0026#34;Bumped version to 1.0.1-SNAPSHOT\u0026#34; Adding Library to Codename One Libs If you want other Codename One developers to find your library, I also recommend adding it to the CodenameOneLibs repository so that it will be listed in CodenameOne Settings when users are looking for available plugins. The process for this is quite simple.\nFork the CodenameOneLibs repository. Add your .cn1lib file to the cn1libs directory. After running mvn deploy on your project, you’ll find that a .cn1lib has been built in your library project’s common/target directory. Copy this file into the cn1libs directory of the CodenameOneLibs project. Add a \u0026lt;plugin\u0026gt; entry in the CN1Libs.xml file. Use the GoogleMaps entry as a reference. Commit your change and send a pull request. Summary This may look like an over complicated process, but most of heavy lifting is a one-time thing – setting up Sonatype access, generating certificates, etc…​ Subsequent releases will become much easier, and, the work will be worth it.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/publishing-codename-one-libraries-on-maven-central/","summary":"\u003cp\u003eOne of the cool things about Maven is Maven Central - the repository that contains every version of every Java library (that has been published on Maven central at least). Once your library is published, it can be used by other projects by copying and pasting an XML snippet into their \u003ccode\u003epom.xml\u003c/code\u003e file. In this article, I describe how to publish your Codename One libraries to Maven central so that app developers can use them in their projects.\u003c/p\u003e","title":"Publishing Codename One Libraries on Maven Central"},{"content":"As you may know, we are moving to Maven for our build tool. As part of this transition, we are moving towards a single Maven project structure, and away from separate structures for each IDE. This will be easier to maintain, and will also make it easier to collaborate on projects with other developers who use a different IDE (or no IDE at all).\nWe have also introduced a online new tool for creating new app projects called Codename One initializr. Alternatively, you can create new projects using the cn1app-archetype (for App projects), and cn1lib-archetype for library projects.\nThat’s great for new projects. But what about my existing application project? Is there an easy way to convert my old Ant project into a new Maven project?\nYes there is! We have just released a new Maven migration tool that makes migrating your old projects to Maven as simple as clicking a couple of buttons.\nThe following 5-minute video shows you how to use this tool to convert your existing application projects (beginning at approx 1:37) and library projects (beginning at approx 3:48).\nTLDW (Too Long Didn’t Watch) I begin the video by downloading the latest release of the Codename One Migration tool. At the time of writing, the latest release is 1.0.1, so I downloaded the file named \u0026ldquo;migrationtool-javase-1.0.1.zip\u0026rdquo; from the \u0026ldquo;Assets\u0026rdquo; for the release:\nNote: The Migration Tool should work on any computer with Java8 or higher installed. I have tested it on Windows, Mac, and Linux. Other than Java, it has no dependencies. It doesn’t require Maven to be installed, as it uses the Maven wrapper to download the correct version of Maven as required.\nAfter downloading and extracting the Zip file, I open the \u0026ldquo;migrationtool-javase-1.0.1.jar\u0026rdquo; file contained inside.\nIf you have Java installed, you should be able to double-click this jar file to open the app.\nTip: On newer versions of Mac OS, you will need to right click on the .jar file and select \u0026ldquo;Open\u0026rdquo; from the context menu.\nIt will pop up a scary dialog saying that the app is from an unidentified developer.\nPress the \u0026ldquo;Open\u0026rdquo; button, and it will open the app. You only need to do this the first time you open the app.\nThe app’s main window looks like the following:\nThe first text field allows you to specify the version of the Codename One plugin that you wish to use to perform the migration. If you leave this field blank or with the special value \u0026ldquo;LATEST\u0026rdquo;, then it will automatically use the latest version from Maven central.\nTip: You can use a snapshot version that you have built yourself also. Just enter the \u0026ldquo;SNAPSHOT\u0026rdquo; version into this field. This requires that you have build and installed the cn1-maven-archetypes and CodenameOne projects into your local Maven repository.\nMigrating the Kitchen Sink App To demonstrate the process for migrating an application project, I download the KitchenSink project from Github.\nI then (at approx 1:45) press the \u0026ldquo;Browse…​\u0026rdquo; button next to the \u0026ldquo;Source Project\u0026rdquo; field.\nAnd select the Kitchen Sink project folder in the file dialog.\nNext, I select the destination directory by pressing the \u0026ldquo;Browse…​\u0026rdquo; button next to the Destination Directory field.\nI select the Downloads directory here for my destination.\nThen I press the Create Project button, to start the migration.\nNote: For application projects you don’t need to enter a groupId or artifactId. It will use the project’s packageName as the groupId, and the mainName as the artifactId.\nThis triggers Maven to run the generate-app-project goal, and you can follow the process in the console at the bottom of the window:\nThis takes a few seconds, and when it is done, it pops up a success dialog:\nWhen you click \u0026ldquo;OK\u0026rdquo;, it will also open the new project directory in the Finder or equivalent.\nWorking with the Project You can open this project in any IDE that is compatible with Maven. I recommend IntelliJ, but Eclipse and NetBeans will work well also. You can also work with it from the command-line.\nFind our more about the project structure, including running, building, and modifying it in this tutorial.\nMigrating the Filechooser Library Project To demonstrate the process for migrating a library project, I download the CN1FileChooser library from Github and try to convert it, at approximately 3:45 of the video.\nI select a new source project by pressing the \u0026ldquo;Browse…​\u0026rdquo; button next to the Source Project field. Then I select the CN1FileChooser library in the dialog:\nNotice, that as soon as we select this project, it reveals a new section on the form to enter maven details:\nIn this example, I entered \u0026ldquo;com.codenameone\u0026rdquo; for groupId and \u0026ldquo;filechooser\u0026rdquo; for artifactId. You would enter values appropriate for your project instead.\nFrom there I press the Create Project button again, and watch the output in the console. When it is finished, it will open my project in the finder window, just as it did for the application project migration.\nSimilar to the application project, you can open this project in any IDE that supports maven. Or you can work with it directly from the command-line.\nThe Old-Fashioned Approach Just in case you’re old-fashioned, and prefer to do things from the command-line, the following sections describe the same process, except using maven directly from the command-line.\nConverting an existing App Project to Maven The Codename One Maven plugin provides a Maven goal that will generate a new app project based on an existing Ant project. Allow me to demonstrate this on the Kitchen Sink app.\nNote: For the purposees of this post, I’m going to use a tag I created for the KitchenSink repository so that the examples here continue to work in the future, even if the KitchenSink app structure is changed.\nDownload the source code for the Kitchen Sink project and extract it. Once extracted you’ll have the project in a directory named \u0026ldquo;KitchenSink-1.0-cn17.0.11\u0026rdquo;\nNow, open a command prompt in the directory containing the KitchenSink project. In the listing below, I’m going to use CN1_VERSION=7.0.19, but you should change this to be the latest version in Maven central.\nCN1_VERSION=7.0.22 mvn com.codenameone:codenameone-maven-plugin:${CN1_VERSION}:generate-app-project \\ -DarchetypeGroupId=com.codenameone \\ -DarchetypeArtifactId=cn1app-archetype \\ -DarchetypeVersion=${CN1_VERSION} \\ -DartifactId=kitchensink \\ -DgroupId=com.example \\ -Dversion=1.0-SNAPSHOT \\ -DinteractiveMode=false \\ -DsourceProject=KitchenSink-1.0-cn7.0.11 Note: This command is formatted for the bash prompt (e.g. Linux or Mac). It will work on Windows also if you use bash. If you are on Windows and are using PowerShell or the regular command prompt, then you’ll need to modiy the command slightly. In particular, the entire command would need to be on a single line. (Remove the \u0026lsquo;' at the end of each line, and merge lines together, with space between the command-line flags)\nThis will generate a new Maven project in a directory named \u0026ldquo;kitchensink\u0026rdquo;, because of the -DartifactId=kitchensink option.\nTip: When converting your own projects, you’ll want to change the -DgroupId, and -DartifactId parameters to suit your needs.\nThat’s all there is to it. From now on, you can work with this new maven project, and ditch the old project.\nFor an introduction to this new project structure, you should start with this tutorial, as it walks you through all of the common tasks (e.g. running, debugging, building, etc..).\nConverting an Existing Library Project to Maven We used the \u0026ldquo;generate-app-project\u0026rdquo; Maven goal to migrate our app project. For a library project, we’ll use the \u0026ldquo;generate-cn1lib-project\u0026rdquo;\nAs an example, I’ll Migrate the CodeRAD library project to Maven.\nNote: For the purposes of this post, I’ll be using a tag of the CodeRAD repo to ensure that these examples continue to work after the master branch is changed.\nDownload the source code for the project and extract it. You should now have the project in a directory named CodeRAD-1.0.\nNow, open a command prompt/terminal window and navigate to the directory containing the CodeRAD-1.0 directory. In the listing below, I’m going to use CN1_VERSION=7.0.19, but you should change this to be the latest version in Maven central.\nCN1_VERSION=7.0.22 mvn com.codenameone:codenameone-maven-plugin:${CN1_VERSION}:generate-cn1lib-project \\ -DartifactId=coderad \\ -DgroupId=com.example \\ -Dversion=1.0-SNAPSHOT \\ -DinteractiveMode=false \\ -Dcn1Version=${CN1_VERSION} \\ -DsourceProject=CodeRAD-1.0 If all went well, it should have created the project in a directory named \u0026ldquo;coderad\u0026rdquo; (because of the -DartifactId=coderad argument).\nTip: When converting your own projects, you’ll want to change the -DgroupId, and -DartifactId parameters to suit your needs.\nThat’s all there is to it. You can start working with the new maven project and ditch the old Ant project. For details on working with this new project structure, see Creating a Library Project from the Codename One Maven Developers Guide. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nDiamond Obama — April 14, 2021 at 4:43 pm (permalink) Diamond Obama says:\nThanks Steve, for making us lazy developers lazier 😉\nThis is a really helpful tool.\nDiamond Obama — April 14, 2021 at 4:58 pm (permalink) Diamond Obama says:\nI’m getting an error when I click the JavaSE jar file on Windows 10 with Java 6,7,8,9,11, and 14.\nJava Virtual Machine Launcher\nCould not find the main class:\ncom.codename1.maven.migrationtool.MigrationToolStub.\nProgram will exit.\nSteve Hannah — April 14, 2021 at 5:01 pm (permalink) Steve Hannah says:\nAre you building from source? (you shouldn’t build from source).\nUse the zip distribution. https://github.com/shannah/maven-migration-tool/releases/download/v1.0.3/migrationtool-javase-1.0.3.zip\nDiamond Obama — April 14, 2021 at 5:41 pm (permalink) Diamond Obama says:\nBoth building from Source and the zipped app produced the same error.\nSteve Hannah — April 14, 2021 at 5:51 pm (permalink) Steve Hannah says:\nI’d like to better understand exactly what you’re doing. I’ve tested on 3 Windows machines now and can’t reproduce.\nAll I can think is that perhaps it is choosing an old version of Java (pre 8) when you open the jar.\nSo the process:\nDownload the zip file. Extract the zip file (i.e. right click \u0026gt; Extract All) Open the directory that was extracted. It will have the jar file and a \u0026ldquo;libs\u0026rdquo; directory. Do all of those steps correspond to your steps? What does the error look like?\nIf that fails, perhaps try running it from the command-line: java -jar migration-tool-javase-1.0.3.jar\nDiamond Mubaarak — April 15, 2021 at 8:22 am (permalink) Diamond Mubaarak says:\nRunning in command line works, thanks.\nBTW, \u0026ldquo;Post Comment\u0026rdquo; on this WebPage is sometimes hidden and only shows when you hover.\nSteve Hannah — April 15, 2021 at 12:07 pm (permalink) Steve Hannah says:\nRunning in command line works.\nProbably double-clicking was choosing Java6 or Java7 to run it then. If you right click the jar, and select \u0026ldquo;Open With\u0026rdquo;, it may allow you to select a specific version of Java to run it.\nI guess this is why best practice is to distribute with bundled JRE. The first release of this tool I generated native apps for (on Mac and Windows) using the build server, but decided to forego that as the jar distribution seemed to work just as well. Perhaps I need to generate launch scripts for the jar executable to help choose an appropriate JRE.\nThomasH99 — September 19, 2021 at 2:08 pm (permalink) ThomasH99 says:\nI’m finally getting around to try out this migration, but when executing the migrationtool jar (on Mac Big Sur, and using the Open as recommended which by default is JavaLauncher.app)\nI get an error \u0026ldquo;Java Application launch failed.\u0026rdquo; asking me to look in the Console for error messages but I can’t find any references to migrationtool. Any idea what might be wrong? (java –version says openjdk 15.0.1, but in System Preferences I see Oracle Java build 1.8.0_301-b09).\nHowever, afterwards I tried with the command line ike Diamond and that works, but still it might indicate an issue you’d want to fix.\nThomasH99 — September 19, 2021 at 7:06 pm (permalink) ThomasH99 says:\nThe source code of my app is not in the new source directory. Is that supposed to be copied over as well or does the script only create the project and you then bring in the source yourself? Maybe a stupid question (I’m not familiar with Maven at all), but I got the impression the migration tool handled everything 🙂\nThomasH99 — September 19, 2021 at 7:43 pm (permalink) ThomasH99 says:\nSmall usability suggestion: if you indicate a Destination Directory that doesn’t exist you get an error message in red saying \u0026ldquo;Specified directory could not be found\u0026rdquo;. However, if you then enter a correct directory, the error message doesn’t go away, making you think the new value is also wrong.\nThomasH99 — September 19, 2021 at 8:43 pm (permalink) ThomasH99 says:\nSorry, last comment today: I successfully generate a project, but when I open it in IntelliJ I don’t see any Configurations. If I click on e.g. Run/Run, I get a popup saying Run – Edit Configurations, but no scripts in the list. Maybe the migrationtool assumes a recent CN1 project (those I’ve tried with date back at least a few years)? Or do I need to do something specific in IntelliJ (I’m a newbie)?\nSteve Hannah — September 21, 2021 at 11:54 am (permalink) Steve Hannah says:\nIf the run configurations aren’t there, then something is wrong. It may not be recognizing it as a maven project. Make sure you’re opening the root project – not one of the submodules. Relevant documents:\nhttps://shannah.github.io/codenameone-maven-manual/\nI suspect that it may be using the wrong JDK. You should be using JDK 11 or JDK 8 for now. For the migration tool, you can try running it in terminal using java -jar migration-tool.jar, and that way have more control over which JDK it uses for the migration. If you find you need to copy source files to different places after the migration is complete, then there’s a problem.\nThomasH99 — September 22, 2021 at 7:04 pm (permalink) ThomasH99 says:\nThanks Steve, after forcing java to use 1.8 and having the same issue, it turned out the problem was opening the wrong root directory, I opened the one I created for the migrated project and as you clarified, I needed to open the one inside that. I can also open the ones migrated the other day, so using jdk 15 seems to work fine. Thanks for your help!\nThomasH99 — September 22, 2021 at 8:16 pm (permalink) ThomasH99 says:\nOne thing that would really help me with the migration from Netbeans to IntelliJ: when my project in Netbeans is in Git, how do I connect the migrated copies in IntelliJ to the same Git repos? Should I delete the source in the new migrated project and then connect and download from Git or may that disrupt something in the migrated project?\nAdrian Ionescu — September 23, 2021 at 4:17 pm (permalink) Adrian Ionescu says:\nI have been using the cn1-mirah-json macros for json/pojo mapping. After converting the project to maven format, Netbeans (8.2) is complaingint that it can’t find the Mapper classes. Any help with this? Thanks.\nSteve Hannah — September 23, 2021 at 4:50 pm (permalink) Steve Hannah says:\nUnfortunately the Mirah support depended on a few ant-specific things. I’ll need to look into porting it to Maven, but I don’t have an ETA.\nAdrian Ionescu — September 23, 2021 at 6:54 pm (permalink) Adrian Ionescu says:\nThank you. Then I’ll postpone porting to maven for a while.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/migrating-your-project-to-maven/","summary":"\u003cp\u003eAs you may know, we are moving to Maven for our build tool. As part of this transition, we are moving towards a single Maven project structure, and away from separate structures for each IDE. This will be easier to maintain, and will also make it easier to collaborate on projects with other developers who use a different IDE (or no IDE at all).\u003c/p\u003e\n\u003cp\u003eWe have also introduced a online new tool for creating new app projects called \u003ca href=\"https://start.codenameone.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCodename One initializr\u003c/a\u003e. Alternatively, you can create new projects using the cn1app-archetype (for App projects), and cn1lib-archetype for library projects.\u003c/p\u003e","title":"Migrating Your Project to Maven"},{"content":"As a follow-up to our recent announcement about transitioning to Maven, this post provides an overview of the new project structure.\nTip If you want to follow along with this tutorial, you can quickly generate a new project using Codename One intializr.\nThe new project structure is based on the cn1app-archetype. You can see the basic file layout by looking at the archetype-resources directory of that project.\nSome Highlights: 1. This is a multi-module project with sub modules for each target platform.\nIt comes bundled with a maven wrapper script, and utility shell (and bat) scripts to facility command-line usage.\nThe includes NetBeans and IntelliJ configuration files to provide better integration with those IDEs.\n4. The \u0026ldquo;common\u0026rdquo; module contains all of the cross-platform stuff, and is the most direct successor to the old Ant project structure.\ni. codenameone_settings.properties is found in the common module.\nii. CSS files are in common/src/main/css. iii. Java files are in common/src/main/java. iv. Resources are in common/src/main/resources. v. Kotlin files are in common/src/main/kotlin. vi. GUIBuilder files are in common/src/main/guibuilder. vii. Unit tests are in common/src/test/java. 5. CSS By Detault. Projects are set to use CSS by default. You can edit the styles in common/src/main/css/theme.css.\nYou can install cn1lib dependencies either via a Maven snippet in your common/pom.xml file, or using Codename One Settings. You can Also use the install-cn1lib goal. Creating a New Project The easiest way to create a new project is using Codename One initializr. This will allow you to generate and download a starter project that is ready to run, debug, and build.\nModules Let’s now go through each module in the project and discuss its purpose.\ncommon A Codename One application. All of your cross-platform application code goes in this module.\nandroid Module containing native Android code such as native interface implementations.\nios Module containing native iOS code, such as native interface implementations.\njavase Module containing native JavaSE code, such as native interface implementations.\njavascript Module containing native javascript code for the Javascript port.\nwin Module containing native Windows UWP code for the UWP windows port.\ncn1libs Module where legacy cn1libs will be installed the cn1:install-cn1lib goal.\nShell Scripts The archetype project includes run.sh and build.sh shell scripts, as well as their Windows counterparts run.bat and build.bat. These scripts are convenience wrappers for common commands that you may wish to perform on the Command-line. e.g.\nRunning project in the Codename One Simulator ./run.sh Building a cross-platform JavaSE desktop app locally ./build.sh Generating Xcode project locally ./build.sh ios_source # project will be generated in ios/target directory Generating Android Studio project locally ./build.sh android_source # project will be generated in android/target directory. Building iOS app using build server ./build.sh ios Building Android app using build server ./build.sh android Opening Codename One Settings ./run.sh settings Updating Codename One ./run.sh update Tip The run and build scripts are very thin wrappers over mvn. Open these scripts in your text editor to see the exact mvn commands that they run.\nThe Raw Maven Commands The Codename One Maven plugin includes several goals, some of which are executed internally at the appropriate phase of the Maven lifecycle. Others are meant to be executed by you. Typically, you would run the Maven goals in the root module.\nBy default, only the \u0026ldquo;common\u0026rdquo; module is activated. You can activate other modules by specifying them with the codename1.platform property. e.g. If you wanted to build the javase module, you would do:\nmvn package -Dcodename1.platform=javase If, instead, you wanted to build for iOS, you would do:\nmvn package -Dcodename1.platform=ios Tip The codename1.platform property, if supplied, should correspond to the names of the platform-specific module projects. i.e. It supports values \u0026ldquo;javascript\u0026rdquo;, \u0026ldquo;javase\u0026rdquo;, \u0026ldquo;ios\u0026rdquo;, \u0026ldquo;android\u0026rdquo;, and \u0026ldquo;win\u0026rdquo;.\nWhen performing builds (e.g. mvn package), you may also need to specify which build target you wish to use, as most platforms have more than one build target. For example the javase platform is used for the simulator, Mac desktop apps, Windows desktop apps, and JavaSE desktop apps. You should use the codename1.buildTarget property to differentiate.\ne.g. To build a Mac Desktop app you would run:\nmvn package -Dcodename1.platform=javase \\ -Dcodename1.buildTarget=mac-os-x-desktop And to build for Windows Desktop, you would run:\nmvn package -Dcodename1.platform=javase \\ -Dcodename1.buildTarget=windows-desktop Why 2 Properties? You might be wondering why we need to include both codename1.platform and codename1.buildTarget properties explicitly. The codename1.buildTarget property should correspond to a unique codename1.platform value (e.g. codename1.buildTarget=mac-os-x-desktop implies codename1.platform=javase), so why can’t we just omit the codename1.platform property and let the build system \u0026ldquo;figure it out\u0026rdquo;? Indeed!\nThe reason is because Maven doesn’t allow you to do this in a way that will support our needs. The codename1.platform property is used for more than just activating the correct module. It is used by cn1lib projects that are listed as dependencies also to include the correct artifacts for the current build. If this property isn’t provided on the command-line, then it won’t be available early enough in the Maven reactor process to activate all of the needed modules and artifacts.\nIf you know a clever solution to this issue, I’m all ears. My solution was to just provide the build.sh and build.bat scripts to wrap the common goals and include the needed properties at that level.\nCheck out the build.sh script source for a list of the most-common build commands.\nIn the IDE As mentioned above, we’ve done some work to add better integration than default to IntelliJ and NetBeans. If you open the project in IntelliJ, the Configuration menu will include options for all of the common commands including building the project for each target platform, running in the simulator, opening Codename Settings, and updating Codename One.\nNetBeans includes similar support, and we plan to add \u0026ldquo;special\u0026rdquo; support for Eclipse and VSCode in the near future.\nSee Getting Started with the Bare-bones Java App Project for more in-depth coverage of each IDE including screenshots.\nWhere to go from here Our Maven support represents months of careful work, and there is much more that could be discussed. Over the coming weeks I’ll be writing more blog posts on various aspects of this support. In the mean time, you can check out the Getting Started tutorial and the Codename One Maven Developer Guide for a deeper dive. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nEric Gbofu — April 13, 2021 at 6:01 pm (permalink) Eric Gbofu says:\nHello\nI have a few things to report about Maven support\nNormally, a Kotlin project accepts a mix of Java and Kotlin files. With the old Ant support, I could mix * .kt and * .java files in the same project and everything worked fine. With this new Maven support, when I mix these two file formats in a kotlin project, the first run goes fine and everything displays fine, but when I make changes to the * .java file and re executes the code, the simulator starts but the modifications are applied. Any modification that is done after the first execution in the java file is not applied at all. With Ant, this problem was not present. What is the cause?\nWith the previous Ant build system, we can see methods documentation in the IDE. With Maven, this documentation is no longer displayed. Can you fix that please ?\nIn the documentation you show how to create CN1 maven project via the command line and Codename One initializer. Can you also add in the documentation how to do it directly via the IDE without going through the two previous options?\nThanks\nEric Gbofu — April 13, 2021 at 10:00 pm (permalink) Eric Gbofu says:\nAnswers for my previous questions: https://github.com/codenameone/CodenameOne/issues/3390\nAntonio Rios — March 20, 2022 at 3:49 pm (permalink) Antonio Rios says:\nExcellent post Steve!\nThanks for all this great information. I completed watching the introductory free course from the academy and Shai told me that you guys are now using maven and css instead of old way with the IDE plugins. So I follow this instructions and the developer guide to try the new way of creating projects with maven. I ran into a couple of problems that took me some time to figure out since I’m new to this. If it helps I’m using OpenJDK 17 on puppy linux and vim as my lightweight IDE and running everything in the terminal. I’m really impress how well everything works on my 7 year old laptop.\nI used the Bare-bones Java App with the option \u0026ldquo;Other\u0026rdquo; for the IDE maven starter project. When I tried to run the project the simulator would not launch because the ‘MaxPermSize=128M’ VM option was unrecognized. I was able to fix this problem by commenting out line 612 from the pom.xml file in the javase folder.\n\u0026quot;\n[INFO] — exec-maven-plugin:3.0.0:exec (run-in-simulator) @ learningapp-javase —\nUnrecognized VM option ‘MaxPermSize=128M’\nError: Could not create the Java Virtual Machine.\nError: A fatal exception has occurred. Program will exit.\n[ERROR] Command execution failed.\norg.apache.commons.exec.ExecuteException: Process exited with an error: 1 (Exit value: 1)\n\u0026quot;\nThe second problem I had was when trying to open the settings by using the command run.sh settings. I kept getting an error message stating that no plugin was found for prefix ‘cn’ in the current project and in the plugin groups. Eventually I figured out the problem was in the run.sh file so I had to append a 1 to cn on line 14 so it would call \u0026ldquo;cn1:settings\u0026rdquo;.\n\u0026quot;\n[ERROR] No plugin found for prefix ‘cn’ in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (/root/.m2/repository), central (https://repo.maven.apache.org/maven2)] -\u0026gt; [Help 1]\n\u0026quot;\nSteve Hannah — March 21, 2022 at 11:48 am (permalink) Steve Hannah says:\nThanks for sharing this. I have made these changes to the archetype so that they will be part of the next update (7.0.62). Officially we support JDK8 and JDK11, not JDK17 yet, which is the reason for this failure. (i.e. an alternate fix for the first error would have been to change to JDK11).\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/maven-project-structure/","summary":"\u003cp\u003eAs a follow-up to our recent announcement about transitioning to Maven, this post provides an overview of the new project structure.\u003c/p\u003e\n\u003ch2 id=\"tip\"\u003eTip\u003c/h2\u003e\n\u003cblockquote\u003e\n\u003cp\u003eIf you want to follow along with this tutorial, you can \u003ca href=\"https://shannah.github.io/cn1-maven-archetypes/cn1app-archetype-tutorial/getting-started.html#generating-new-project\" target=\"_blank\" rel=\"noopener noreferrer\"\u003equickly generate a new project\u003c/a\u003e using \u003ca href=\"https://start.codenameone.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCodename One intializr\u003c/a\u003e.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eThe new project structure is based on the \u003ca href=\"https://github.com/shannah/cn1-maven-archetypes/tree/master/cn1app-archetype\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ecn1app-archetype\u003c/a\u003e. You can see the basic file layout by looking at the \u003ca href=\"https://github.com/shannah/cn1-maven-archetypes/tree/master/cn1app-archetype/src/main/resources/archetype-resources\" target=\"_blank\" rel=\"noopener noreferrer\"\u003earchetype-resources\u003c/a\u003e directory of that project.\u003c/p\u003e\n\u003ch2 id=\"some-highlights\"\u003eSome Highlights:\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003e\u003cstrong\u003e1. This is a multi-module project\u003c/strong\u003e\u003c/strong\u003e with sub modules for each target platform.\u003c/p\u003e","title":"Maven Project Structure"},{"content":"Due to popular demand, we are officially providing local build support for iOS, Android and cross-platform JavaSE Desktop apps. No build server or Codename One account required.\nThe Build Server has been a fundamental building block of Codename One from the very beginning. In the fractured world of mobile development where you need the latest Mac running the Latest Xcode to build for iOS, and the latest Windows running the latest Visual Studio to build for Windows, the build server reduced your system requirements to JDK 8 and an IDE. In general, this was a big win, and it makes mobile app development much more pleasant.\nDespite its demonstrated utility, however, it has been frequently cited as a barrier to adoption by developers who prefer not to rely on a third party service to build their apps. Developers (myself included) have a strong libertarian streak, especially when it comes to our code. We don’t like to have strings of any kind attached to code that we write, and reliance on a build server to build our code certainly qualifies as a \u0026ldquo;string\u0026rdquo;.\nIt has always been \u0026ldquo;possible\u0026rdquo; to build apps locally, without the build server. The Codename One source code is open source (GPL+CE), and all of the tools required to build apps are freely available, but we didn’t provide support for this option, nor did we document how to do it. It was up to the developer to hack together their own solution if they really wanted to build locally, and this was a complicated endeavor.\nBefore I joined Codename One, I developed a number of offline build tools myself, and implemented support for alternative compilers and virtual machines, so I can verify that it is and was always possible. However, my offline-build solutions were still 2nd-class and didn’t support all of the features of Codename One. Native Interfaces, for example, require some complex logic to generate platform-specific \u0026ldquo;glue\u0026rdquo;, and my offline builders didn’t support this.\nSince joining Codename One, we have had ongoing internal discussions about the merits of developing, maintaining, and supporting local build options. Would local builds result in an avalanche of support requests that would swallow up our limited resources? Would it result in developers opting for the \u0026ldquo;free\u0026rdquo; offline build option and canceling their subscriptions? Such a result might impact our ability to exist at all.\nThese are unresolved questions, but we are poised to find out their answers, as we are officially providing local build support for iOS, Android, and Desktop. These build options are built into our new Maven project archetype. See below for details and caveats about these build targets.\niOS Builds The Local iOS build target generates an Xcode project that you can open and build directly in Xcode. This target requires a Mac with Xcode installed. CocoaPods is only required for CocoaPods-based builds; projects that use Swift Package Manager use the normal Apple toolchain instead. See the current \u0026ldquo;Working with iOS\u0026rdquo; section in the developer guide and Building for iOS for more information.\nAndroid Builds The Local Android build target generates an Android Studio project that you can open and build directly in Android Studio. This target necessarily requires that you have Android Studio installed, but it doesn’t have any special requirements outside of that. See Building for Android from this tutorial for more information.\nDesktop Builds The local desktop build target builds a cross-platform JavaSE desktop application in the form of an executable Jar file. See Building JavaSE Desktop App from this tutorial for more information.\nThe Case for the Build Server Now that you can build your projects locally, you are not tied to the build server. You don’t require a Codename One subscription in order to build your code anymore. Your code is your code, and that is final. However, I think you’ll still find that the build server provides a superior developer experience.\nThe build server provides a one click experience from project to distributable app. Local builds require you to first generate the native (Xcode/Android Studio) project, then open and build that project. This is more time-consuming and fraught with pain points, as maintaining your own local toolchains isn’t all sunshine and rainbows.\nThe Case for a Codename One Subscription If you find Codename One useful, but you don’t require access to our build servers, then the best reason to purchase a subscription is to help us keep the lights on and make the product better.\nBeyond that, a Pro subscription provides access to many useful features such as the Push notification service, crash reporting, and e-mail support, and Enterprise subscription provides support for Javascript builds, phone/Zoom support, and many more benefits.\nWe are also working on some other exclusive content options that will be available to subscribers, as a reward for your support.\nHelp Spread the Word Subscriptions aside, the best way to support us is to spread the word. Blog about the cool things you’re doing with Codename One. Share us on sites like Reddit, Facebook, Twitter, and Hacker News. Answer Codename One related questions on Stack Overflow to help other community members. Build cn1libs and publish them on Github.\nWe all benefit from a larger, more diverse community.\nGetting Started Getting started with Codename One is easy. Just go to Codename One initializr, and generate a starter project that you can open, run, debug, and build in your preferred IDE. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nMehdi ELGHISSASSI — June 1, 2021 at 7:03 pm (permalink) Mehdi ELGHISSASSI says:\nhello,\nhow i can display Local Build config option in netbeans to choose Gradle Android Project to generate an Android Studio project.\nShai Almog — June 2, 2021 at 1:12 am (permalink) Shai Almog says:\nYou need to migrate the project to maven as explained here \u0026lt;/blog/moving-to-maven/\u0026gt;\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/you-can-now-build-android-and-ios-apps-locally/","summary":"\u003cp\u003eDue to popular demand, we are officially providing local build support for iOS, Android and cross-platform JavaSE Desktop apps. No build server or Codename One account required.\u003c/p\u003e\n\u003cp\u003eThe Build Server has been a fundamental building block of Codename One from the very beginning. In the fractured world of mobile development where you need the latest Mac running the Latest Xcode to build for iOS, and the latest Windows running the latest Visual Studio to build for Windows, the build server reduced your system requirements to JDK 8 and an IDE. In general, this was a big win, and it makes mobile app development much more pleasant.\u003c/p\u003e","title":"You Can Now Build Android \u0026 iOS Apps Locally"},{"content":"Codename One is migrating to Maven. This will simplify some aspects of our build process and update/dependency management.\nAs the headline states, we’re moving to Maven, and leaving the ant-infested old build system behind. To be honest, I love using Ant. It is quick and dirty, and let’s me assemble ad-hoc build workflows with little effort.\nMigrating to Maven, at times, felt like strapping on a pair of cement boots. It is much more rigid than Ant, and much more opinionated. It’s the \u0026ldquo;Maven\u0026rdquo; way, or you’re in for a world of pain.\nWhy Maven? So, you may ask, if Maven is so opinionated and painful, why are we adopting it? The reason is simply because it is worth it. Maven’s rigidity encourages better project hygiene — Builds that \u0026ldquo;just work\u0026rdquo;, without having to read through a page of build instructions, or embarking on a dependency scavenger hunt. Once you agree to surrender some of the flexibility that Ant provided, you can begin to enjoy a better developer experience, all round.\nDependencies can be added as XML snippets to the pom.xml file rather than downloaded manually. And they can be removed, or upgraded to new versions just as easily.\nThe Maven eco-system is mature and diverse, providing all kinds of plugins to augment your build process. Maven’s rigidity helps all of these plugins work together as if on an assembly line.\nMaven projects are also well supported by all major IDEs. Rather than maintaining a separate project type for each IDE, we can provide a single Maven project archetype that can be used by any IDE – or even no IDE if you prefer.\nNew Features As part of this move, we’ve included a few new features, some of which are simply by-products of using Maven.\nLocal Builds Due to popular demand, we have provided support for building iOS, Android, and Cross-platform JavaSE Desktop apps locally. i.e. No build server or Codename One account required. More on this in a future blog post, but you can read more about it here.\nFirst-Class Kotlin Support Kotlin support is now provided directly using the official Kotlin Maven plugin, and it is included into the Codename One Application archetype by default. Previously we had been providing Kotlin support via a cn1lib that included a Kotlin runtime, which we maintained ourselves by periodically updating it to newer versions of Kotlin.\nFor more information about developing Codename One apps in Kotlin, see Getting Started with the Bare-bones Kotlin App Template.\nSupport for Jar Dependencies You can now use regular Java jar dependencies in your projects, with the caveat that your build will fail if you use any APIs (transitively) that aren’t supported by Codename One. You can paste regular dependency snippets from Maven central into your projects. In the past, only cn1libs were supported, as they ensured compliance with the Codename One API.\nThis is made possible by improvements to our compile-time compliance check which incorporates Proguard to determine which classes and methods are used in your app, then throw an error if it identifies any unsupported APIs.\nWarning It isn’t yet clear how useful this \u0026ldquo;jar\u0026rdquo; support will be, as many Jar dependencies on Maven central are directed at server-side audiences and are fundamentally incompatible with Codename One. For this reason, I still prefer to use cn1libs.\nPublish your Libraries on Maven Central You can now deploy your Codename One Library projects to Maven central so that others can use them by pasting a dependency snippet into the the pom.xml file of their Application projects. Cn1libs listed in Codename One Settings can now include a Maven dependency snippet which will be used when adding the library to a Maven project.\nA Small Change in the Workflow The transition to Maven should be nearly seamless, but you will notice a few changes in the development workflow.\nThe \u0026ldquo;Old\u0026rdquo; Ant Workflow 1\nInstall Codename One 2\nCreate New Project 3\nDevelop \u0026amp; Debug App 4\nAdd cn1libs 5\nCreate a Build The old Ant workflow worked as follows:\nInstall the Codename One Plugin in your IDE via the \u0026ldquo;Install Plugin\u0026rdquo; mechanism in the IDE. We provide plugins for IntelliJ, NetBeans, and Eclipse.\nCreate a new Codename One Application project using the \u0026ldquo;New Project\u0026rdquo; option in your IDE.\nUse the IDE’s editor to develop and debug your application.\nAdd cn1libs (plugins) to your project using Codename One Settings.\nUse the Codename One menu in the IDE to perform tasks like building your project for iOS or Android.\nThe New Maven Workflow 1\nCodename One initializer 2\nOpen in IDE 3\nDevelop \u0026amp; Debug App 4\nAdd cn1libs 5\nCreate a Build With the Maven transition, you no longer need to install a plugin in your IDE, since all of the Major IDEs know how to speak maven out of the box. Instead you can use our Maven project archetypes to create new Application or Library projects – or use the new Codename One initializr tool to generate a new project for you from a growing selection of Application templates. More on that later.\nSo the workflow (with IDE) becomes:\nGenerate a new project from an application template using Codename One initializr.\nOpen the project in your preferred IDE.\nUse the IDE’s editor to develop and debug your application.\nAdd cn1libs (plugins) to your project using Codename One Settings – or by pasting a regular Maven dependency snippet into your pom.xml file.\nUse the provided configuration options in the IDE to build the project for various platforms such as iOS, Android, etc…​\nAlternatively, and additionally, everything can be done via the command-line, if you prefer to run, debug, and build your projects that way.\nMigrating Existing Projects That new workflow is all fine and dandy for new projects, but what about my existing Codename One application project that I’ve been working on for the past 5 years?\nYou’re in luck. We’ve included a migration tool in the maven plugin that will convert Ant projects into the new Maven project format. All you need to do is run a single command, and you’ll be all set up to use Maven, like the rest of the cool kids.\nGetting Started Create your first Maven project right now using the Codename One initializr tool.\nRead about the nuts and bolts in the Codename One Maven Developers Guide.\nWatch the video demo of Codename One initializr. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nJavier Anton — March 29, 2021 at 11:53 pm (permalink) Javier Anton says:\nPlease fix the sample code at https://shannah.github.io/codenameone-maven-manual/#migrate-existing-project\nThere should be a space after each -D and there shouldn’t be backslashes after each line. I think that copying the command into HTML messed it up somehow\nSteve Hannah — March 29, 2021 at 11:59 pm (permalink) Steve Hannah says:\nLooks correct to me. Those slashes escape the new line chars so it can be displayed on multiple lines. You can paste that directly into Mac or Linux. Or Windows even, if running bash.\nJavier Anton — March 30, 2021 at 7:42 am (permalink) Javier Anton says:\nNevermind. I was running Powershell on Windows. In that case, what I said is required\nSteve Hannah — March 30, 2021 at 12:29 pm (permalink) Steve Hannah says:\nThanks. I’ll add a note in the docs about Windows.\nJavier Anton — March 30, 2021 at 9:48 am (permalink) Javier Anton says:\nAfter migrating from Ant to Maven, I had to add the maven android dependency to the pom.xml in order to compile my android native source:\n29\ncom.google.android\nandroid\n${android.platform}\nsystem\n${user.home}/.codenameone/android-${android.platform}/android.jar\nJavier Anton — March 30, 2021 at 9:49 am (permalink) Javier Anton says:\nseems the comments can’t contain xml\nJavier Anton — March 30, 2021 at 9:53 am (permalink) Javier Anton says:\nActually, that was wrong. I still can’t compile because my new maven project doesn’t detect the android package of my native sources. And I can’t delete my previous comments, which makes this page look kind of ugly. Enough feedback for today! 😛\nSteve Hannah — April 1, 2021 at 12:23 pm (permalink) Steve Hannah says:\nI see the issue. Add the following to the section of your android/pom.xml file.\nsrc/main/empty\nSteve Hannah — March 30, 2021 at 12:28 pm (permalink) Steve Hannah says:\nYou shouldn’t need to do that. The android native source doesn’t get compiled. It is sent to the build server as source. Are you getting an error message when you try to build?\nJavier Anton — March 30, 2021 at 7:44 pm (permalink) Javier Anton says:\nYes, I was getting an error message when building from Android. It started with it complaining about the android package. I know that this wasn’t happening before (Ant) and thought that it was now (Maven) required to use the Android SDK. Why could it be that my project is saying this after migrating to Maven?\nSteve Hannah — March 30, 2021 at 7:59 pm (permalink) Steve Hannah says:\nWhat IDE are you using, or are you building from Command-line?\nYou should always build from the root project (not the sub-modules), and it will include appropriate sub-modules according to your flags.\nIf building from command line, either use the build.sh (or build.bat) script, or see the maven commands executed by these scripts to see how to run the maven commands directly.\nIf building from the IDE, use the preset build options.\nFor building Android using the build server (i.e. mvn package -Dcodename1.platform=android -Dcodename1.buildTarget=android-device) you do NOT need to have the android SDK installed.\nYou would only need the android SDK installed if you were doing a local android build (e.g. mvn package -Dcodename1.platform=android -Dcodename1.buildTarget=android-source).\nJavier Anton — March 30, 2021 at 11:51 pm (permalink) Javier Anton says:\nI removed my android sdk deps. Now I am stuck here (android sdk error no longer shows):\n\u0026ldquo;Failed to merge properties from library com.some.package:SomeApp-GoogleMaps. Property codename1.arg.ios.glAppDelegateHeader has a conflict\u0026rdquo;\nI use the GooglMaps cn1lib. My delegate’s header already contains something and is as follows:\n#include \u0026ldquo;com_some_something.h\u0026rdquo; #import \u0026ldquo;com_some_more_something.h\u0026rdquo;\nGoogleMaps cn1lib’s del header appends: \\n#import \u0026ldquo;GoogleMaps/GoogleMaps.h\u0026rdquo;\nIf I remove my del. header’s build hint, the error goes away. But the same error then appears but complaining about the pods build hint. Is Maven having trouble merging build hints from cn1libs with the app’s?\nThese errors happen both in PowerShell and in NetBeans\nSteve Hannah — March 31, 2021 at 12:14 am (permalink) Steve Hannah says:\nCheck the cn1.version property in your pom.xml file. If it’s not 7.0.17 start over (migrate the ant project again). If it is 7.0.17, then please describe the exact command you are running, and what output you are getting. Javier Anton — March 31, 2021 at 8:05 am (permalink) Javier Anton says:\nChecked, it’s 7.0.17.\nOn PowerShell:\nmvn package -D codename1.platform=android -D codename1.buildTarget=android-device -e\nOn NetBeans:\nSelect main project. Select \u0026ldquo;Android App\u0026rdquo; from the config dropdown. Press build or run I just tried \u0026ldquo;Clean and Rebuild\u0026rdquo; and now my project doesn’t detect Android native code anymore. I think I’ll have to re-run the migration later today and see if something changes\nJavier Anton — March 31, 2021 at 7:25 pm (permalink) Javier Anton says:\nOK so I re-ran the migration and got to the same place.\n-Can compile local javase fine\n-Can run simulator\n-Can’t compile Android because it looks for android package in native sources and then it fails:\n\u0026ldquo;com/namespace/SomeActivity.java:[8,19] package android.app does not exist\u0026rdquo;\n-Can’t compile iOS because it complains about build hints conflict as stated before:\n\u0026ldquo;Failed to merge properties from library com.groups:NewId-GoogleMaps. Property codename1.arg.ios.glAppDelegateHeader has a conflict\u0026rdquo;\nThe command used for the migration is as follows (PowerShell):\nSET CN1_VERSION=7.0.17\nmvn com.codenameone:codenameone-maven-plugin:${CN1_VERSION}:generate-app-project -D archetypeGroupId=com.codename1 -D archetypeArtifactId=cn1app-archetype -D archetypeVersion=${CN1_VERSION} -D artifactId=NewId -D groupId=com.my.namespace -D version=1.0-SNAPSHOT -D interactiveMode=false -D sourceProject=folderWithAndProject\nThe migration says that all is successful\nFeel free to send me an email or anything, I can jump on a call too if required. Unless you can think of anything I will stop trying to fix this for now as I feel I have hit a dead end\nSteve Hannah — March 31, 2021 at 9:25 pm (permalink) Steve Hannah says:\nI found an bug with the migration of cn1libs that include required library properties. It is fixed and will be part of the the 7.0.19 release. You’ll need to run migration again with that version number. That release has already been deployed to maven central, but it usually takes a few hours before it is available.\nJavier Anton — April 1, 2021 at 8:51 am (permalink) Javier Anton says:\nSome good news. With 7.0.19, iOS no longer complains about a build hint conflict and builds.\nAndroid builds still try to find the android SDK for native sources and fail\nSteve Hannah — April 1, 2021 at 12:21 pm (permalink) Steve Hannah says:\nI see the issue. Add the following to the section of your android/pom.xml file.\nsrc/main/empty\nJavier Anton — April 1, 2021 at 2:45 pm (permalink) Javier Anton says:\nNice one – it works\nEric Gbofu — April 1, 2021 at 4:15 pm (permalink) Eric Gbofu says:\nHi Steve,\nWhen i use the project template downloaded from the Codename One initializr, everything works fine but when i want to do the same thing using the intellij idea project creation wizard to create a new project using the Codename One maven app archetype, it doesn’t work and i have the following error during the project generation process in batch mode\nHere is the error message :\nFailed to execute goal org.apache.maven.plugins:maven-archetype-plugin:3.2.0:generate (default-cli) on project standalone-pom: Archetype com.codenameone:cn1app-archetype:LATEST is not configured\nProperty mainName is missing.\nProperty mainName is missing. Add -DmainName=someValue\nPS: Maven is new for me.\nSteve Hannah — April 1, 2021 at 4:50 pm (permalink) Steve Hannah says:\nYes. That’s right. You need to add the mainName property. There are other properties you can add also, such as cn1Version (to set explicit codename one version).\nEric Gbofu — April 1, 2021 at 5:06 pm (permalink) Eric Gbofu says:\nThanks Steve! I did it and it works.\nOne last question. Will you remove completely the Codename One plugin in a near future to only adopt the maven project or you will modify it according to the new way to create projects ?\nRegards\nSteve Hannah — April 1, 2021 at 5:41 pm (permalink) Steve Hannah says:\nI believe the plan is to deprecate the Codename One plugins. They will not be modified to support Maven. IDEs all have built-in support for Maven. We’ll be focusing on tailoring the application project archetype to work smoothly with each IDE. This will provide a more robust and consistent experience for developers across all IDEs.\nEric Gbofu — April 1, 2021 at 9:43 pm (permalink) Eric Gbofu says:\nOk! Thanks for the clarification\nEric Gbofu — April 1, 2021 at 11:29 pm (permalink) Eric Gbofu says:\nAbout my question, i want to know if you can add the mainName property directly into the archetype so the developer will not have to add it manually every time that he wants to create a new project ?\nEric Gbofu — April 1, 2021 at 11:30 pm (permalink) Eric Gbofu says:\nAbout my first question, i want to know if you can add the mainName property directly into the archetype so the developer will not have to add it manually every time that he wants to create a new project ? Is there a problem to do it that way?\nRaazia Tariq — February 22, 2024 at 9:42 pm (permalink) Raazia Tariq says:\nGeneral error during conversion: Conflicting module versions. Module [groovy-all is loaded in version 2.4.16 and you are trying to load version 2.4.8..\nI got this error while converting an existing project.\nShai Almog — February 23, 2024 at 3:02 am (permalink) Shai Almog says:\nPersonally I found it’s easier and more reliable to create a new project using https://start.codenameone.com and then copying over the source/css/codenameone_settings.properties on top of the new project (while removing cn1lib build hints). Then reinstalling the cn1libs.\nRaazia Tariq — February 23, 2024 at 4:16 pm (permalink) Raazia Tariq says:\nI was able to convert the project successfully. Now, I am stuck on upgrading the project to support higher version of android and iOS. Is there any documentation regarding that?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/moving-to-maven/","summary":"\u003cp\u003eCodename One is migrating to Maven. This will simplify some aspects of our build process and update/dependency management.\u003c/p\u003e\n\u003cp\u003eAs the headline states, we’re moving to Maven, and leaving the ant-infested old build system behind. To be honest, I love using Ant. It is quick and dirty, and let’s me assemble ad-hoc build workflows with little effort.\u003c/p\u003e\n\u003cp\u003eMigrating to Maven, at times, felt like strapping on a pair of cement boots. It is much more rigid than Ant, and much more opinionated. It’s the \u0026ldquo;Maven\u0026rdquo; way, or you’re in for a world of pain.\u003c/p\u003e","title":"Moving to Maven"},{"content":"The following recipes relate to data processing and conversion in Codename One apps. This includes parsing data like JSON, HTML and XML.\nParsing HTML Problem You want to parse some HTML content into a data structure. You can’t simply use the XMLParser class because the content is not well-formed XML, but you would like to be able to work with the parsed document using the same tools (e.g. Result and Element.)\nSolution Use the HTMLParser class from the CN1HTMLParser cn1lib. It contains a simple API for parsing an HTML string into an Element, the same type of element that XMLParser returns.\nUsage Example: HTMLParser parser = new HTMLParser(); Element root = parser.parse(htmlString).get(); (1) Result r = Result.fromContent(root); // Now modify the document // In this example we\u0026#39;re going to replace image src with placeholders // so we can load them separately. List images = r.getAsArray(\u0026#34;//img\u0026#34;); int index = 0; List toLoad = new ArrayList\u0026lt;\u0026gt;(); if (images != null) { for (Element img : images) { String src = img.getAttribute(\u0026#34;src\u0026#34;); if (src.startsWith(\u0026#34;http://*/\u0026#34;) || (!src.startsWith(\u0026#34;http://\u0026#34;) \u0026amp;\u0026amp; !src.startsWith(\u0026#34;data:\u0026#34;) \u0026amp;\u0026amp; !src.startsWith(\u0026#34;https\u0026#34;))) { img.setAttribute(\u0026#34;id\u0026#34;, \u0026#34;nt-image-\u0026#34;+index); toLoad.add(src); img.setAttribute(\u0026#34;src\u0026#34;, \u0026#34;\u0026#34;); index++; } } } // Now write the document as well-formed XML. XMLWriter writer = new XMLWriter(true); String pageContent = writer.toXML(root); The parse() method returns an Async promise. If you want to use it synchronously, you can call get(), which will wait until parsing is done.\nAlternate Async Usage The above example uses the get() method to wait until the result is ready, but you can use the parser asynchronously as well:\nparser.parse(htmlString).ready(root-\u0026gt;{ // root is the root Element of the document. }); Discussion The HTMLParser class wraps an off-screen BrowserComponent to use the platform’s native webview to actually parse the HTML. It then serializes the DOM as XML, which is then re-parsed using the Codename One XML parser. There are pitfalls to this approach, including performance (it takes time to pass data back-and forth between a webview, after all), and possibly different results on different platforms.\nNOTE The Codename One core library also includes an HTMLParser class at com.codename1.ui.html.HTMLParser. This parser is meant to be used as part of the deprecated HTMLComponent class, which is a light-weight web view component that used to be used on platforms that didn’t have a native webview, e.g. J2ME. Now all modern platforms have a native webview, so this component isn’t used much. Additionally the HTMLParser class in that package doesn’t support all HTML, and will fail in strange ways if you try to use it headlessly.\nFurther Reading XMLParser Javadocs – Since the output of HTMLParser is the same as XMLParser, you can find some useful examples in the XMLParser javadocs.\nUsing the Clipboard Problem You want to copy and paste to and from the system clipboard.\nSolution Use the Display.copyToClipboard() and Display.getPasteDataFromClipboard() to copy and paste to/from the system clipboard respectively.\nExample: Copying to the Clipboard Display.getInstance().copyToClipboard(\u0026#34;Some text to copy\u0026#34;); Example: Copying text from clipboard into Label Object pasteData = Display.getInstance().getPasteDataFromClipboard(); Label text = new Label(); if (pasteData instanceof String) { text.setText((String)pasteData); } else { ToastBar.showInfoMessage(\u0026#34;Paste data is not text\u0026#34;); } IMPORTANT In the Javascript port we are restricted by the browser’s sandbox. We can’t just access the system clipboard data for security reasons. However, if the user initiates a paste via Ctrl-V, Command-V, Edit → Paste etc, the system clipboard contents will be loaded into the Codename One clipboard, so that the next time you call getPasteDataFromClipboard(), it will include those contents.\nYou can use Form.addPasteListener(ActionListener) to be notified when the clipboard contents are updated via this method so that you can respond appropriately - usually by calling getPasteDataFromClipboard() and doing something with the data.\nFull Example allowing copy and paste using the Clipboard API package com.codename1.samples; import com.codename1.components.ToastBar; import static com.codename1.ui.CN.*; import com.codename1.ui.Display; import com.codename1.ui.Form; import com.codename1.ui.Dialog; import com.codename1.ui.Label; import com.codename1.ui.plaf.UIManager; import com.codename1.ui.util.Resources; import com.codename1.io.Log; import com.codename1.ui.Toolbar; import java.io.IOException; import com.codename1.ui.layouts.BoxLayout; import com.codename1.io.NetworkEvent; import com.codename1.ui.Button; import com.codename1.ui.CN; import com.codename1.ui.TextArea; import com.codename1.ui.TextField; import com.codename1.ui.layouts.GridLayout; public class ClipboardSample { private Form current; private Resources theme; public void init(Object context) { // use two network threads instead of one updateNetworkThreadCount(2); theme = UIManager.initFirstTheme(\u0026#34;/theme\u0026#34;); // Enable Toolbar on all Forms by default Toolbar.setGlobalToolbar(true); // Pro only feature Log.bindCrashProtection(true); addNetworkErrorListener(err -\u0026gt; { // prevent the event from propagating err.consume(); if(err.getError() != null) { Log.e(err.getError()); } Log.sendLogAsync(); Dialog.show(\u0026#34;Connection Error\u0026#34;, \u0026#34;There was a networking error in the connection to \u0026#34; + err.getConnectionRequest().getUrl(), \u0026#34;OK\u0026#34;, null); }); } public void start() { if(current != null){ current.show(); return; } Form hi = new Form(\u0026#34;Hi World\u0026#34;, BoxLayout.y()); TextField text = new TextField(); Button copyBtn = new Button(\u0026#34;Copy\u0026#34;); copyBtn.addActionListener(evt-\u0026gt;{ Display.getInstance().copyToClipboard(text.getText()); }); Button pasteBtn = new Button(\u0026#34;Paste\u0026#34;); pasteBtn.addActionListener(evt-\u0026gt;{ if (\u0026#34;html5\u0026#34;.equalsIgnoreCase(CN.getPlatformName())) { // In the browser, we don\u0026#39;t have permission, in general, to read from the clipboard // but the user can initiate a paste using Ctrl-V or Cmd-V, or Edit \u0026gt; Paste, // and the data will be received in the paste listener. Dialog.show(\u0026#34;Help\u0026#34;, \u0026#34;Please key-codes or Edit \u0026gt; Paste to paste content.\u0026#34;, \u0026#34;OK\u0026#34;, null); return; } handlePaste(text); }); // The paste listener is informed when the user initiates a paste using // key-codes or browser menu items (Edit \u0026gt; Paste). This is currently only // used by the Javascript port. hi.addPasteListener(evt-\u0026gt;{ handlePaste(text); }); hi.add(text) .add(GridLayout.encloseIn(2, copyBtn, pasteBtn)); hi.show(); } /** * Pastes the current clipboard data as text into the given TextArea. * @param text The textarea to paste into */ private void handlePaste(TextArea text) { Object pasteData = Display.getInstance().getPasteDataFromClipboard(); if (pasteData instanceof String) { text.setText((String)pasteData); } else { ToastBar.showInfoMessage(\u0026#34;Paste data is not text\u0026#34;); } } public void stop() { current = getCurrentForm(); if(current instanceof Dialog) { ((Dialog)current).dispose(); current = getCurrentForm(); } } public void destroy() { } } Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/data-processing-in-codename-one-apps/","summary":"\u003cp\u003eThe following recipes relate to data processing and conversion in Codename One apps. This includes parsing data like JSON, HTML and XML.\u003c/p\u003e\n\u003ch3 id=\"parsing-html\"\u003eParsing HTML\u003c/h3\u003e\n\u003ch2 id=\"problem\"\u003eProblem\u003c/h2\u003e\n\u003cp\u003eYou want to parse some HTML content into a data structure. You can’t simply use the \u003ca href=\"/javadoc/com/codename1/xml/XMLParser/\"\u003eXMLParser\u003c/a\u003e class because the content is not well-formed XML, but you would like to be able to work with the parsed document using the same tools (e.g. \u003ca href=\"/javadoc/com/codename1/processing/Result/\"\u003eResult\u003c/a\u003e and \u003ca href=\"/javadoc/com/codename1/xml/Element/\"\u003eElement\u003c/a\u003e.)\u003c/p\u003e\n\u003ch2 id=\"solution\"\u003eSolution\u003c/h2\u003e\n\u003cp\u003eUse the HTMLParser class from the \u003ca href=\"https://github.com/shannah/CN1HTMLParser\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCN1HTMLParser cn1lib\u003c/a\u003e. It contains a simple API for parsing an HTML string into an \u003ca href=\"/javadoc/com/codename1/xml/Element/\"\u003eElement\u003c/a\u003e, the same type of element that \u003ca href=\"/javadoc/com/codename1/xml/XMLParser/\"\u003eXMLParser\u003c/a\u003e returns.\u003c/p\u003e","title":"Data Processing in Codename One apps"},{"content":"Recipes to customize the look and feel of Codename One apps using Themes, CSS, Styles, etc.\nThe following recipes include tips on customizing the look and feel of Codename one apps using themes, CSS, styles, etc.\nPlatform-Specific Styling Problem You have used CSS to style your app, and it looks great on some devices but not on others. You want to change the font size of some styles, but only on specific devices.\nSolution Use CSS media queries to target styles at a specific device (e.g. desktop, tablet, or phone), platform (e.g. Android, iOS, Mac, Windows, etc…​), or device densities (e.g. low, medium, high, very high, etc..).\nExample: A media query to override Label color on iOS only @media platform-ios { Label { color: red; } } Media queries will allow you to target devices based on three axes: Platform, Device, and Density\nTable 1. Platform Queries Value Description platform-ios Apply only on iOS platform-and Apply only on Android platform-mac Apply only on Mac desktop platform-win Apply only on Windows desktop Table 2. Device Queries Value Description device-desktop Apply only on desktop device-tablet Apply only on tablet device-phone Apply only on phone Table 3. Density Queries Value Description density-very-low Very low density 176x220 and smaller density-low Low density up to 240x320 density-medium Medium density up to 360x480 density-high High density up to 480x854 density-very-high Very high density up to 1440x720 density-hd HD up to 1920x1080 density-560 Intermediate density for screens between HD to 2HD density-2hd Double the HD level density density-4k 4K level density You can combine media queries to increase the specificity.\nExample: Targeting only 4k Android tablets @media platform-and, device-tablet, density-4k { Label { font-size: 5mm; } } You can also combine more than one query of the same type to broaden the range of the query.\nFor example, targeting only HD, 2HD, and 4K Android tablets:\n@media platform-and, device-tablet, density-4k, density-2hd, density-hd { Label { font-size: 5mm; } } Further Reading: Media Queries Section of Codename One Wiki\nPlatform-Specific Font Scaling Problem Your app looks great except that on desktop, the fonts are a little too small. If you could only scale the fonts to be 25% larger on the desktop, your app would be perfect.\nSolution You can use font-scaling constants to scale all of the fonts in your stylesheet by a constant factor. You can use a \u0026ldquo;media-query-like\u0026rdquo; syntax to apply this scaling only on particular platforms, devices, or densities.\nExample: Scaling Fonts to be 25% larger on desktop #Constants { device-desktop-font-scale: \u0026#34;1.25\u0026#34;; } Tip: In most cases it is better to use standard media queries to apply styles which target specific platforms in a more fine-grained manner.\nFurther Reading: Font-Scaling constants section of the Codename One Wiki Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nThomasH99 — March 16, 2021 at 8:07 am (permalink) ThomasH99 says:\nGreat addition, really useful. Thanks!\nJavier Anton — March 24, 2021 at 9:06 am (permalink) Javier Anton says:\nThanks, I rely on themes at the moment and kind of dread migrating to CSS. I know the clock is ticking and you will switch off support for themes at some point, so resources like these are great\nThomasH99 — March 28, 2021 at 9:33 am (permalink) ThomasH99 says:\nJavier, I’m using CSS since quite some time, I found it easy to get started, and it’s a really nice way of working, especially with the live update (the simulator is updated as soon as you save the CSS file). This has made the workflow a LOT faster. The only slight concern I’ve come across is that since the CSS conversion creates every possible variation of the UIIDs (pressed ect), my generated .res becomes very big (280 uiids gives a .res of 400kb, no pictures). I define UIIDs for most of the individual elements based on their semantics and that might not be the best solution, but it makes it easy to tune individual styles whenever needed.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/customizing-themes-of-codename-one-apps/","summary":"\u003cp\u003eRecipes to customize the look and feel of Codename One apps using Themes, CSS, Styles, etc.\u003c/p\u003e\n\u003cp\u003eThe following recipes include tips on customizing the look and feel of Codename one apps using themes, CSS, styles, etc.\u003c/p\u003e\n\u003ch3 id=\"platform-specific-styling\"\u003ePlatform-Specific Styling\u003c/h3\u003e\n\u003ch2 id=\"problem\"\u003eProblem\u003c/h2\u003e\n\u003cp\u003eYou have used CSS to style your app, and it looks great on some devices but not on others. You want to change the font size of some styles, but only on specific devices.\u003c/p\u003e","title":"Customizing Themes Of Codename One Apps"},{"content":"\nWe’re thrilled to announce the immediate availability of Codename One 7.0 (AKA Video). This has been our most challenging release to date. We constantly shifted the release date due to constantly shifting requirements and pivotal changes.\nHighlights of this Release Here are the highlights of Codename One 7.0\nWebRTC Support This is probably one of the biggest challenges we took to date. We now have one of the best cross platform WebRTC implementations. This took a lot of work and proved to be a huge challenge in every single platform.\nBuild App With the new build app we want to change the process of building/working with Codename One. Right now it’s \u0026ldquo;just\u0026rdquo; a more unified settings/build experience but we plan to make it central to Codename One development. This will reduce the importance of the IDE plugins and of the build app.\nCEF Migration It’s now possible to use proper web APIs and debug web based code embedded in a Codename One application. This also finally removes the problematic JavaFX dependency we had for our simulator and desktop ports.\nCodeRad CodeRAD might end up being the biggest feature of this release. It’s a higher level approach for building Codename One apps that makes building elaborate apps much easier.\nNew Website and SSO This isn’t quite a Codename One feature but it’s a huge change to the way we handle builds, signups etc.\nOther Features Those were the highlights but there were also a few important smaller features. There are too many to list but here are some that you might find interesting:\n→ Sign in with Apple Support – this also includes some improvements to the OAuth support\n→ New KitchenSink Demo\n→ AudioRecorderComponent\n→ API to set video capture constraints\n→ Multiple fixes to ParparVM (used in the iOS port) mostly for Kotlin support and wider support of the Java API\n→ Dark Mode API\n→ Sheet Component\n→ SpanMultiButton Component\n→ Improved CSS Image Border support\n→ Tooltips Support\n→ Safe download even when minimized\n→ Labels (and their subclasses) now support badging\n→ Better Java to JavaScript interaction with postMessage\n→ Arrow dialogs now work in a cross platform way\n→ Radar Chart\n→ Async Media\nMoving Forward Codename One 8 will continue in some of the same directions but will also pivot strongly towards more open architectures.\nWe intend to build more upon the basic framework of Codename One Build. We think it’s better to use a single app to manage the build, settings and everything related to Codename One as opposed to using multiple plugins.\nThis will let us simplify the plugins and make them easier to update/maintain.\nWe also plan to migrate to Maven. This is already in progress and will materialize within the next couple of months. This will simplify some aspects of our build process and update/dependency management.\nWe will use CSS as the default framework effectively deprecating the designer approach. While the designer has many advantages ultimately CSS is the de-facto standard and with live CSS editing it’s a pretty compelling case.\nWe would also like to strengthen our desktop offering. We believe Codename One on the desktop has a unique value proposition for Java developers that no other framework offers at this time. This is especially true with our CEF support.\nFinally, we intend to make it easier to build Codename One from sources and work with the open source code that’s already available.\nHow Can You Help? If you think we are doing a good job and appreciate our help, please help us by:\n– Spreading the word\n– Edit our docs\n– Edit our sources and submit bug fixes\n– Signup/Upgrade your account\nIf your company can afford it, please take the time and upgrade to enterprise, this will allow us to work on the things that are important for your company!\nThanks for reading this far and if you have any thoughts/suggestions of any kind please let us know! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJavier Anton — February 6, 2021 at 11:15 pm (permalink) Javier Anton says:\nCongratulations and can’t wait to see where CN1 goes from here\nIMIENS CORP — February 9, 2021 at 8:26 am (permalink) IMIENS CORP says:\nThank you so much, for adding WebRTC !\nIMIENS CORP — February 9, 2021 at 8:33 am (permalink) IMIENS CORP says:\nBTW, any examples, docs on WebRTC ?\nShai Almog — February 10, 2021 at 2:06 am (permalink) Shai Almog says:\nNothing serious yet but initial stuff is in the project page: https://github.com/shannah/CN1WebRTC\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/introducing-codename-one-7-0-aka-video/","summary":"\u003cp\u003e\u003cimg alt=\"Codename One 7.0 - Video\" loading=\"lazy\" src=\"/blog/introducing-codename-one-7-0-aka-video/7.0-Video-1c.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’re thrilled to announce the immediate availability of Codename One 7.0 (AKA Video). This has been our most challenging release to date. We constantly shifted the release date due to constantly shifting requirements and pivotal changes.\u003c/p\u003e\n\u003ch3 id=\"highlights-of-this-release\"\u003eHighlights of this Release\u003c/h3\u003e\n\u003cp\u003eHere are the highlights of Codename One 7.0\u003c/p\u003e\n\u003ch3 id=\"webrtc-support\"\u003eWebRTC Support\u003c/h3\u003e\n\u003cp\u003eThis is probably one of the biggest challenges we took to date. We now have one of the best cross platform WebRTC implementations. This took a lot of work and proved to be a huge challenge in every single platform.\u003c/p\u003e","title":"Introducing Codename One 7.0 (AKA Video)"},{"content":"\nAt long last we’re entering code freeze for Codename One 7.0. This release cycle has been longer than it should have been because of many detours along the way.\nBut finally if all goes according to plan, version 7.0 should be out next Friday.\nThe code freeze won’t impact most of you as it’s mostly an artifact of our release cycle.\nWe will have the regular Friday release but will only have critical reviewed commits during this week. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJavier Anton — February 1, 2021 at 9:59 pm (permalink) Javier Anton says:\nI’m embarrassed to admit to how long I spend each day working with CN1. Thank you for all the effort, this project is a huge undertaking. You all deserve a gold medal for this\nAs I begin expanding my use of CN1, I keep needing more and more to append my final native sources and rebuild. This process takes considerable time, as each finished build needs to be edited so it ships with everything else (I am mainly talking about XCode extensions and capabilities here). I have no idea how it’d work, but it would be great if this process could be automated in one way or another. I get dizzy from having to do this each time I build.. sometimes for extremely small changes (since the built sources are illegible and can’t realistically be changed after they’ve come out of the build server). Anyway, just a thought, thanks again guys\nShai Almog — February 2, 2021 at 2:38 am (permalink) Shai Almog says:\nYou can use build hints and native code to customize the project for most intents and purposes e.g. ios.add_libs allows you to add frameworks from xcode. The idea is to get a fully functional app without requiring any customization after the fact.\nJavier Anton — February 6, 2021 at 11:33 pm (permalink) Javier Anton says:\nI’m still learning the ropes when it comes to XCode. In a specific example: where in my netbeans project should I put the code with a framework that contains a Share Extension (with my own code) in order for it to be picked up by the ios.add_libs build hint? Is this possible?\nShai Almog — February 7, 2021 at 1:58 am (permalink) Shai Almog says:\nI’m not familiar enough with share extensions but if you need a specific framework to be added just add it to the list in add_libs e.g. ios.add_libs=x.framework;y.framework;mylib.a\nJavier Anton — February 7, 2021 at 6:21 pm (permalink) Javier Anton says:\nI shall look into this, thanks\nFrancesco Galgani — February 2, 2021 at 4:57 pm (permalink) Francesco Galgani says:\nI use native interfaces extensively (which is the solution to the problem pointed out by Javier Anton). In my opinion, it would be very useful to add support for all Swift libraries and create a documentation on native interfaces that is more extensive and up-to-date than the current one. Wrapping some Android or iOS SDKs in Codename One is really difficult for me, I often go by trial and error and sometimes I’m forced to give up. A practical example is this one, in which I pointed out a problem that I don’t know how to solve (wrapping requires Swift support): https://stackoverflow.com/questions/65698741/current-support-status-of-webrtc-in-codename-one-and-antmedia-usage\nHowever, it’s not just a Swift support problem. It also takes very advanced knowledge of how Codename One works, which we simple developers don’t always have.\nShai Almog — February 3, 2021 at 3:13 am (permalink) Shai Almog says:\nWe did some deep dive tutorials on that but it’s hard to go deep as the ground is constantly shifting and you end up having to teach the native platforms themselves with all the related complexity. Unfortunately, there aren’t tricks in our quiver to solve that. It’s just hard trial and error until it works with the various native platforms. Ideally if you can package stuff as a POD or dependency then you’re 90% of the way to getting it working and most things should work that way.\nThe best tip is to send a build with \u0026ldquo;include native source\u0026rdquo; and build on the native platform then migrate your changes back to Codename One. This isn’t trivial but it gives you a good starting point.\nWe have an RFE on Swift in the issue tracker if I remember correctly. I’m not sure when we’ll get to it as our issue pipeline is pretty deep and our manpower is heavily committed to some deep tasks. This is also a pretty hard task to implement and will produce a sub-par result since Swift is inherently problematic with VMs due to ARC.\nJavier Anton — February 6, 2021 at 11:41 pm (permalink) Javier Anton says:\nWhat I meant by appending the native sources was adding Targets (Share Extensions, Notification Service/Content Extensions, etc) and modifying core files like delegate/view controller. I don’t think this can be accomplished using native interfaces please correct me if I am wrong. I also don’t know if using Targets will in some way solve your swift problem since each target can have either objc/swift and it all works together\nShai Almog — February 7, 2021 at 2:03 am (permalink) Shai Almog says:\nYou can inject sources to various files such as the delegates with build hints. If you look at the source code in git you’ll see various magical comments that generally contain the word \u0026ldquo;REPLACE\u0026rdquo; these are special comments that our build servers replace and we can give you a build hint to replace code in that area (some of these build hints are documented).\nJavier Anton — February 7, 2021 at 6:21 pm (permalink) Javier Anton says:\nI know, and thanks. I still need to inject code in areas where there aren’t build hint markers as well as remove existing code. This is mostly due to the fact that I am implementing my own push, so I am probably just an outlier\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/code-freeze-for-codename-one-7-0/","summary":"\u003cp\u003e\u003cimg alt=\"Codename One 7.0 - Video\" loading=\"lazy\" src=\"/blog/code-freeze-for-codename-one-7-0/7.0-Video-1c.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAt long last we’re entering code freeze for Codename One 7.0. This release cycle has been longer than it should have been because of many detours along the way.\u003c/p\u003e\n\u003cp\u003eBut finally if all goes according to plan, \u003cstrong\u003eversion 7.0 should be out next Friday\u003c/strong\u003e.\u003c/p\u003e\n\u003cp\u003eThe code freeze won’t impact most of you as it’s mostly an artifact of our release cycle.\u003c/p\u003e\n\u003ch2 id=\"we-will-have-the-regular-friday-release-but-will-only-have-critical-reviewed-commits-during-this-week\"\u003eWe will have the regular Friday release but will only have critical reviewed commits during this week.\u003c/h2\u003e\n\u003ch2 id=\"archived-comments\"\u003eArchived Comments\u003c/h2\u003e\n\u003cp\u003e\u003cem\u003eThis post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\u003c/em\u003e\u003c/p\u003e","title":"Code Freeze for Codename One 7.0"},{"content":"These top 10 best cross-platform app development frameworks in 2024 help app developers with code reusability, better ROI, easy maintenance and shorter time to market.\nWith the rapid advancements in technology in today’s highly competitive digital sphere, developers are continuously on a hunt for app development tools or frameworks that can make their job easier and minimize app development time and cost.\nConsequently, now in 2024, you will see that an overwhelming amount of cross-platform app development frameworks have emerged to bridge that demand. The increased frequency of search queries can be seen by looking at Google trends’ indicators from 2010 to date.\nWhat is a Cross-Platform App Development Framework? A cross-platform app development framework is a set of tools that allows you to build native or native-like apps for multiple platforms such as Android, iOS, Windows and Web with a single codebase.\nThis enables you to expand your reach to a much larger target audience on multiple platforms at a significantly reduced cost and less time.\nHere are some of the best open-source cross platform app development frameworks based on programming languages:\nProgramming Language Framework Java Codename One JavaScript React Native, Cordova, Ionic, NativeScript, Appcelerator Python Kivy, BeeWare C# Xamarin C++ Qt Ruby RubyMotion Dart Flutter Basic B4A Related 📝 How to Build iOS Apps with Java\nIs Cross Platform better than Native Development? Cross-platform vs Native development is a never-ending debate that has kept the tech community divided for many years. Both technologies are in a constant state of evolution. However, as platforms converge, the future seems to be more in favor of cross-platform.\nTo give you an overview, let’s look at the comparison between native and cross-platform across various important factors.\nFactors Native App Development Cross-Platform App Development Architecture Different apps for different platforms One app for multiple platforms Cost High cost of development Relatively low cost of development Code Reusability Almost none, code works for a single platform Single code can be used on multiple platforms, for an easy portability Hardware Access Complete hardware accessibility with platform SDKs Limited access to all device APIs UI/UX Consistent \u0026amp; platform specific UI/UX Unified UI/UX for all platforms with limited consistency Performance Seamless, fully native performance High performance, native-like Target Audience Limited to a specific platform Reach a large number of users Time to Market More time required as need to write different code Significantly reduced time to market due to single codebase Team Size Large (different resources for different platforms) Small (1 for all platforms) 👨‍💻 Looking for Cross-Platform Developer Jobs?\nWhat are the Benefits of Cross-Platform App Development Frameworks? Here are some of the upsides of cross-platform app development frameworks.\nCode Reusability Possibly the biggest upside of cross-platform app development frameworks is code reusability. Developers just need to code once and that codebase can be reused to deploy the app to multiple platforms. This concept is commonly referred to as \u0026ldquo;Write Once Run Anywhere\u0026rdquo; or WORA.\nWORA eliminates repetition, and in turn, saves operational costs. A shared codebase also allows you to add another platform at a later point without too much effort.\nReduced Costs \u0026amp; Resources Cross-platform app development frameworks help you find a good balance between quality and cost by allowing you to be agile while utilizing a smaller team with one skill set and codebase for multiple platforms.\nIt’s simple math: Less time, resources, and efforts spent on app development is directly proportional to lower costs.\nEasy Deployment \u0026amp; Maintenance Since there’s a single codebase for multiple platforms, developers only need to write and maintain just a single source code. This translates to easy and fast deployment, maintenance, updates, and bug fixes.\nWhen updates are made to the code, they are synced over multiple platforms and devices instantly, saving time and effort.\nWider Market Reach Cross-platform frameworks give you maximum exposure to your target audience by allowing you to deploy your app on multiple platforms i.e. Android, iOS, Windows, MacOS, Web etc. This ensures a wider market reach to potential users.\nUniform Design Cross-platform frameworks make it easier to share a unified UI/UX across different platforms, while still respecting platform-specific standards. Offering users a consistent experience will help them easily recognize and interact with the app on any platform.\nTop 10 Best Cross-Platform App Development Frameworks in 2024 There are many cross-platform app development frameworks out there, having their own pros and cons.\nHowever, there’s NO one size fits all framework for cross-platform app development. Everything comes down to your preferred programming language and the platforms you want to target.\nChoosing the right tool can be a daunting task. We have tried our best to be as unbiased as possible while making this list of the top 10 best cross-platform app development frameworks in 2024.\nCross-Platform Frameworks Based on Programming Languages Java/Kotlin\nCodename One\nJavaScript \u0026amp; HTML5\nReactNative\nIonic\nNativeScript\nCordova\nAppcelerator\nDart\nFlutter\nC#\nXamarin\nC++\nQt\nRuby\nRubyMotion\nFollowing parameters were considered while putting this list together:\n– Performance \u0026amp; popularity – Code reusability – Plugins, integrations \u0026amp; components – Ease of learning – Community support \u0026amp; documentation – Ability to access device capabilities 1. React Native Launched in 2015, React Native is Facebook’s open-source cross-platform mobile app development framework. It uses JavaScript and React.js libraries to build apps for Android, iOS, Mac, Windows and the Web.\nReact Native is based on Facebook’s JavaScript library React, which renders to native platform UI. React Native is a great choice for simple apps where the APIs have a clear bridge between platforms. However, for complex apps, native code is often needed to bridge any gaps in functionality.\nThe Stack Overflow Developer Survey Results 2019 listed React Native in the category of dreaded frameworks for the first time.\nProgramming Language: JavaScript\nFamous Apps: Facebook, Bloomberg, Walmart, Uber and Shopify.\nAvg. App Development Cost: The average cost of React Native app development ranges from $15 to $25 per hour.\nRecommended Course: The Complete React Native + Hooks Course ($95)\nArchitecture: The following diagram shows a high-level view of the React Native application architecture.\nSource: React Native’s new Architecture\nReact Native Pros React Native Cons React Native\u0026rsquo;s focus on UI is to a great extent, rendering a highly responsive interface. React Native is not a truly cross-platform framework. Code is not 100% reusable across platforms, depending on the app’s complexity. Rich variety of built-in and community driven components and APIs save development time. When it comes to releasing of updates, React Native lacks consistency. Fast Refresh feature enables developers to see changes made in code within seconds. React Native apps are not efficiently optimized for speed and memory use. React Native is supported by contributions from developers and companies around the world. It has one of the highest number of contributors for any repository in GitHub. React Native\u0026rsquo;s dependency on third-party libraries is on the higher side. 2. Xamarin Launched in 2011 and acquired by Microsoft in 2016, Xamarin is an open-source cross-platform app development framework that uses C# language, .Net framework and Visual Studio to build apps for Android, iOS, macOS, and Windows (UWP).\nXamarin offers great compile-time checking which allows developers to experience fewer run-time errors. Xamarin also makes it easy to design a native-like app with its native friendly interface and controls assisting.\nXamarin integrates with Visual Studio which is a Microsoft’s IDE for the .NET Framework, allowing Visual Studio to be used for creating applications for Android, iOS and Windows.\nProgramming Language: C#\nFamous Apps: UPS, Alaska Airlines, Microsoft News and BBC Good Food.\nAvg. App Development Cost: The average cost of Xamarin developers ranges from $20 to $50+ per hour.\nRecommended Course: The Complete Xamarin Developer Course: iOS And Android!\nArchitecture: The following diagram shows a high-level view of the Xamarin application architecture.\nSource: What is Xamarin\nXamarin Pros Xamarin Cons Allows sharing up to 90% of your code across platforms for \u0026ldquo;Write Once, Run Anywhere\u0026rdquo;. Depending on complexity, Xamarin apps are typically larger in size than native ones. Platform-specific UI elements with Xamarin.Forms delivers consistent look across different OS. Xamarin is not recommended for apps that demand rich graphics. A UX/UI-heavy app is advised to be implemented natively. Xamarin supports linking with native libraries and uses platform-specific APIs. Xamarin has limited access to certain important open source libraries. Xamarin has a strong community of over 60,000 contributors from more than 3,700 companies. Xamarin is free for individuals and startups. However, enterprises are required to buy a license for Microsoft’s Visual Studio. 3. Codename One Created by the co-founders of the LWUIT project in 2012, Codename One is the leading open source Write Once Run Anywhere (WORA) framework to build native apps for iOS, Android, Desktop and Web with Java or Kotlin.\nCodename One is a revolutionary mobile development solution started by ex-Sun Microsystems developers based on the work that started within Sun.\nIts core appeal is its unrestricted access to the native platform allowing developers to write native code directly from Java or Kotlin and access everything that the native mobile platform can provide.\nRelated: Codename One comparison with other frameworks\nProgramming Language: Java or Kotlin\nApps made with Codename One: Muving, yHomework, HBZ, CIPC, Oxbridge Academy \u0026amp; Hyundai Smart Care.\nAvg. App Development Cost: The average cost of Java developers ranges from $30 to $60 per hour.\nRecommended Course: Codename One Academy (Free \u0026amp; Paid courses)\nArchitecture: The following diagram shows a high-level view of the Codename One application architecture.\nSource: Introduction to Codename One\nCodename One Pros Codename One Cons Write Once Run Anywhere (WORA) support with no special hardware requirements and 100% code reuse. Not suitable for elaborate games such as FPS. The framework and related tools were designed from the start focused around apps. Codename One has plugins for popular IDEs such as IntelliJ/IDEA, NetBeans and Eclipse. Codename One\u0026rsquo;s graphic UI does not match the requirements of large projects and its visual themes are not updated. Codename One is easy to use with 100% portable Drag \u0026amp; Drop GUI builder. Due to the storage of all event handlers in a single file, development part is cumbersome. Codename One can be extended easily using 3rd party libraries (cn1libs) that can include native OS code. While it\u0026rsquo;s possible to build without the cloud build server, in case if its needed, then there\u0026rsquo;s a monthly quota of builds. Codename One’s cloud build allows developers to build native applications using cloud servers. This removes the need to own dedicated hardware. 4. Flutter Developed and released by Google in 2017, Flutter is a popular open source and free cross-platform framework. It uses Dart language to develop apps for Android, iOS, Mac, Windows, Linux and the Web from a single codebase.\nFlutter has a strong following in the cross-platform community as its a versatile SDK for mobile app development. The Stack Overflow developer survey 2020 results suggests that Flutter is the third-most loved framework.\nFlutter framework, as well as Dart language, hasn’t been around for long, which is why it’s still not entirely stable and mature.\nProgramming Language: Dart\nFamous Flutter Apps: Google, eBay, Alibaba and BMW\nAvg. App Development Cost: The average cost of Flutter app development ranges from around $15 to $50 per hour.\nRecommended Course: Flutter \u0026amp; Dart – The Complete Guide ($131)\nArchitecture: The following diagram shows a high-level view of the Flutter application architecture.\nSource: Flutter Architecture\nFlutter Pros Flutter Cons Flutter is easy to learn, simple to build and debug with, and is fully compiled. Dart is a less popular programming language and the Hot Reload feature works only with Dart. Flutter has a full set of widgets in Google’s Material Design and in Apple’s style with the Cupertino pack. Flutter doesn\u0026rsquo;t support all the devices. It won\u0026rsquo;t run on your 32-bit laptop seamlessly. Hot Reload feature enables developers to see changes made in code within seconds. There are fewer third-party packages available to support Flutter apps on multiple platforms. Flutter\u0026rsquo;s community of developers is active and evolving, proactively helping developers in solving problems related to the platform. Flutter is suitable for MVP and startups. For large-scale projects, you will have to proceed smartly. Flutter is relatively new and growing. You will find little proven expertise in the market. Flutter apps are relatively bigger in size. 5. Ionic Released in 2013, Ionic open-source framework leverages web technologies such as HTML, CSS, and JavaScript with integrations for frameworks such as Angular, React and Vue to build hybrid mobile, desktop, and Progressive Web Apps.\nIonic framework uses a SaaS UI and is fundamentally built on Cordova. It uses Cordova and Capacitor plugins to gain access to native OS features such as Camera, GPS, Flashlight, etc.\nIonic has its own IDE known as Ionic Studio. Ionic also offers features such as code deploys, automated builds, lazy loading, Ionic CLI, etc.\nProgramming Languages/Frameworks: JavaScript, Angular, React and Vue.js\nFamous Apps: NHS, EA Games and Southwest Airlines.\nAvg. App Development Cost: The average cost of Web or AngularJS developers ranges from $25 to $150+ per hour.\nRecommended Course: Ionic – Build iOS, Android \u0026amp; Web Apps with Ionic \u0026amp; Angular\nArchitecture: The following diagram shows a high-level view of the Ionic application architecture.\nSource: What is Ionic\nIonic Pros Ionic Cons Based on well-known technologies i.e. Angular, HTML, CSS and JavaScript. If one wants to go beyond basic apps, knowledge of AngularJS becomes almost a necessity. Compatability with React, Angular and Vue frameworks and supports Cordova plugins. Performance of apps built with Ionic is on a lower side. Ionic has a wide range of tools, plugins and UI components. Building in-app navigation is difficult because of its complex UI-router. Ionic is backed by a vibrant community of developers and sufficient documentation. High dependency on plugins. Some native plugins aren\u0026rsquo;t stable and can conflict with each other. 6. Cordova Apache Cordova (formerly PhoneGap) is an open source framework that utilizes HTML, CSS, and JavaScript to build hybrid web apps for Android, iOS and Windows.\nApache Cordova is the open source fork of the PhoneGap project which was acquired by Adobe in 2011. Adobe later discontinued PhoneGap in 2020.\nApps built with Cordova are hybrid, meaning that they are neither truly native nor purely Web-based. Cordova enables wrapping up of HTML, CSS and JavaScript depending upon the platform of the device.\nCordova apps rely on standards-compliant API bindings to access each device’s capabilities such as data, sensors, network status, etc.\nProgramming Language: HTML, CSS \u0026amp; JavaScript.\nFamous Apps: Pacifica, Sworekit, FanReact \u0026amp; JustWatch.\nAvg. App Development Cost: The average cost of Web developers ranges from $30 to $80+ per hour.\nRecommended Course: Apache Cordova Fundamentals\nArchitecture: The following diagram shows a high-level view of the Cordova application architecture.\nSource: Apache Overview\nCordova Pros Cordova Cons Based on well-known technologies i.e. HTML, CSS and JavaScript. Cordova apps are slower than native mobile apps due to the cross-compilation process. Compatible with a variety of third-party plugins and APIs. Also supports custom plugins. Developers find it daunting to find plugins based on their precise needs. The command line syntax is easy to learn and implement. Not recommended for high-performance and hardware intensive apps due to poor performance and lack of UI Widgets. Easy to setup, develop, adding platforms and deploying apps for multiple platforms. Supporting different devices can become very difficult. 7. NativeScript Released in 2015, NativeScript is an open-source framework that allows you to build native Android and iOS apps using JavaScript, TypeScript, Angular or Vue.js.\nNativeScript allows developers to access native Android and iOS APIs and render platform-native UI. While the app source code is written in web languages, NativeScript apps run directly on the native device without using WebViews or DOM manipulation.\nNativeScript’s major components include Runtimes, Core Modules, CLI and Plugins. The Runtimes call the native APIs using JavaScript. Core Modules provide abstractions to access native platforms. The CLI allows to create, build, and run apps using NativeScript. And the Plugins form the building blocks of NativeScripts for faster development.\nProgramming Languages/Frameworks: JavaScript, TypeScript, Angular and Vue.js\nFamous Apps: Strudel, BitPoints, Daily Nanny \u0026amp; Dwitch.\nAvg. App Development Cost: The average cost of NativeScript specialists ranges from $40 to $120+ per hour.\nRecommended Course: NativeScripting (Free \u0026amp; Paid courses)\nArchitecture: The following diagram shows a high-level view of the NativeScript application architecture.\nSource: How NativeScript Works\nNativeScript Pros NativeScript Cons Based on well-known web technologies i.e. JavaScript, TypeScript, Angular and Vue.js NativeScript is not a truly cross-platform framework. Code is not 100% reusable across platforms, depending on the app’s complexity. Gives access to native Android and iOS APIs. NativeScript runs everything on a single thread which can lead to the apps feeling slower. Renders platform-native UI without relying on WebViews. No hot-reload feature to preview instant code changes without an app restart. Large repository of plugins and pre-built app templates. The app size could be reduced to be more in line with pure native and other similar frameworks. NativeScript is 100% free and open source. Due to the many different ways you can write NativeScript apps, the documentation is not always accurate. 8. Titanium SDK Released in 2008, Appcelerator Titanium is an open-source cross-platform native app development framework for building iOS, Android and Windows apps with JavaScript.\nThe core features of Titanium SDK includes a cross-platform API for accessing native UI and device functionality, direct access to native APIs using Hyperloop and MVC-based framework Alloy.\nAppcelerator offers pre-built integrations with Salesforce, MS Azure, MS SQL, MongoDB and Box. It also offers ArrowDB, a schema-less database that allows developers to deploy data models with no setup efforts.\nAxway acquired Appcelerator and its open-source cross platform application framework, Titanium in 2016.\nNote: Axway announced \u0026lsquo;End-of-Support\u0026rsquo; for Titanium effective March 1, 2022.\nProgramming Language: JavaScript.\nFamous Apps: Body Shop, CBC Media, MIT \u0026amp; Pulse.\nAvg. App Development Cost: The average cost of Appcelerator Titanium specialists ranges from $40 to $70+ per hour.\nRecommended Course: Beginner Mobile App Development with Appcelerator Titanium\nArchitecture: The following diagram shows a high-level view of the Appcelerator Titanium application architecture.\nSource: Titanium Platform Overview\nAppcelerator Titanium Pros Appcelerator Titanium Cons JavaScript compiles to native code with no hybrid compromises. Limited code reusability (60-90%) across platforms. Direct access to native APIs using Hyperloop. The development complexities and costs rise as app complexity increases. Access to native UI across platforms with Alloy. Appcelertor Titanium often requires that you rewrite your UI (roughly 50% of the code) for every platform. Schema-less ArrowDB with no setup efforts. Titanium apps are often slower and laggy with animations and responsiveness. Growing community of developers. Errors are usually not detected until runtime. 9. Qt Released in 1995, Qt is an open-source widget toolkit for creating cross-platform apps and GUIs for Android, iOS, Windows, macOS, Linux and embedded systems using C++.\nQt is used for developing cross-platform apps and graphical user interfaces (GUIs) that run on most mobile, desktop or embedded platforms. Qt supports compilers such as Visual Studio, GCC compiler and PHP via an extension.\nQt tools include the Qt Creator IDE for C++ and Qt Quick which includes a declarative scripting language called QML. Other Qt features include XML parsing, JSON parsing, SQL database access and thread management.\nProgramming Language: C++.\nQt use cases: Spotify, Malwarebytes, VLC Player, Google Earth etc.\nAvg. App Development Cost: The average cost of Qt developers ranges from $30 to $70+ per hour.\nRecommended Course: Qt 5 Core for Beginners with C++\nArchitecture: The following diagram shows a high-level view of the Qt application architecture.\nSource: Qt Architecture\nQt Pros Qt Cons Qt is mature and stable. It has been vetted by major companies. The time to market is long without using Qt Quick Compiler, which is only available with the Commercial license. It is a well-designed C++ GUI application framework. Mobile UX is far from being smooth. When using default QT GUI components you do not get an ideal look and feel for iOS and Android. The code is compiled to native binaries that run at full speed (no need to use a virtual machine) There is no official Qt support for mainstream Ad Networks (only 3rd party libraries, if available) Qt\u0026rsquo;s IDE, Qt Creator is very capable and works on all platforms. QT requires licensing fees for distribution. If you stop paying the monthly licensing fee, you need to stop distributing the apps you’ve already built. Qt has huge user base and documentation. It\u0026rsquo;s easy to get answers to questions. The QObject and QWidget are not thread-safe. 10. RubyMotion Released in 2012, RubyMotion is a partially open-source framework for creating cross-platform native apps for Android, iOS and MacOS using Ruby.\nRuby programming language is mainly used for web development. However, with RubyMotion, mobile apps can be made using Ruby.\nRubyMotion is based on MacRuby, an implementation of Ruby created and maintained previously at Apple. RubyMotion adapted and extended MacRuby to work on platforms beyond MacOS.\nApps written in RubyMotion call into the native platform APIs and function in the same manner as platform native language. RubyMotion apps are created from the terminal command-line using any text editor.\nProgramming Language: Ruby.\nApps made with RubyMotion: A Dark Room, Jimdo, Bandcamp, Jukely \u0026amp; Frontback.\nAvg. App Development Cost: The average cost of Ruby developers ranges from $30 to $80+ per hour.\nRecommended Course: Getting Started with RubyMotion\nArchitecture: The following diagram shows a high-level view of the RubyMotion application architecture.\nSource: Getting To Know RubyMotion With Laurent Sansonetti\nRubyMotion Pros RubyMotion Cons Ruby as a language for mobile development environment. RubyMotion is not open-source. It\u0026rsquo;s a commercial partially open-source product. RubyMotion apps are statically compiled and call into the native platform APIs. RubyMotion requires separate GUI code for Android and iOS. RubyMotion apps can be extended with Gems (reusable components). It\u0026rsquo;s hard debug with RubyMotion. CocoaPods and Gradle are supported natively. RubyMotion\u0026rsquo;s free version is limited. Terminal + Editor of choice workflow. RubyMotion needs better documentation for beginners. Frequently Asked Questions (FAQs) What is a cross-platform framework?\nA cross-platform app development framework is a set of tools that allows you to use a single codebase to build native or native-like apps for multiple platforms such as Android, iOS, Desktop and Web.\nHow to choose a cross-platform framework?\nChoosing the right cross-platform framework comes down to your preferred programming language and the platforms you want to target. There’s NO one size fits all framework for cross-platform app development.\nWhat programming language is best for cross platform app development?\nThere is no one best programming language for cross-platform development. Which language to use for a particular app depends on the type of app, development team, and the specific project requirements.\nProgramming languages such as Java, C++ and JavaScript are widely considered preferred languages for cross-platform app development.\nWhat are the benefits of cross-platform app development?\nBenefits of cross-platform app development includes:\nCode Reusability\nReduced Costs \u0026amp; Resources\nEasy Deployment \u0026amp; Maintenance\nWider Market Reach\nUniform Design\nWhat are the cons of cross-platform app development?\nDisadvantages of cross-platform app development includes:\nPerformance issues\nDifficult to build an optimal UI/UX\nLimited access to hardware\nLong wait time for new features\nCode losses if switching to another platform\nHow much does it cost to make a cross-platform app?\nCross-platform app development is less costly as compared to native app development since there\u0026rsquo;s a single codebase, they\u0026rsquo;re quicker to develop and take less QA effort.\nCross-platform apps usually cost $30 to $80+ per hour depending on the requirements and complexity.\nHow long does it take to make a cross-platform app?\nCompared to native apps, cross-platform apps take less time to develop and deploy since there’s only a single codebase for multiple platforms that developers need to write and maintain.\nThe development time of cross-platform apps depends on several factors such as the complexity, target platforms and technical skills.\nFinal Thoughts Cross-platform app development is the obvious route if you’re looking for code reusability, budget savings, easy maintenance and quick deployment as opposed to native development.\nCross-platform development also makes your code simpler and faster to read, write, maintain, debug, re-use and scale.\nWhen choosing the best cross-platform app development framework, there’s NO one size fits all tool. What’s the best framework for you really depends on your technical skills, preferred programming language, project requirements and the platforms you want to target. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nFrancesco Galgani — January 25, 2021 at 1:29 pm (permalink) Francesco Galgani says:\nI thank you for this very interesting article.\nThe document included in an iframe (Google trends’ indicators) is not visible.\nIt’s very nice to find this overview about cross platform tools right on Codename One blog.\nThe discussion on the pros and cons could be expanded, but the considerations would still be subjective and related to their own development experience. Certainly, Codename One allows with few resources and few people to do what otherwise would require many more resources and many more people.\nVitali Kuptsov — May 31, 2021 at 1:56 pm (permalink) Vitali Kuptsov says:\nThank you for your article! I wouldn’t be sure for Cordova as imo it’s not as great as it used to be due to new frameworks that really surpass it. For example, Flutter which you also mentioned. Flutter definitely wins with its HotReload and automated testing, and more native UI. I’ve read about it recently in this article [link removed], and it looks quite convincing.\nShai Almog — May 31, 2021 at 2:25 pm (permalink) Shai Almog says:\nI removed your link since it appears to be SEO related. FYI Codename One supports hit reload etc. This isn’t such a unique feature.\nMuminjon Abduraimov — August 22, 2021 at 8:40 pm (permalink) Muminjon Abduraimov says:\nDelphi and C++ Builder with FireMonkey Framework should also be here! 🙂\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/top-10-best-cross-platform-app-development-frameworks-in-2024/","summary":"\u003cp\u003eThese top 10 best cross-platform app development frameworks in 2024 help app developers with code reusability, better ROI, easy maintenance and shorter time to market.\u003c/p\u003e\n\u003cp\u003eWith the rapid advancements in technology in today’s highly competitive digital sphere, developers are continuously on a hunt for app development tools or frameworks that can make their job easier and minimize app development time and cost.\u003c/p\u003e\n\u003cp\u003eConsequently, now in 2024, you will see that an overwhelming amount of cross-platform app development frameworks have emerged to bridge that demand. The increased frequency of search queries can be seen by looking at Google trends’ indicators from 2010 to date.\u003c/p\u003e","title":"Top 10 Best Cross Platform App Development Frameworks in 2024"},{"content":"Spring Boot is an open source Java framework used to create micro services. Learn why you should learn Spring Boot in 2021?\nWhat is Spring Boot? Spring Boot is a lightweight framework for Java developers to develop stand-alone and production-grade spring applications that \u0026ldquo;just run\u0026rdquo;.\nSpring Boot shortens the Spring framework code length and provides you with the easiest way to develop an application with minimum configurations.\nYou can call it a framework of framework as it supports many frameworks such as Hibernate, EJB (Enterprise Java Bean) etc.\nImage Source: Spring Boot 01 (Dependency Injection)\nWhy Spring Boot? Spring Boot removes a lot of hassle and boilerplate from Java coding. It makes Java code fluid and concise without trading scalability.\nSpring Boot offers many advantages to developers such as:\n– Easy to understand and develop spring applications. – Increases productivity: Flexible configuration of Java Beans, XML, and Database Transactions. – Reduces the development time: Everything is auto configured. Learn Spring Boot We have partnered with Packt Publishing to bring Java developers a beginner friendly Udemy course that aims to help you quickly build and deploy production-ready microservices within the Java and JVM ecosystem using Spring Boot 2.\nSpring Boot 2 Fundamentals - Udemy Happy learning! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved here for historical context. New discussion happens in the Discussion section below.\nFrancesco Galgani — January 7, 2021 at 11:32 am (permalink) Francesco Galgani says:\nI have known for the first time and learned Spring Boot following Shai’s courses in the Codename One Academy and deepening on my own: in fact, at the beginning it was an uphill path rather difficult, but now I can say that Codename One + Spring Boot are my daily bread to make \u0026ldquo;real\u0026rdquo; applications. Perhaps my greatest demonstration of how Codename One + Spring Boot is a winning combination is when I made a desktop application for Windows in just one day, an application still used today, which is a small backend for a website made by me (obviously I had a lot of code ready because I used it in other projects, otherwise it would not have been possible). It needs a lot of study and patience to use Codename One + Spring Boot.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/why-you-should-learn-spring-boot-in-2021/","summary":"\u003cp\u003eSpring Boot is an open source Java framework used to create micro services. Learn why you should learn Spring Boot in 2021?\u003c/p\u003e\n\u003ch3 id=\"what-is-spring-boot\"\u003eWhat is Spring Boot?\u003c/h3\u003e\n\u003cp\u003eSpring Boot is a lightweight framework for Java developers to develop stand-alone and production-grade spring applications that \u0026ldquo;just run\u0026rdquo;.\u003c/p\u003e\n\u003cp\u003eSpring Boot shortens the Spring framework code length and provides you with the easiest way to develop an application with minimum configurations.\u003c/p\u003e\n\u003cp\u003eYou can call it a framework of framework as it supports many frameworks such as Hibernate, EJB (Enterprise Java Bean) etc.\u003c/p\u003e","title":"Why You Should Learn Spring Boot in 2021?"},{"content":"We have recently released a new tool named Control Center. Some of you may ask why have we released a new tool? You already have quite a few: IDE plugins, builds dashboard, preferences app, simulator, designer, GUI builder and more.\nWhy? Well the main reason behind this new app is exactly because we have plenty of tools.\nThe new Control Center App’s aim is to consolidate the many tools we have which will make your life easier and ours much easier to release updates and to introduce new features and support.\nWhat’s in it? The first version we are releasing contains the preferences app, the builds dashboard and the support channel. Moving forward we plan to enhance it and move more of the tools into this App.\nPlease feel free to send us feedback and suggestions how to improve\nHappy coding! and a Happy New Year!\nScreenshots Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — December 31, 2020 at 3:35 pm (permalink) Francesco Galgani says:\nHappy New Year to all Codename One staff and developers!\nCodename One has become an important part of my life for years now… I wish all of us developers to realize our dreams.\nHappy 2021!\nJavier Anton — January 10, 2021 at 9:42 pm (permalink) Javier Anton says:\nA bit late, but happy new year to you too Francesco. CN1 has also dug a hole in my heart, here’s to a great 2021 for all developers and of course for CN1!\nJavier Anton — January 11, 2021 at 6:32 pm (permalink) Javier Anton says:\nI can’t click on the \u0026ldquo;Control Center\u0026rdquo; link. I also can’t find the tool on the website\nChen Fishbein — January 12, 2021 at 8:51 am (permalink) Chen Fishbein says:\nThe \u0026ldquo;Control Center\u0026rdquo; App replaces the settings app, it is accessible from the IDE plugins.\nSelect the \u0026ldquo;CodenameOne Settings\u0026rdquo; from the plugin.(notice if you still see the old settings do an \u0026ldquo;update\u0026rdquo; from the Settings app menu and restart the app).\nColin Forster — March 15, 2021 at 2:21 am (permalink) Colin Forster says:\nI can’t login via the Control Center. The Login button responds to the click (as in the button colour changes) but nothing happens.\nIs there any log files I can check which might shed more light?\nLinux Mint 20\nIntelliJ IDEA 2020.3 CE\nLet me know if you need any more clarification.\nShai Almog — March 15, 2021 at 3:34 pm (permalink) Shai Almog says:\nThanks for the headsup. We’ll try to fix it for the next update of the tool.\nColin Forster — March 17, 2021 at 6:48 am (permalink) Colin Forster says:\nI managed to get it working again by re-installing the ide (and therefore cn1 plugin). Thanks for the prompt reply.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-control-center-desktop-app/","summary":"\u003cp\u003eWe have recently released a new tool named Control Center. Some of you may ask why have we released a new tool? You already have quite a few: IDE plugins, builds dashboard, preferences app, simulator, designer, GUI builder and more.\u003c/p\u003e\n\u003ch3 id=\"why\"\u003eWhy?\u003c/h3\u003e\n\u003cp\u003eWell the main reason behind this new app is exactly because we have plenty of tools.\u003c/p\u003e\n\u003cp\u003eThe new Control Center App’s aim is to consolidate the many tools we have which will make your life easier and ours much easier to release updates and to introduce new features and support.\u003c/p\u003e","title":"Codename One Control Center Desktop App"},{"content":"Hello Codename One community, my name is Sergey Gerashenko. I’m a junior software developer at Codename One. My journey here began 3 months ago when I passed my first interview at Codename One and my first task was to learn Java within 2 weeks.\nLearning Java I knew a few programming languages like Python, C and C++ but was unfamiliar with Java or managed languages beforehand.\nLearning a completely new language in just two weeks seemed like an impossible task at first because it took me around five months to learn C++.\nI joined this Java course on Udemy and started learning immediately.\nMy first impression of Java was great. It reminded me of C++ but much easier to understand and work with. After two weeks I felt confident with Java and started my work at Codename One.\nMy first task was to update the Kitchen Sink cross-platform demo application to demonstrate all the main usages of Codename One framework.\nThe First Week My first week at the new job was a mess. The problem was that I came from the Real Time and Embedded background. I had never used Codename One or any other UI tools before and had a knowledge gap.\nI tried learning by watching tutorial videos on Codename One Academy but it was a bit difficult for someone without UI development experience.\nIn the beginning, I didn’t understand some common terms and jargons and I had to Google my way around in order to get a good grasp of things. At the end of the first week, I was asked to show my progress.\nI barely wrote 100 lines of code (not the best ones). Even worst than that, I felt like I didn’t learn enough in the past week. In the second week, I decided to start from scratch. Now that I knew the basics, things became much easier.\nWhat Really Helped? I found the Codename One developer guide to be the best learning resource. It’s great for learning your way around the tool and understanding its components.\nIn the How Do I section I found some very helpful video tutorials that also helped a lot with learning common use cases, like the Layout basics video, and the How to convert a PSD Design into a Native Mobile App.\nAt that point, I was comfortable enough with a good foundation level knowledge and my work seemed much smoother and stress-free.\nLearning Kotlin I started to enjoy the process of building apps, and everything else in between. When my app was ready, I was asked to write the Kitchen Sink in Kotlin to demonstrate our Kotlin support.\nMy first impression of Kotlin wasn’t that great just as my first impression of Java. Kotlin syntax was a little bit different from those languages that I knew so far, but when I studied it more I started to see its real beauty.\nKotlin reminds me of Java but it seems more concise and readable after you get used to it. I spent the next two weeks on learning and writing the same Kitchen Sink app in Kotlin.\nThe process wasn’t too hard as Kotlin has great tools to convert Java code to Kotlin. Though it was far from perfect and I spent a lot of time to review the code and make the necessary changes.\nAfter two months of hard work, learning and just enjoying the process, my app was ready for deployment and I was ready for my next challenge.\nKitchen Sink The Codename One Kitchen Sink app is a great tool for those who want to start developing applications with Codename One tools.\nIt explains all the basic components of Codename One and demonstrates the most common uses of them. It also demonstrates more complicated uses of Codename One like the low-level graphics possibilities with a gorgeous Clock demo and the use of GoogleMaps lib.\nAnd even better, the app contains links to the source code of the project, so anyone can just download the code, see how they can use specific components, play with them and experiment.\nBut more importantly, users can see and learn about the application structure and how it needs to be written.\nArchived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\n[email protected] — December 26, 2020 at 2:56 pm (permalink) javierantonf says:\nLooking forward to having an extra hand on CN1, Sergey. Welcome 🙂\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/a-junior-software-developers-journey-at-codename-one/","summary":"\u003cp\u003eHello Codename One community, my name is Sergey Gerashenko. I’m a junior software developer at Codename One. My journey here began 3 months ago when I passed my first interview at Codename One and my first task was to learn Java within 2 weeks.\u003c/p\u003e\n\u003ch3 id=\"learning-java\"\u003eLearning Java\u003c/h3\u003e\n\u003cp\u003eI knew a few programming languages like Python, C and C++ but was unfamiliar with Java or managed languages beforehand.\u003c/p\u003e\n\u003cp\u003eLearning a completely new language in just two weeks seemed like an impossible task at first because it took me around five months to learn C++.\u003c/p\u003e","title":"A Junior Software Developer’s Journey at Codename One"},{"content":"[show_blogs_home]\n","permalink":"https://www.codenameone.com/testing-2/","summary":"\u003cp\u003e[show_blogs_home]\u003c/p\u003e","title":"testing"},{"content":"Today, we are finally integrating the new Single-Sign-On to most of our tools.\nThis means that you will need to create a new account using the login button in this site in order to use Codename One from now on.\nTo make the migration easier, we tried to keep the existing login working as much as possible with the one notable exception of password reset which is no longer wired. So if you lose your password, you would need to migrate.\nIf you’re creating a new account, this should be pretty seamless. Just use the product as it is.\nIf you already have a Codename One account (paid or otherwise) just signup as a new account by pressing Login and clicking register. Make sure to use the email address used for your existing account. You will get a confirmation email which you will need to click. At this point the new account and the old account will be bound. If you’re a paid subscriber things should \u0026ldquo;just work\u0026rdquo;.\nThis is the current status our various tools when it comes to the new login: **Website: **Already works with the new login system.\nBuild from IDE: This is launching on Friday the 27th of November.\nCodename One Settings: Settings still uses the old login. We hope to release an update in a couple of weeks.\n**Codename One Build On Web: **There are two versions of build. The old one here and the new login here.\nCodename One Build Mobile App: The Android app will be updated within a couple of weeks. It still uses the old login.\nAs always, please use the website chat to let us know if you’re experiencing difficulties. Notice this isn’t a live chat, we get email alerts and get back to you when available so it works best if you leave an email.\nComing Up… The Single Sign On work has taken up a lot of my time and made me a bottleneck for information and actual productivity. But there’s a lot going on while we’re doing this.\nNew build app : Chen has re-imagined the Codename One Build app and Settings as a hybrid console for Codename One. It looks stunning and we plan to launch it in the next couple of weeks.\nDiscussion forum : We hope to import the Google Group discussion forum into a website standard forum which will give us greater control. This is especially important due to recent changes from Google to the group interface and control.\nComments : We still don’t have website comments. Our web developer was having a hard time dealing with this and I was busy with SSO. We’ll try to get them up and about soon enough so we can return to our communicative selves. As of now we’re still up on the discussion forum and in stack overflow.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-sign-in-behavior/","summary":"\u003cp\u003eToday, we are finally integrating the new \u003cstrong\u003eSingle-Sign-On\u003c/strong\u003e to \u003cstrong\u003emost\u003c/strong\u003e of our tools.\u003c/p\u003e\n\u003cp\u003eThis means that you will need to create a new account using the login button in this site in order to use Codename One from now on.\u003c/p\u003e\n\u003cp\u003eTo make the migration easier, we tried to keep the existing login working as much as possible with the one notable exception of password reset which is no longer wired. So if you lose your password, you would need to migrate.\u003c/p\u003e","title":"Important: New Sign-In Behavior"},{"content":"\nWelcome to our new website. There are a lot of things that are still being worked on so please bare with us and let us know ASAP when something is broken. Comments are still disabled in the current site but we’ll import them and turn them on in the next few weeks.\nWith the new website we’re migrating to a Single Sign-On solution based onKeycloak. This means login for this website will go through that system. Right now it’s disconnected from our existing Codename One Build login but we intend to unify everything under Keycloak and your account would merge seamlessly (assuming you used the same email address).\nGoodby Paypal. Hello Paddle! One of the biggest complaints people have about signing up for Codename One’s paid subscription is our use of Paypal. To be fair, Paypal is pretty amazing. They have unparalleled global service and are pretty easy to integrate/work with.\nBut there are a lot of downsides such as limited ability to manage the payment settings, trigger payment, upgrade/downgrade etc. When developers ask us for help, we also have limited capabilities as Paypal manages their own system. Then there’s the matter of invoicing which becomes difficult for the various locales.\nEnter Paddle Paddle solves most of these problems. It’s also simple to integrate and it works as a reseller not as a billing service. So effectively, you’re buying our service from a 3rd party reseller who handles invoicing and all the complexities. That means you can use your local currency and get local invoices without a problem.\nIt also gives us the power to fix your account.\nWant to upgrade/downgrade?\nNo more waiting to the end of the month, our support team in the website chat can do that immediately.\nRight now upgrade/downgrade isn’t self service yet, but we’ll hopefully add that in the future.\nNotice that Paypal is one of the supported payment methods for Paddle so you can still use your Paypal account if you choose to.\nSince we’re in a transition period, Paddle is used when subscribing through the website and Paypal is used when subscribing via the dashboard. We’ll fix everything to use Paddle and keycloak SSO in the near future.\nExisting Paypal Subscriptions If you have an existing Paypal/SWIFT subscription, everything should keep working as it did before. There should be no change and we won’t force you to migrate.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-website-sso-and-payment-processing/","summary":"\u003cp\u003e\u003cimg alt=\"Codename One - New Website, SSO and new Payment Processing\" loading=\"lazy\" src=\"https://beta.codenameone.com/wp-content/uploads/2020/11/Single-Sign-On.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWelcome to our new website. There are a lot of things that are still being worked on so please bare with us and let us know ASAP when something is broken. Comments are still disabled in the current site but we’ll import them and turn them on in the next few weeks.\u003c/p\u003e\n\u003cp\u003eWith the new website we’re migrating to a \u003cstrong\u003eSingle Sign-On solution\u003c/strong\u003e based on\u003cstrong\u003eKeycloak\u003c/strong\u003e. This means login for this website will go through that system. Right now it’s disconnected from our existing Codename One Build login but we intend to unify everything under Keycloak and your account would merge seamlessly (assuming you used the same email address).\u003c/p\u003e","title":"New Website, SSO \u0026 Payment Processing"},{"content":"This is the second is a series of blog posts hightlighting some of the components available in the CodeRAD cn1lib. The first post (or series of posts) introduced the RAD Chatroom component, a rich 2nd order UI component that encapsulates the user interface for a fully functional chat room.\n__ A second-order UI component is a complex UI component, usually composed of multiple basic components, which is designed for a specific type of application. Some examples of second-order UI components are login forms, contacts lists, chat room components, news lists, etc.. In this post I share a much simpler, first-order component: The HelpButton. The HelpButton is just a button that displays a \u0026ldquo;Help\u0026rdquo; or \u0026ldquo;Error\u0026rdquo; icon. When the user clicks on this button, it pops up with some \u0026ldquo;help\u0026rdquo; text.\nUsage Example The following is the snippet that was used to generate the above screen capture:\nForm hi = new Form(\u0026quot;Hi World\u0026quot;, BoxLayout.y()); HelpButton btn = new HelpButton(\u0026quot;This is some help text to give you some hints\u0026quot;); hi.add(FlowLayout.encloseIn(new Label(\u0026quot;Hi World\u0026quot;), btn)); hi.show(); There really isn’t much to this component, but it is a handy addition to the toolbox nonetheless.\nTo use the HelpButton component you’ll need to add the CodeRAD cn1lib to your project, which is available in through Codename One preferences. For instructions on adding cn1libs to your projects, see this tutorial. For more information about CodeRAD, check out its github repo.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/helpbutton-component/","summary":"\u003cp\u003eThis is the second is a series of blog posts hightlighting some of the components available in the CodeRAD cn1lib. The \u003ca href=\"/blog/rad-chatroom-part-1/\"\u003efirst post (or series of posts) introduced the RAD Chatroom component\u003c/a\u003e, a rich 2nd order UI component that encapsulates the user interface for a fully functional chat room.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eA second-order UI component is a complex UI component, usually composed of multiple basic components, which is designed for a specific type of application. Some examples of second-order UI components are login forms, contacts lists, chat room components, news lists, etc..\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eIn this post I share a much simpler, first-order component: The \u003ca href=\"https://shannah.github.io/CodeRAD/javadoc/ca/weblite/shared/components/HelpButton.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHelpButton\u003c/a\u003e. The HelpButton is just a button that displays a \u0026ldquo;Help\u0026rdquo; or \u0026ldquo;Error\u0026rdquo; icon. When the user clicks on this button, it pops up with some \u0026ldquo;help\u0026rdquo; text.\u003c/p\u003e","title":"HELPBUTTON COMPONENT"},{"content":"A while back we added a new TestRunnerComponent that provides a visual UI for running unit tests inside an app. Sometimes, while I’m developing unit tests, I find it easier to write them inside a regular app project instead of in the \u0026ldquo;tests\u0026rdquo; directory. This allows me to debug the unit tests in the IDE more easily, just like I debug regular apps. The TestRunner component makes it simple to do this.\nAll you need to do is create some unit tests in your app (i.e. a class that extends AbstractTest. E.g.\npublic class MyTest extends AbstractTest { /** * Overridden to return true so test runs on EDT @Override public boolean shouldExecuteOnEDT() { return true; } /** * Actual body of the test. @Override public boolean runTest() throws Exception { // run tests here. return true; } /** * Override toString() so that the test shows up nicely in the testrunner. @Override public String toString() { return \u0026quot;MyTest\u0026quot;; } } You can then just add an instance of each Test class to your TestRunnerComponent. E.g. in your app’s start method you might have something like:\npublic void start() { if(current != null){ current.show(); return; } TestRunnerComponent runner = new TestRunnerComponent(); runner.add(new MyTest()); // add other tests here.. runner.showForm(); } When you run the app, it will display a form with single button \u0026ldquo;Run Tests\u0026rdquo;.\nWhen you press this button, it will run the tests and show the results on the screen.\nThe above screenshot is taken from the CodeRADTests project which contains unit tests for the CodeRAD cn1lib.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-testrunner-component/","summary":"\u003cp\u003eA while back we added a new \u003ca href=\"/javadoc/com/codename1/testing/TestRunnerComponent/\"\u003eTestRunnerComponent\u003c/a\u003e that provides a visual UI for running unit tests inside an app. Sometimes, while I’m developing unit tests, I find it easier to write them inside a regular app project instead of in the \u0026ldquo;tests\u0026rdquo; directory. This allows me to debug the unit tests in the IDE more easily, just like I debug regular apps. The TestRunner component makes it simple to do this.\u003c/p\u003e","title":"NEW TESTRUNNER COMPONENT"},{"content":" Home Inquiry Form Inquiry about Codename One Corporate Account ","permalink":"https://www.codenameone.com/inquiry-form/","summary":"\u003cul\u003e\n\u003cli\u003eHome\u003c/li\u003e\n\u003cli\u003eInquiry Form\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"inquiry-about-codename-one-corporate-account\"\u003eInquiry about Codename One Corporate Account\u003c/h2\u003e","title":"Inquiry Form"},{"content":"We’ve recently added some new display settings, and a new method, revalidateLater(), which can significantly increase your app’s rendering throughput in some cases. Before I get to the specifics of these changes, let’s review how UI rendering works in Codename One.\nThe Codename One UI rendering can be broken down into two phases:\nLayout – Calculating the bounds for each component on the screen, and \u0026ldquo;laying\u0026rdquo; them out. Painting – Actually drawing each component. Generally you only want to run the \u0026ldquo;layout\u0026rdquo; step when the layout has changed. This would include when components are added or removed from a Container, or when a component’s bounds or position has changed.\nWhen you make changes to a component and you want these changes to be updated on the screen, generally you would call repaint() or revalidate(), depending on whether your changes require a \u0026ldquo;layout\u0026rdquo; phase. repaint() will only trigger a \u0026ldquo;paint\u0026rdquo; without updating the layout. revalidate() will first layout the container, and then it will paint it.\n__ revalidate() isn’t the only method that can be used to trigger \u0026ldquo;layout\u0026rdquo;. If you want the UI component changes to be animated, you can use animateLayout(), animateHierarchy(), or several other animateXXX() methods of the Container class. Unintended Revalidation Triggers One cause of rendering performance issues is unintended revalidations.\nAs I mentioned above, revalidation is expensive, so you should strive to revalidate only when necessary, and only revalidate the portions of the UI that require revalidation. It gets tricky, however, because you may not always be aware of revalidations that are triggered by other actions. For example, if you make a change to a style in a Component, it will trigger a revalidation of the component’s parent container. E.g.\nmyLabel.getStyle().setBgColor(0xff0000); // This will trigger a revalidate() call in the parent container!!! One accidental revalidate() call is not a big deal, but suppose you are setting a whole bunch of styles in sequence:\nmyLabel.getStyle().setBgColor(0xff0000); myLabel.getStyle().setFont(...); myLabel.getStyle().setBgTransparency(0xff); myLabel.getStyle().setPadding(0,0,0,0); myLabel.getStyle().setMargin(0,0,0,0); myLabel.getStyle().setTextDecoration(...); myLabel.getStyle().setUnderline(...); myLabel.getStyle().setStrikeThru(...); myLabel.getStyle().setFgColor(0x0); myLabel.getStyle().setBorder(...); // The above calls will trigger 10 revalidations()!!! The above example shows some code that sets 10 style properties on a label. This code will trigger 10 calls to revalidate() in \u0026ldquo;myLabel\u0026rdquo;‘s parent container.\nHow do we avoid these redundant revalidations?\nOne simple way to avoid the redundant revalidations in the example above is to set all of the style properties before adding myLabel to a container. Then no revalidations would occur.\nHowever, we have just recently added a display property that will prevent style changes from triggering revalidations at all. Add the following into the init() method of your app’s main class:\nCN.setProperty(\u0026quot;Component.revalidateOnStyleChange\u0026quot;, \u0026quot;false\u0026quot;); Currently I recommend setting this property to \u0026ldquo;false\u0026rdquo; in all apps. Future versions of Codename One may change the default behaviour to \u0026ldquo;false\u0026rdquo;, but for now, the default is \u0026ldquo;true\u0026rdquo; because it is possible that some existing apps depend on the current behaviour.\nUnintended Revalidation Scope Another performance trap that you may accidentally step into is a revalidation scope that is greater than you intend. If you call myContainer.revalidate(), the current Codename One default behaviour is to trigger a revalidation on the entire form – not just \u0026ldquo;myContainer\u0026rdquo;. This behaviour was likely implemented to cover some edge, but it is a major performance killer. To fix this issue, we have added another display property \u0026ldquo;Form.revalidateFromRoot\u0026rdquo;, which can be set to \u0026ldquo;false\u0026rdquo; to prevent this behaviour. E.g. Add the following to your init() method:\nCN.setProperty(\u0026quot;Form.revalidateFromRoot\u0026quot;, \u0026quot;false\u0026quot;); This way, when you call myContainer.revalidate() it will relayout \u0026ldquo;myContainer\u0026rdquo; and only \u0026ldquo;myContainer\u0026rdquo;.\nRedundant Revalidations It is also possible to initiate a number of redundant calls to revalidate() if you’re not careful. E.g. If your UI is build with views that are bound to one or more model objects, and the views are directed to \u0026ldquo;revalidate\u0026rdquo; whenever a property of the model is changed, it is possible, and even likely, that your model may generate 10 or 20 property change events in one batch, which will propagate into 10 or 20 revalidation calls on the same container.\nFor example, consider the following excerpt from a \u0026ldquo;View\u0026rdquo; class:\n/** * A UI view for a Person */ public class PersonView extends Container { private Label name, description, ...; private Person model; public PersonView(Person model) { this.model = model; this.model.addPropertyChangeListener(evt -\u0026gt; update()); ... } /** * This method is triggered whenever a property is changed in the model. */ public void update() { boolean changed = false; if (!Objects.equals(name.getText(), model.getName())) { name.setText(model.getName()); changed = true; } if (!Objects.equals(description.getText(), model.getDescription()) { description.setText(model.getDescription()); changed = true } // ... etc... check all the properties to see if they have changed // and update the corresponding UI component accordingly if (changed) { // If a change has occurred, then revalidate() revalidate(); } } } In the constructor of this view, we register a PropertyChangeListener on the model so that the update() method will be called whenever a property is changed on the model. Inside the update() method, we trigger a revalidate() if any changes were made in the model that required an update in the view. Now consider a fairly typical snippet of code where we load data into the model. E.g.:\nperson.setName(\u0026quot;...\u0026quot;); person.setDescription(\u0026quot;...\u0026quot;); person.setAge(21); person.setOnline(true); person.setHeight(121); // ... etc... set all the other properties Given the way that our model is bound to the view, this code will generate a property change event for each property. If we set 30 property values, then we trigger 30 property change events. And each property change event results in the update() method being called, and revalidate() being triggered. Therefore, this code could result in 30 revalidations of the view (and, if we aren’t using CN.setProperty(\u0026quot;Form.revalidateFromRoot\u0026quot;, \u0026quot;false\u0026quot;), this also results in 30 revalidations of the full form). It is easy to see that this is a waste. You might not notice the performance degradation in simple interfaces, but it will become more evident as the UI grows more complex.\nHow to fix this\nTo combat the problem of redundant revalidations, we have introduced a new method, revalidateLater() which will defer the revalidation until just before the next paint cycle. This method will automatically eliminate duplicate revalidations, which will result in a significant performance increase in situations like the one depicted here. In our particular example, if we changed our view code from:\nif (changed) { revalidate(); } to\nif (changed) { revalidateLater(); } Then changing 30 properties on the model would trigger only a single revalidation instead of 30.\nSummary So summarize the new features discussed in this post:\nRevalidation should be done as little as possible for best performance. Style changes on components trigger revalidations by default. You can set the \u0026ldquo;Component.revalidateOnStyleChange\u0026rdquo; display property to \u0026ldquo;false\u0026rdquo; to prevent style changes from triggering revalidations. E.g. In your app’s init() method do:CN.setDisplayProperty(\u0026quot;Component.revalidateOnStyleChange\u0026quot;, \u0026quot;false\u0026quot;); Calling revalidate() on a container, will trigger revalidation of the entire form by default. You can set the \u0026ldquo;Form.revalidateFromRoot\u0026rdquo; display property to \u0026ldquo;false\u0026rdquo; to prevent revalidate() from triggering revalidation of the entire form. E.g. In your app’s init() method, do:CN.setDisplayProperty(\u0026quot;Form.revalidateFromRoot\u0026quot;, \u0026quot;false\u0026quot;); You can use revalidateLater() instead of revalidate() to defer revalidation until the next paint cycle, and avoid redundant revalidations. You should prefer revalidateLater() in most cases. The only time when revalidate() might be required is if you need to perform calculations on measurements after revalidation occurs. Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/smarter-faster-rendering/","summary":"\u003cp\u003eWe’ve recently added some new display settings, and a new method, \u003ccode\u003erevalidateLater()\u003c/code\u003e, which can significantly increase your app’s rendering throughput in some cases. Before I get to the specifics of these changes, let’s review how UI rendering works in Codename One.\u003c/p\u003e\n\u003cp\u003eThe Codename One UI rendering can be broken down into two phases:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003eLayout\u003c/strong\u003e – Calculating the bounds for each component on the screen, and \u0026ldquo;laying\u0026rdquo; them out.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ePainting\u003c/strong\u003e – Actually drawing each component.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eGenerally you only want to run the \u0026ldquo;layout\u0026rdquo; step when the layout has changed. This would include when components are added or removed from a Container, or when a component’s bounds or position has changed.\u003c/p\u003e","title":"SMARTER, FASTER RENDERING"},{"content":" Home Videos HOW DO I? Getting Started Instructional Videos[how_slides][show_shortcode_how_cat]\n","permalink":"https://www.codenameone.com/how-main/","summary":"\u003cul\u003e\n\u003cli\u003eHome\u003c/li\u003e\n\u003cli\u003eVideos\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"how-do-i\"\u003eHOW DO I?\u003c/h2\u003e\n\u003cp\u003eGetting Started Instructional Videos[how_slides][show_shortcode_how_cat]\u003c/p\u003e","title":"how-main"},{"content":"[woocommerce_cart]\n","permalink":"https://www.codenameone.com/cart/","summary":"\u003cp\u003e[woocommerce_cart]\u003c/p\u003e","title":"Cart"},{"content":"[woocommerce_checkout]\n","permalink":"https://www.codenameone.com/checkout/","summary":"\u003cp\u003e[woocommerce_checkout]\u003c/p\u003e","title":"Checkout"},{"content":"Codename One can be extended with native or Java code using the cn1lib format.\nThis page is generated from the official CN1Libs XML index and refreshed by the website build script.\nYou can install these extensions from Codename One Settings using the Extensions section:\nTo submit your own library, open a pull request in the source repository: github.com/codenameone/CodenameOneLibs\nFor format details, see the developer guide section on libraries: Developer Guide: Libraries (cn1lib)\n","permalink":"https://www.codenameone.com/cn1libs/","summary":"\u003cp\u003eCodename One can be extended with native or Java code using the \u003ccode\u003ecn1lib\u003c/code\u003e format.\u003c/p\u003e\n\u003cp\u003eThis page is generated from the official CN1Libs XML index and refreshed by the website build script.\u003c/p\u003e\n\u003cp\u003eYou can install these extensions from Codename One Settings using the Extensions section:\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Extensions section\" loading=\"lazy\" src=\"/uploads/extensions-section.png\"\u003e\u003c/p\u003e\n\u003cp\u003eTo submit your own library, open a pull request in the source repository:\n\u003ca href=\"https://github.com/codenameone/CodenameOneLibs\" target=\"_blank\" rel=\"noopener noreferrer\"\u003egithub.com/codenameone/CodenameOneLibs\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eFor format details, see the developer guide section on libraries:\n\u003ca href=\"/manual/advanced-topics.html#_libraries_cn1lib\"\u003eDeveloper Guide: Libraries (cn1lib)\u003c/a\u003e\u003c/p\u003e","title":"Extend Codename One with Native \u0026 Generic Libraries/Plugins"},{"content":"[woocommerce_my_account]\n","permalink":"https://www.codenameone.com/my-account/","summary":"\u003cp\u003e[woocommerce_my_account]\u003c/p\u003e","title":"My account"},{"content":"","permalink":"https://www.codenameone.com/shop/","summary":"","title":"Shop"},{"content":"\nComing Soon\u0026hellip; Go Back to Home page\n","permalink":"https://www.codenameone.com/coming-soon/","summary":"\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/uploads/footer-logo-1.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"coming-soon\"\u003eComing Soon\u0026hellip;\u003c/h2\u003e\n\u003cp\u003eGo Back to Home page\u003c/p\u003e","title":"Coming soon"},{"content":"\nImportant update below. After a very long journey we will launch the new Codename One website on October 2nd. Since this will only deal with the website itself most things should still work as they did before. Thanks to the cloud dashboard the migration shouldn’t disrupt any users and should be 99% superficial.\n__ The launch will be delayed tentatively to October 9th but possibly even later One thing that might be impacted are website comments which we will need to migrate to a new system. Initially the new website will launch without comments which we will need to re-integrate.\nThere might also be some disruption to discussion forum posts as we plan to migrate the discussion forum to a new medium.\nNotice that we will try to keep links as close as possible to the previous links but that might be challenging so some links (specifically to the developer guide) will redirect to a new location. There might be a period of DNS reshuffling as the new website will occupy a different server.\n__ That’s one of the motivations for conducting this migration on a Friday As part of this migration login on the website will no longer be available/required. Since the dashboard is no longer in this site this shouldn’t be an issue. Some pages will still be unavailable and will be added as we move forward. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — September 27, 2020 at 7:28 am (permalink) Francesco Galgani says:\nThe javadocs are essential, I consult them continuously: will they remain in the same position?\nIf the new site will continue to have the blogging section (which I’ve grown fond of…), you could add an article indicating which are the new links. Thank you.\nShai Almog — September 27, 2020 at 7:41 am (permalink) Shai Almog says:\nYes. The comments won’t be present on launch but we’ll add them later.\nMost links (including blogs) should remain the same.\nFrancesco Galgani — October 5, 2020 at 8:36 am (permalink) Francesco Galgani says:\nI guess something didn’t work: I keep seeing the site as before…\nShai Almog — October 5, 2020 at 8:39 am (permalink) Shai Almog says:\nNotice the update I posted last week to the article at the top… I doubt we’ll make it by this weekend either. This is proving much harder in the least expected quadrants.\nFrancesco Galgani — October 5, 2020 at 8:42 am (permalink) Francesco Galgani says:\nOh, I’m sorry: I didn’t notice that update.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-website-launch/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-website-launch/generic-java-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eImportant update below\u003c/strong\u003e. After a very long journey we will launch the new Codename One website on October 2nd. Since this will only deal with the website itself most things should still work as they did before. Thanks to the \u003ca href=\"https://cloud.codenameone.com/buildapp/index.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ecloud dashboard\u003c/a\u003e the migration shouldn’t disrupt any users and should be 99% superficial.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eThe launch will be delayed tentatively to October 9th but possibly even later\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eOne thing that might be impacted are website comments which we will need to migrate to a new system. Initially the new website will launch without comments which we will need to re-integrate.\u003c/p\u003e","title":"New Website Launch"},{"content":"coming Soon\u0026hellip; App Gallery Lorem ipsum dolor sit amet, consectetur adipiscing elit.\nUt elit tellus, luctus nec ullamcorper mattis,\npulvinar dapibus leo.\nGo Back to Home page ","permalink":"https://www.codenameone.com/app-gallery/","summary":"\u003ch2 id=\"coming-soon\"\u003ecoming Soon\u0026hellip;\u003c/h2\u003e\n\u003ch2 id=\"app-gallery\"\u003eApp Gallery\u003c/h2\u003e\n\u003cp\u003eLorem ipsum dolor sit amet, consectetur adipiscing elit.\u003cbr\u003e\nUt elit tellus, luctus nec ullamcorper mattis,\u003cbr\u003e\npulvinar dapibus leo.\u003c/p\u003e\n\u003cp\u003eGo Back to Home page \u003cimg loading=\"lazy\" src=\"/uploads/footer-logo.png\"\u003e\u003c/p\u003e","title":"App Gallery"},{"content":"[custom_breadcrumb]\nHOW DO I? Getting Started Instructional Videos[show_scripe_how][show_shortcode_how]\n","permalink":"https://www.codenameone.com/how-do-i/","summary":"\u003cp\u003e[custom_breadcrumb]\u003c/p\u003e\n\u003ch2 id=\"how-do-i\"\u003eHOW DO I?\u003c/h2\u003e\n\u003cp\u003eGetting Started Instructional Videos[show_scripe_how][show_shortcode_how]\u003c/p\u003e","title":"How do i"},{"content":"DISCUSSION FORUM Codename One engineers make sure all questions/queries have a response within 24 hours on business days. Primary Community Support Use GitHub Discussions as the main place for community Q\u0026amp;A, troubleshooting, and feature discussions.\nCodename One GitHub Discussions\nAdditional Community Channels (Secondary) Stack Overflow and Reddit are still available, but GitHub Discussions is the primary channel we monitor and recommend.\nStack Overflow (tag: codenameone) Reddit (r/cn1) Legacy Forums Our old Google Group is deprecated and kept only for historical context.\nGoogle Group (deprecated)\nTWITTER Tweets Liked by @Codename_One Follow Us on Twitter\nOTHER RESOURCES GitHub Discussions\n","permalink":"https://www.codenameone.com/discussion-forum/","summary":"\u003ch2 id=\"discussion-forum\"\u003eDISCUSSION FORUM\u003c/h2\u003e\n\u003ch2 id=\"codename-one-engineers-make-sure-all-questionsqueries-have-a-response-within-24-hours-on-business-days\"\u003eCodename One engineers make sure all questions/queries have a response within 24 hours on business days.\u003c/h2\u003e\n\u003ch2 id=\"primary-community-support\"\u003ePrimary Community Support\u003c/h2\u003e\n\u003cp\u003eUse GitHub Discussions as the main place for community Q\u0026amp;A, troubleshooting, and feature discussions.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/codenameone/CodenameOne/discussions\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCodename One GitHub Discussions\u003c/a\u003e\u003c/p\u003e\n\u003ch2 id=\"additional-community-channels-secondary\"\u003eAdditional Community Channels (Secondary)\u003c/h2\u003e\n\u003cp\u003eStack Overflow and Reddit are still available, but GitHub Discussions is the primary channel we monitor and recommend.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://stackoverflow.com/questions/tagged/codenameone\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eStack Overflow (tag: codenameone)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.reddit.com/r/cn1/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eReddit (r/cn1)\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"legacy-forums\"\u003eLegacy Forums\u003c/h2\u003e\n\u003cp\u003eOur old Google Group is deprecated and kept only for historical context.\u003c/p\u003e","title":"Discussion Forum"},{"content":"Watch Codename One videos, webinars, and conference talks.\n","permalink":"https://www.codenameone.com/videos/","summary":"\u003cp\u003eWatch Codename One videos, webinars, and conference talks.\u003c/p\u003e","title":"Videos"},{"content":"Compare Codename One Cross-platform frameworks solve different problems, so comparisons can feel like apples-to-oranges.\nThis page focuses on practical decision criteria: portability, performance profile, tooling, native integration, and long-term maintainability.\nAt a Glance Capability Codename One Flutter React Native Hybrid-Web (Ionic/Cordova) Xamarin Core Language Java/Kotlin Dart JavaScript/TypeScript JavaScript/HTML/CSS C# Portability Model High WORA focus Cross-platform with custom runtime Cross-platform with platform-specific branches as complexity grows WebView-based hybrid Cross-platform with platform-specific layers Native Output Native target builds Native shell + Flutter runtime Native shell + bridge model Web app wrapped in native container Native target builds Desktop + Web Reuse Yes Partial (varies by app/tooling) Partial (ecosystem dependent) Web-first (mobile native UX tradeoffs) Limited web strategy Build Workflow Cloud build + standard Java tooling Flutter toolchain Node + native toolchains Web stack + native wrappers Visual Studio + native SDKs Native Integration Complexity Direct native interfaces Plugin/channel integration Bridge/plugin integration Plugin/web-to-native integration Platform bindings Why Teams Choose Codename One Area Codename One Advantage Developer Base Built on Java/Kotlin with mature, widely available talent pools Performance Native target builds and lightweight architecture avoid common bridge bottlenecks Tooling Works with IntelliJ IDEA, NetBeans, and Eclipse using familiar Java workflows Build Infrastructure Cloud builds reduce platform-specific machine dependency Portability High code reuse across mobile, desktop, and web targets Head-to-Head Notes Codename One vs Flutter Dimension Codename One Flutter Runtime Model Native target strategy with lightweight architecture Ships with its own rendering/runtime stack Language Ecosystem Java/Kotlin Dart Styling Workflow CSS subset with live editing workflow Flutter-specific widget/styling system Native Calls Direct native interface model Channel/plugin-based integration Tooling Standards Maven and mainstream Java IDEs Flutter-specific CLI/tooling stack Codename One vs React Native Dimension Codename One React Native Portability Strong WORA focus Often needs platform-specific handling at scale Performance Consistency Lightweight components and native outputs Bridge + native widget differences can vary behavior Toolchain Setup Cloud build helps reduce machine/toolchain friction Typically requires native platform environment setup Web/Desktop Reuse Unified strategy Depends on separate ecosystem choices Codename One vs Hybrid-Web Dimension Codename One Hybrid-Web Execution Native app model WebView container model Device Variance Stable runtime distribution with the app Browser/OS engine variation impacts behavior Native Capability Depth Strong native integration options Plugin-based access, often with UX/perf limits UI Fidelity Built for cross-device native app behavior Web-first model can require extra adaptation Codename One vs Xamarin Dimension Codename One Xamarin Build Strategy Cloud build model for cross-target output Native SDK dependencies still central Web Deployment Path Java-to-JavaScript compilation path available Less central to default model Portability Shape Single-project-first approach More platform-specific project structure Additional Comparisons J2ObjC J2ObjC is useful for Java business-logic translation to Objective-C, but it is not a full cross-platform application framework with a portable UI stack.\nJavaFX / Swing Codename One borrows proven UI ideas from Swing while targeting mobile-first constraints, native integration realities, and smaller deployment footprints.\nOracle MAF MAF historically combined enterprise complexity with hybrid-web tradeoffs and a licensing model that could become expensive for production distribution.\nBottom Line If you want a Java/Kotlin-based, high-portability cross-platform workflow with strong native output and reduced platform build friction, Codename One is built for exactly that.\n","permalink":"https://www.codenameone.com/compare/","summary":"\u003ch1 id=\"compare-codename-one\"\u003eCompare Codename One\u003c/h1\u003e\n\u003cp\u003eCross-platform frameworks solve different problems, so comparisons can feel like apples-to-oranges.\u003c/p\u003e\n\u003cp\u003eThis page focuses on practical decision criteria: portability, performance profile, tooling, native integration, and long-term maintainability.\u003c/p\u003e\n\u003ch2 id=\"at-a-glance\"\u003eAt a Glance\u003c/h2\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eCapability\u003c/th\u003e\n          \u003cth\u003eCodename One\u003c/th\u003e\n          \u003cth\u003eFlutter\u003c/th\u003e\n          \u003cth\u003eReact Native\u003c/th\u003e\n          \u003cth\u003eHybrid-Web (Ionic/Cordova)\u003c/th\u003e\n          \u003cth\u003eXamarin\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCore Language\u003c/td\u003e\n          \u003ctd\u003eJava/Kotlin\u003c/td\u003e\n          \u003ctd\u003eDart\u003c/td\u003e\n          \u003ctd\u003eJavaScript/TypeScript\u003c/td\u003e\n          \u003ctd\u003eJavaScript/HTML/CSS\u003c/td\u003e\n          \u003ctd\u003eC#\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ePortability Model\u003c/td\u003e\n          \u003ctd\u003eHigh WORA focus\u003c/td\u003e\n          \u003ctd\u003eCross-platform with custom runtime\u003c/td\u003e\n          \u003ctd\u003eCross-platform with platform-specific branches as complexity grows\u003c/td\u003e\n          \u003ctd\u003eWebView-based hybrid\u003c/td\u003e\n          \u003ctd\u003eCross-platform with platform-specific layers\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eNative Output\u003c/td\u003e\n          \u003ctd\u003eNative target builds\u003c/td\u003e\n          \u003ctd\u003eNative shell + Flutter runtime\u003c/td\u003e\n          \u003ctd\u003eNative shell + bridge model\u003c/td\u003e\n          \u003ctd\u003eWeb app wrapped in native container\u003c/td\u003e\n          \u003ctd\u003eNative target builds\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eDesktop + Web Reuse\u003c/td\u003e\n          \u003ctd\u003eYes\u003c/td\u003e\n          \u003ctd\u003ePartial (varies by app/tooling)\u003c/td\u003e\n          \u003ctd\u003ePartial (ecosystem dependent)\u003c/td\u003e\n          \u003ctd\u003eWeb-first (mobile native UX tradeoffs)\u003c/td\u003e\n          \u003ctd\u003eLimited web strategy\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eBuild Workflow\u003c/td\u003e\n          \u003ctd\u003eCloud build + standard Java tooling\u003c/td\u003e\n          \u003ctd\u003eFlutter toolchain\u003c/td\u003e\n          \u003ctd\u003eNode + native toolchains\u003c/td\u003e\n          \u003ctd\u003eWeb stack + native wrappers\u003c/td\u003e\n          \u003ctd\u003eVisual Studio + native SDKs\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eNative Integration Complexity\u003c/td\u003e\n          \u003ctd\u003eDirect native interfaces\u003c/td\u003e\n          \u003ctd\u003ePlugin/channel integration\u003c/td\u003e\n          \u003ctd\u003eBridge/plugin integration\u003c/td\u003e\n          \u003ctd\u003ePlugin/web-to-native integration\u003c/td\u003e\n          \u003ctd\u003ePlatform bindings\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"why-teams-choose-codename-one\"\u003eWhy Teams Choose Codename One\u003c/h2\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eArea\u003c/th\u003e\n          \u003cth\u003eCodename One Advantage\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eDeveloper Base\u003c/td\u003e\n          \u003ctd\u003eBuilt on Java/Kotlin with mature, widely available talent pools\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ePerformance\u003c/td\u003e\n          \u003ctd\u003eNative target builds and lightweight architecture avoid common bridge bottlenecks\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eTooling\u003c/td\u003e\n          \u003ctd\u003eWorks with IntelliJ IDEA, NetBeans, and Eclipse using familiar Java workflows\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eBuild Infrastructure\u003c/td\u003e\n          \u003ctd\u003eCloud builds reduce platform-specific machine dependency\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ePortability\u003c/td\u003e\n          \u003ctd\u003eHigh code reuse across mobile, desktop, and web targets\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"head-to-head-notes\"\u003eHead-to-Head Notes\u003c/h2\u003e\n\u003ch3 id=\"codename-one-vs-flutter\"\u003eCodename One vs Flutter\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eDimension\u003c/th\u003e\n          \u003cth\u003eCodename One\u003c/th\u003e\n          \u003cth\u003eFlutter\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eRuntime Model\u003c/td\u003e\n          \u003ctd\u003eNative target strategy with lightweight architecture\u003c/td\u003e\n          \u003ctd\u003eShips with its own rendering/runtime stack\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eLanguage Ecosystem\u003c/td\u003e\n          \u003ctd\u003eJava/Kotlin\u003c/td\u003e\n          \u003ctd\u003eDart\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eStyling Workflow\u003c/td\u003e\n          \u003ctd\u003eCSS subset with live editing workflow\u003c/td\u003e\n          \u003ctd\u003eFlutter-specific widget/styling system\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eNative Calls\u003c/td\u003e\n          \u003ctd\u003eDirect native interface model\u003c/td\u003e\n          \u003ctd\u003eChannel/plugin-based integration\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eTooling Standards\u003c/td\u003e\n          \u003ctd\u003eMaven and mainstream Java IDEs\u003c/td\u003e\n          \u003ctd\u003eFlutter-specific CLI/tooling stack\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"codename-one-vs-react-native\"\u003eCodename One vs React Native\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eDimension\u003c/th\u003e\n          \u003cth\u003eCodename One\u003c/th\u003e\n          \u003cth\u003eReact Native\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ePortability\u003c/td\u003e\n          \u003ctd\u003eStrong WORA focus\u003c/td\u003e\n          \u003ctd\u003eOften needs platform-specific handling at scale\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ePerformance Consistency\u003c/td\u003e\n          \u003ctd\u003eLightweight components and native outputs\u003c/td\u003e\n          \u003ctd\u003eBridge + native widget differences can vary behavior\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eToolchain Setup\u003c/td\u003e\n          \u003ctd\u003eCloud build helps reduce machine/toolchain friction\u003c/td\u003e\n          \u003ctd\u003eTypically requires native platform environment setup\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eWeb/Desktop Reuse\u003c/td\u003e\n          \u003ctd\u003eUnified strategy\u003c/td\u003e\n          \u003ctd\u003eDepends on separate ecosystem choices\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"codename-one-vs-hybrid-web\"\u003eCodename One vs Hybrid-Web\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eDimension\u003c/th\u003e\n          \u003cth\u003eCodename One\u003c/th\u003e\n          \u003cth\u003eHybrid-Web\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eExecution\u003c/td\u003e\n          \u003ctd\u003eNative app model\u003c/td\u003e\n          \u003ctd\u003eWebView container model\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eDevice Variance\u003c/td\u003e\n          \u003ctd\u003eStable runtime distribution with the app\u003c/td\u003e\n          \u003ctd\u003eBrowser/OS engine variation impacts behavior\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eNative Capability Depth\u003c/td\u003e\n          \u003ctd\u003eStrong native integration options\u003c/td\u003e\n          \u003ctd\u003ePlugin-based access, often with UX/perf limits\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eUI Fidelity\u003c/td\u003e\n          \u003ctd\u003eBuilt for cross-device native app behavior\u003c/td\u003e\n          \u003ctd\u003eWeb-first model can require extra adaptation\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"codename-one-vs-xamarin\"\u003eCodename One vs Xamarin\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eDimension\u003c/th\u003e\n          \u003cth\u003eCodename One\u003c/th\u003e\n          \u003cth\u003eXamarin\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eBuild Strategy\u003c/td\u003e\n          \u003ctd\u003eCloud build model for cross-target output\u003c/td\u003e\n          \u003ctd\u003eNative SDK dependencies still central\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eWeb Deployment Path\u003c/td\u003e\n          \u003ctd\u003eJava-to-JavaScript compilation path available\u003c/td\u003e\n          \u003ctd\u003eLess central to default model\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ePortability Shape\u003c/td\u003e\n          \u003ctd\u003eSingle-project-first approach\u003c/td\u003e\n          \u003ctd\u003eMore platform-specific project structure\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"additional-comparisons\"\u003eAdditional Comparisons\u003c/h2\u003e\n\u003ch3 id=\"j2objc\"\u003eJ2ObjC\u003c/h3\u003e\n\u003cp\u003eJ2ObjC is useful for Java business-logic translation to Objective-C, but it is not a full cross-platform application framework with a portable UI stack.\u003c/p\u003e","title":"COMPARE"},{"content":"Start Here Codename One is a cross-platform framework for building native mobile and desktop apps with Java or Kotlin.\nLooking for a fast answer? Start with Pricing, Documentation, or Stack Overflow below.\nIf you need implementation-specific help, use:\nStack Overflow (codenameone tag) GitHub Issues Community Forum/Help Product \u0026amp; Platform What is Codename One and how does it work? Codename One lets Java/Kotlin developers build native apps from one codebase. You write app code once, and Codename One generates platform-specific binaries for iOS, Android, desktop, and web targets.\nLearn more in:\nIntroduction Developing in Codename One Do I need a Mac to build iOS apps? Not if you use the Codename One cloud build service. The cloud handles iOS compilation on Mac infrastructure.\nIf you build fully offline, Apple tooling still requires macOS for iOS builds and submission workflows.\nHow does performance compare to native or HTML-based solutions? Codename One compiles to native targets and is designed for production-level performance, including optimized rendering and modern VM/runtime improvements.\nFor a practical comparison, see Compare.\nCan I use third-party libraries? Yes, via Codename One libraries (cn1libs) and Maven dependencies that fit the Codename One toolchain.\nBrowse available libraries at Plugins/CN1Libs.\nLicensing \u0026amp; Pricing Is Codename One free and open source? Yes. Codename One is open source and can be used commercially. The optional cloud build/runtime services are available in free and paid tiers.\nWhat are the limits of the free plan? Free-plan limits apply mainly to cloud resources:\nBuild credits per month (iOS builds consume more credits than non-iOS targets due to Mac build costs) Cloud service quotas (e.g., push limits) Build artifact/JAR size limits for cloud builds Paid plans expand these limits and unlock additional production features.\nSee current details on Pricing.\nCan I cancel a paid plan and keep my app live? Yes. Built apps continue to work.\nCloud-backed runtime services (such as certain push/cloud features) require an active subscription.\nIs pricing per app or per developer? Pricing is per developer seat, not per app.\nCan teams mix different subscription tiers? No. For team accounts, developer seats are expected to be on the same subscription level.\nCloud Build, Source, and Security Is my source code sent to the cloud? No source code is sent for normal cloud builds. Codename One processes compiled bytecode.\nNative platform integrations may require native source segments to be uploaded for target-specific compilation.\nCan I build offline? Yes. You can build using local/offline workflows (including Maven-based workflows), subject to platform toolchain requirements.\nCan I download generated native sources? Paid tiers provide generated sources for supported targets.\nWhat still requires paid cloud services in production? Your installed app binaries continue to run after cancellation, but cloud-backed runtime features (such as certain push/cloud capabilities) require an active subscription.\nLegal What license is Codename One released under? Codename One source is licensed under GPL + Classpath Exception.\nThis allows commercial app distribution without requiring your app code to be open sourced solely because it links to Codename One.\nProduction Functionality \u0026amp; Limitations Is this a web wrapper approach? No. Codename One is not an HTML5 wrapper by default. It compiles to native targets with a cross-platform UI toolkit.\nWhat Java limitations should I expect? Codename One is Java/Kotlin-first, but not a full desktop-JVM mirror. Some APIs are mobile-adapted, and reflection isn\u0026rsquo;t supported for portability, size, performance and security.\nCan I still use native APIs when needed? Yes. Native interfaces and plugins let you access platform-specific APIs where required.\nCan I build and ship multiple production apps? Yes. There is no per-app licensing cap; plans are tied to developer seats and service usage tiers.\nSupport \u0026amp; Community Where should I ask questions? Stack Overflow (codenameone tag) GitHub Issues Community Forum/Help Can I contribute? Yes. Contributions are welcome via pull requests:\nCodename One on GitHub Do you offer training resources? Yes:\nAcademy / Training How Do I Tutorials Videos Quick Links Getting Started Documentation Pricing Compare ","permalink":"https://www.codenameone.com/faq/","summary":"\u003ch2 id=\"start-here\"\u003eStart Here\u003c/h2\u003e\n\u003cp\u003eCodename One is a cross-platform framework for building native mobile and desktop apps with Java or Kotlin.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eLooking for a fast answer? Start with \u003cstrong\u003ePricing\u003c/strong\u003e, \u003cstrong\u003eDocumentation\u003c/strong\u003e, or \u003cstrong\u003eStack Overflow\u003c/strong\u003e below.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eIf you need implementation-specific help, use:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://stackoverflow.com/questions/tagged/codenameone?sort=votes\u0026amp;pageSize=50\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eStack Overflow (\u003ccode\u003ecodenameone\u003c/code\u003e tag)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/codenameone/CodenameOne/issues\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGitHub Issues\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.reddit.com/r/cn1/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCommunity Forum/Help\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"product--platform\"\u003eProduct \u0026amp; Platform\u003c/h2\u003e\n\u003ch3 id=\"what-is-codename-one-and-how-does-it-work\"\u003eWhat is Codename One and how does it work?\u003c/h3\u003e\n\u003cp\u003eCodename One lets Java/Kotlin developers build native apps from one codebase. You write app code once, and Codename One generates platform-specific binaries for iOS, Android, desktop, and web targets.\u003c/p\u003e","title":"FAQ"},{"content":"Articles about \u0026amp; press releases from Codename One.\n","permalink":"https://www.codenameone.com/press/","summary":"\u003cp\u003eArticles about \u0026amp; press releases from Codename One.\u003c/p\u003e","title":"Press"},{"content":" Home Privacy Privacy Codename One doesn\u0026rsquo;t track users who aren\u0026rsquo;t logged in. However, we make use of 3rd party GDPR compliant services who do: Google Analytics \u0026amp; Crisp. In the past we used Intercom..\nWe maintain user data closely and make no commercial use of said data. User data is the property of the user and thus we don\u0026rsquo;t transfer it to 3rd parties in any way. We use the data strictly to provide our service and improve upon it.\nUse of Crisp Services: We use third-party analytics services to help understand your usage of our services. In particular, we provide a limited amount of your information (such as sign-up date and some personal information like your email address) to Crisp and utilize it to collect data for analytics purposes when you visit our website or use our product. As a data processor acting on our behalf, Crisp analyzes your use of our website and/or product and tracks our relationship by way of cookies and similar technologies so that we can improve our service to you. For more information on Crips use of cookies, please visit crisp.chat/en/privacy/. We may also use Crisp as a medium for communications, either through email, or through messages within our product(s). As part of our service agreements, Crisp collects publicly available contact and social information related to you, such as your email address, gender, company, job title, photos, website URLs, social network handles and physical addresses, to enhance your user experience. For more information on the privacy practices of Crisp. If you would like to opt out of having this information collected by or submitted to Crisp, please contact us. Notice that this will limit your ability to use some forms of support within the site.\nUse of Google Analytics: Google Analytics doesn\u0026rsquo;t collect any private information and doesn\u0026rsquo;t bind to user account data. No private data is tracked by analytics.\nApps built with Codename One include by default a small script that anonymously tracks device installs. This contains anonymized statistics and doesn\u0026rsquo;t track individual users or usage. This data is used purely for statistics. The following anonymous data is logged: OS, Version and Browser User Agent. This can be disabled entirely using the build hint block_server_registration. Note that this build hint requires a basic subscription or higher.\n","permalink":"https://www.codenameone.com/privacy/","summary":"\u003cul\u003e\n\u003cli\u003eHome\u003c/li\u003e\n\u003cli\u003ePrivacy\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"privacy\"\u003ePrivacy\u003c/h2\u003e\n\u003cp\u003eCodename One doesn\u0026rsquo;t track users who aren\u0026rsquo;t logged in. However, we make use of 3rd party GDPR compliant services who do: Google Analytics \u0026amp; Crisp. In the past we used Intercom..\u003c/p\u003e\n\u003cp\u003eWe maintain user data closely and make no commercial use of said data. User data is the property of the user and thus we don\u0026rsquo;t transfer it to 3rd parties in any way. We use the data strictly to provide our service and improve upon it.\u003c/p\u003e","title":"Privacy"},{"content":"Team The Codename One leadership team brings decades of experience building mobile developer tools and production software platforms.\nShai Almog — CEO A 30+ year software industry veteran with broad experience across platforms and technologies. In 1999, Shai founded vPrise LTD, where he and his team delivered solutions for global enterprises across banking, insurance, utilities, telecom, and manufacturing.\nLinkedIn X (Twitter) GitHub Chen Fishbein — CTO Chen is a veteran engineering leader who helped build widely used developer tooling, including the Sprint Toolkit. While working with device manufacturers and operators, he initiated the open-source LWUIT project, which later evolved into Codename One.\nLinkedIn X (Twitter) GitHub Steve Hannah — Lead Engineer Steve is an open-source-focused engineer with more than a decade of enterprise development experience at Simon Fraser University before joining Codename One. He has developed and maintained multiple open source projects used by developers worldwide.\nLinkedIn X (Twitter) GitHub ","permalink":"https://www.codenameone.com/team/","summary":"\u003ch2 id=\"team\"\u003eTeam\u003c/h2\u003e\n\u003cp\u003eThe Codename One leadership team brings decades of experience building mobile developer tools and production software platforms.\u003c/p\u003e\n\u003ch3 id=\"shai-almog--ceo\"\u003eShai Almog — CEO\u003c/h3\u003e\n\u003cp\u003e\u003cimg alt=\"Shai Almog\" loading=\"lazy\" src=\"/uploads/shai.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA 30+ year software industry veteran with broad experience across platforms and technologies. In 1999, Shai founded vPrise LTD, where he and his team delivered solutions for global enterprises across banking, insurance, utilities, telecom, and manufacturing.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.linkedin.com/in/shalmog/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eLinkedIn\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://twitter.com/debugagent\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eX (Twitter)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/shai-almog\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGitHub\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch3 id=\"chen-fishbein--cto\"\u003eChen Fishbein — CTO\u003c/h3\u003e\n\u003cp\u003e\u003cimg alt=\"Chen Fishbein\" loading=\"lazy\" src=\"/uploads/chen.jpg\"\u003e\u003c/p\u003e","title":"Team"},{"content":" Home Terms Terms 1. User\u0026rsquo;s Acknowledgment and Acceptance of Terms\nCodename One (\u0026ldquo;Us\u0026rdquo; or \u0026ldquo;We\u0026rdquo;) provides the Codename One site and various related services (collectively, the \u0026ldquo;site\u0026rdquo;) to you, the user, subject to your compliance with all the terms, conditions, and notices contained or referenced herein (the \u0026ldquo;Terms of Use\u0026rdquo;), as well as any other written agreement between us and you. In addition, when using particular services or materials on this site, users shall be subject to any posted rules applicable to such services or materials that may contain terms and conditions in addition to those in these Terms of Use. All such guidelines or rules are hereby incorporated by reference into these Terms of Use.\nBY USING THIS SITE, YOU AGREE TO BE BOUND BY THESE TERMS OF USE. IF YOU DO NOT WISH TO BE BOUND BY THE THESE TERMS OF USE, PLEASE EXIT THE SITE NOW. YOUR REMEDY FOR DISSATISFACTION WITH THIS SITE, OR ANY PRODUCTS, SERVICES, CONTENT, OR OTHER INFORMATION AVAILABLE ON OR THROUGH THIS SITE, IS TO STOP USING THE SITE AND/OR THOSE PARTICULAR PRODUCTS OR SERVICES. YOUR AGREEMENT WITH US REGARDING COMPLIANCE WITH THESE TERMS OF USE BECOMES EFFECTIVE IMMEDIATELY UPON COMMENCEMENT OF YOUR USE OF THIS SITE.\nThese Terms of Use are effective as of January 1st 2012. We expressly reserve the right to change these Terms of Use from time to time without notice to you. You acknowledge and agree that it is your responsibility to review this site and these Terms of Use from time to time and to familiarize yourself with any modifications. Your continued use of this site after such modifications will constitute acknowledgement of the modified Terms of Use and agreement to abide and be bound by the modified Terms of Use.\nAs used in these Terms of Use, references to our \u0026ldquo;Affiliates\u0026rdquo; include our owners, subsidiaries, affiliated companies, officers, directors, suppliers, partners, sponsors, and advertisers, and includes (without limitation) all parties involved in creating, producing, and/or delivering this site and/or its contents.\n2. Description of Services\nWe make various services available on this site including, but not limited to, Codename One cloud, Build server, Plugin, Designer \u0026amp; Simulator, and other like services. You are responsible for providing, at your own expense, all equipment necessary to use the services, including a computer, modem, and Internet access (including payment of all fees associated with such access).\nWe reserve the sole right to either modify or discontinue the site, including any of the site\u0026rsquo;s features, at any time with or without notice to you. We will not be liable to you or any third party should we exercise such right. Any new features that augment or enhance the then-current services on this site shall also be subject to these Terms of Use.\n3. Registration Data and Privacy\nIn order to access some of the services on this site, you will be required to use an account and password that can be obtained by completing our online registration form, which requests certain information and data (\u0026ldquo;Registration Data\u0026rdquo;), and maintaining and updating your Registration Data as required. By registering, you agree that all information provided in the Registration Data is true and accurate and that you will maintain and update this information as required in order to keep it current, complete, and accurate.\nYou also grant us the right to disclose to third parties certain Registration Data about you. The information we obtain through your use of this site, including your Registration Data, is subject to our Privacy Policy, which is specifically incorporated by reference into these Terms of Use.\n4. Conduct on Site\nYour use of the site is subject to all applicable laws and regulations, and you are solely responsible for the substance of your communications through the site. By posting information in or otherwise using any communications service, chat room, message board, newsgroup, software library, or other interactive service that may be available to you on or through this site, you agree that you will not upload, share, post, or otherwise distribute or facilitate distribution of any content \u0026ndash; including text, communications, software, images, sounds, data, or other information \u0026ndash; that:\na. is unlawful, threatening, abusive, harassing, defamatory, libelous, deceptive, fraudulent, invasive of another’s privacy, tortious, contains explicit or graphic descriptions or accounts of sexual acts (including but not limited to sexual language of a violent or threatening nature directed at another individual or group of individuals), or otherwise violates our rules or policies;\nb. victimizes, harasses, degrades, or intimidates an individual or group of individuals on the basis of religion, gender, sexual orientation, race, ethnicity, age, or disability;\nc. infringes on any patent, trademark, trade secret, copyright, right of publicity, or other proprietary right of any party;\nd. constitutes unauthorized or unsolicited advertising, junk or bulk email (also known as \u0026ldquo;spamming\u0026rdquo;), chain letters, any other form of unauthorized solicitation, or any form of lottery or gambling;\ne. contains software viruses or any other computer code, files, or programs that are designed or intended to disrupt, damage, or limit the functioning of any software, hardware, or telecommunications equipment or to damage or obtain unauthorized access to any data or other information of any third party; or\nf. impersonates any person or entity, including any of our employees or representatives.\nWe neither endorse nor assume any liability for the contents of any material uploaded or submitted by third party users of the site. We generally do not pre-screen, monitor, or edit the content posted by users of communications services, chat rooms, message boards, newsgroups, software libraries, or other interactive services that may be available on or through this site. However, we and our agents have the right at their sole discretion to remove any content that, in our judgment, does not comply with these Terms of Use and any other rules of user conduct for our site, or is otherwise harmful, objectionable, or inaccurate. We are not responsible for any failure or delay in removing such content. You hereby consent to such removal and waive any claim against us arising out of such removal of content. See \u0026ldquo;Use of Your Materials\u0026rdquo; below for a description of the procedures to be followed in the event that any party believes that content posted on this site infringes on any patent, trademark, trade secret, copyright, right of publicity, or other proprietary right of any party.\nIn addition, you may not use your account to breach security of another account or attempt to gain unauthorized access to another network or server. Not all areas of the site may be available to you or other authorized users of the site. You shall not interfere with anyone else\u0026rsquo;s use and enjoyment of the site or other similar services. Users who violate systems or network security may incur criminal or civil liability.\nYou agree that we may at any time, and at our sole discretion, terminate your membership, account, or other affiliation with our site without prior notice to you for violating any of the above provisions. In addition, you acknowledge that we will cooperate fully with investigations of violations of systems or network security at other sites, including cooperating with law enforcement authorities in investigating suspected criminal violations.\n5. Third Party Sites and Information\nThis site may link you to other sites on the Internet or otherwise include references to information, documents, software, materials and/or services provided by other parties. These sites may contain information or material that some people may find inappropriate or offensive. These other sites and parties are not under our control, and you acknowledge that we are not responsible for the accuracy, copyright compliance, legality, decency, or any other aspect of the content of such sites, nor are we responsible for errors or omissions in any references to other parties or their products and services. The inclusion of such a link or reference is provided merely as a convenience and does not imply endorsement of, or association with, the site or party by us, or any warranty of any kind, either express or implied.\n6. Intellectual Property Information\nCopyright (c) January 1st 2012 Codename One All Rights Reserved.\nFor purposes of these Terms of Use, \u0026ldquo;content\u0026rdquo; is defined as any information, data, communications, software, photos, video, graphics, music, sounds, and other material and services that can be viewed by users on our site. This includes message boards, chat, and other original content.\nBy accepting these Terms of Use, you acknowledge and agree that all content presented to you on this site is protected by copyrights, trademarks, service marks, patents or other proprietary rights and laws, and is the sole property of Codename One and/or its Affiliates. You are only permitted to use the content as expressly authorized by us or the specific content provider. Except for a single copy made for personal use only, you may not copy, reproduce, modify, republish, upload, post, transmit, or distribute any documents or information from this site in any form or by any means without prior written permission from us or the specific content provider, and you are solely responsible for obtaining permission before reusing any copyrighted material that is available on this site. Any unauthorized use of the materials appearing on this site may violate copyright, trademark and other applicable laws and could result in criminal or civil penalties.\nNeither we or our Affiliates warrant or represent that your use of materials displayed on, or obtained through, this site will not infringe the rights of third parties. See \u0026ldquo;User’s Materials\u0026rdquo; below for a description of the procedures to be followed in the event that any party believes that content posted on this site infringes on any patent, trademark, trade secret, copyright, right of publicity, or other proprietary right of any party.\nAll custom graphics, icons, logos and service names are registered trademarks, trademarks or service marks of Codename One or its Affiliates. All other trademarks or service marks are property of their respective owners. Nothing in these Terms of Use grants you any right to use any trademark, service mark, logo, and/or the name of Codename One or its Affiliates.\n7. Unauthorized Use of Materials\nSubject to our Privacy Policy.\nIn order to clarify: data sent in the Codename One build process whether in bytecode, source code or binary data and its resulting executable is the sole property of the developer. Codename One claims no ownership or any other rights in these products.\nPlease do not submit confidential or proprietary information to us unless we have mutually agreed in writing otherwise. We are also unable to accept your unsolicited ideas or proposals, do not submit them to us in any circumstance.\nWe respect the intellectual property of others, and we ask you to do the same. If you or any user of this site believes its copyright, trademark or other property rights have been infringed by a posting on this site, you or the user should send notification to our Designated Agent (as identified below) immediately. To be effective, the notification must include:\n1. Identify in sufficient detail the copyrighted work that you believe has been infringed upon or other information sufficient to specify the copyrighted work being infringed).\n2. Identify the material that you claim is infringing the copyrighted work listed in item #1 above.\n3. Provide information reasonably sufficient to permit us to contact you (email address is preferred).\n4. Provide information, if possible, sufficient to permit us to notify the owner/administrator of the allegedly infringing webpage or other content (email address is preferred).\n5. Include the following statement: \u0026ldquo;I have a good faith belief that use of the copyrighted materials described above as allegedly infringing is not authorized by the copyright owner, its agent, or the law.\u0026rdquo;\n6. Include the following statement: \u0026ldquo;I swear, under penalty of perjury, that the information in the notification is accurate and that I am the copyright owner or am authorized to act on behalf of the owner of an exclusive right that is allegedly infringed.\u0026rdquo;\n7. Sign the paper.\n8. Send the written communication to the following address:\nDesignated Agent for Claimed Infringement:\nContact: Shai Almog\nAddress: support@codenameone.com\nYou acknowledge and agree that upon receipt of a notice of a claim of copyright infringement, we may immediately remove the identified materials from our site without liability to you or any other party and that the claims of the complaining party and the party that originally posted the materials will be referred to the United States Copyright Office for adjudication as provided in the Digital Millennium Copyright Act.\n8. Disclaimer of Warranties\nALL MATERIALS AND SERVICES ON THIS SITE ARE PROVIDED ON AN \u0026ldquo;AS IS\u0026rdquo; AND \u0026ldquo;AS AVAILABLE\u0026rdquo; BASIS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR THE WARRANTY OF NON-INFRINGEMENT. WITHOUT LIMITING THE FOREGOING, WE MAKE NO WARRANTY THAT (A) THE SERVICES AND MATERIALS WILL MEET YOUR REQUIREMENTS, (B) THE SERVICES AND MATERIALS WILL BE UNINTERRUPTED, TIMELY, SECURE, OR ERROR-FREE, (C) THE RESULTS THAT MAY BE OBTAINED FROM THE USE OF THE SERVICES OR MATERIALS WILL BE EFFECTIVE, ACCURATE OR RELIABLE, OR (D) THE QUALITY OF ANY PRODUCTS, SERVICES, OR INFORMATION PURCHASED OR OBTAINED BY YOU FROM THE SITE FROM US OR OUR AFFILIATES WILL MEET YOUR EXPECTATIONS OR BE FREE FROM MISTAKES, ERRORS OR DEFECTS.\nTHIS SITE COULD INCLUDE TECHNICAL OR OTHER MISTAKES, INACCURACIES OR TYPOGRAPHICAL ERRORS. WE MAY MAKE CHANGES TO THE MATERIALS AND SERVICES AT THIS SITE, INCLUDING THE PRICES AND DESCRIPTIONS OF ANY PRODUCTS LISTED HEREIN, AT ANY TIME WITHOUT NOTICE. THE MATERIALS OR SERVICES AT THIS SITE MAY BE OUT OF DATE, AND WE MAKE NO COMMITMENT TO UPDATE SUCH MATERIALS OR SERVICES.\nTHE USE OF THE SERVICES OR THE DOWNLOADING OR OTHER ACQUISITION OF ANY MATERIALS THROUGH THIS SITE IS DONE AT YOUR OWN DISCRETION AND RISK AND WITH YOUR AGREEMENT THAT YOU WILL BE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR LOSS OF DATA THAT RESULTS FROM SUCH ACTIVITIES.\nThrough your use of the site, you may have the opportunities to engage in commercial transactions with other users and vendors. You acknowledge that all transactions relating to any merchandise or services offered by any party, including, but not limited to the purchase terms, payment terms, warranties, guarantees, maintenance and delivery terms relating to such transactions, are agreed to solely between the seller or purchaser of such merchandize and services and you. WE MAKE NO WARRANTY REGARDING ANY TRANSACTIONS EXECUTED THROUGH, OR IN CONNECTION WITH THIS SITE, AND YOU UNDERSTAND AND AGREE THAT SUCH TRANSACTIONS ARE CONDUCTED ENTIRELY AT YOUR OWN RISK. ANY WARRANTY THAT IS PROVIDED IN CONNECTION WITH ANY PRODUCTS, SERVICES, MATERIALS, OR INFORMATION AVAILABLE ON OR THROUGH THIS SITE FROM A THIRD PARTY IS PROVIDED SOLELY BY SUCH THIRD PARTY, AND NOT BY US OR ANY OTHER OF OUR AFFILIATES.\nContent available through this site often represents the opinions and judgments of an information provider, site user, or other person or entity not connected with us. We do not endorse, nor are we responsible for the accuracy or reliability of, any opinion, advice, or statement made by anyone other than an authorized Codename One spokesperson speaking in his/her official capacity. Please refer to the specific editorial policies posted on various sections of this site for further information, which policies are incorporated by reference into these Terms of Use.\nYou understand and agree that temporary interruptions of the services available through this site may occur as normal events. You further understand and agree that we have no control over third party networks you may access in the course of the use of this site, and therefore, delays and disruption of other network transmissions are completely beyond our control.\nYou understand and agree that the services available on this site are provided \u0026ldquo;AS IS\u0026rdquo; and that we assume no responsibility for the timeliness, deletion, mis-delivery or failure to store any user communications or personalization settings.\nSOME STATES OR JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF CERTAIN WARRANTIES, SO SOME OF THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU.\n9. Limitation of Liability\nIN NO EVENT SHALL WE OR OUR AFFILIATES BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY SPECIAL, PUNITIVE, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING, WITHOUT LIMITATION, THOSE RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT WE HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OF THIS SITE OR OF ANY WEB SITE REFERENCED OR LINKED TO FROM THIS SITE.\nFURTHER, WE SHALL NOT BE LIABLE IN ANY WAY FOR THIRD PARTY GOODS AND SERVICES OFFERED THROUGH THIS SITE OR FOR ASSISTANCE IN CONDUCTING COMMERCIAL TRANSACTIONS THROUGH THIS SITE, INCLUDING WITHOUT LIMITATION THE PROCESSING OF ORDERS.\nSOME JURISDICTIONS PROHIBIT THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, SO THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU.\n10. Indemnification\nUpon a request by us, you agree to defend, indemnify, and hold us and our Affiliates harmless from all liabilities, claims, and expenses, including attorney’s fees, that arise from your use or misuse of this site. We reserve the right, at our own expense, to assume the exclusive defense and control of any matter otherwise subject to indemnification by you, in which event you will cooperate with us in asserting any available defenses.\n11. Security and Password\nYou are solely responsible for maintaining the confidentiality of your password and account and for any and all statements made and acts or omissions that occur through the use of your password and account. Therefore, you must take steps to ensure that others do not gain access to your password and account. Our personnel will never ask you for your password. You may not transfer or share your account with anyone, and we reserve the right to immediately terminate your account if you do transfer or share your account.\n12. Participation in Promotions\nFrom time to time, this site may include advertisements offered by third parties. You may enter into correspondence with or participate in promotions of the advertisers showing their products on this site. Any such correspondence or promotions, including the delivery of and the payment for goods and services, and any other terms, conditions, warranties or representations associated with such correspondence or promotions, are solely between you and the advertiser. We assume no liability, obligation or responsibility for any part of any such correspondence or promotion.\n13. E-mail, Messaging, Blogging, and Chat Services\nWe may make email, messaging, blogging, or chat services (collectively, \u0026ldquo;Communications\u0026rdquo;) available to users of our site, either directly or through a third-party provider. We make available separate supplemental agreements characterizing the relationship between you and us that, except where expressly noted or contradictory, includes these Terms.\nWe will not inspect or disclose the contents of private Communications except with the consent of the sender or the recipient, or in the narrowly-defined situations provided under the Electronic Communications Privacy Act, GDPR, or as other required by law or by court or governmental order. Further information is available in our Privacy Policy.\nWe may employ automated monitoring devices or techniques to protect our users from mass unsolicited communications (also known as \u0026ldquo;spam\u0026rdquo;) and/or other types of electronic communications that we deem inconsistent with our business purposes. However, such devices or techniques are not perfect, and we will not be responsible for any legitimate communication that is blocked, or for any unsolicited communication that is not blocked.\nMailboxes may have a limited storage capacity. If you exceed the maximum permitted storage space, we may employ automated devices that delete or block email messages that exceed the limit. We will not be responsible for such deleted or blocked messages.\n14. International Use\nAlthough this site may be accessible worldwide, we make no representation that materials on this site are appropriate or available for use in locations outside Israel, and accessing them from territories where their contents are illegal is prohibited. Those who choose to access this site from other locations do so on their own initiative and are responsible for compliance with local laws. Any offer for any product, service, and/or information made in connection with this site is void where prohibited.\n15. Termination of Use\nYou agree that we may, in our sole discretion, terminate or suspend your access to all or part of the site with or without notice and for any reason, including, without limitation, breach of these Terms of Use. Any suspected fraudulent, abusive or illegal activity may be grounds for terminating your relationship and may be referred to appropriate law enforcement authorities.\nUpon termination or suspension, regardless of the reasons therefore, your right to use the services available on this site immediately ceases, and you acknowledge and agree that we may immediately deactivate or delete your account and all related information and files in your account and/or bar any further access to such files or this site. We shall not be liable to you or any third party for any claims or damages arising out of any termination or suspension or any other actions taken by us in connection with such termination or suspension.\n16. Governing Law\nThis site (excluding any linked sites) is controlled by us from our offices within the Tel Aviv, Israel. It can be accessed from countries around the world. As each of these places has laws that may differ from those of Tel Aviv, Israel, by accessing this site both of us agree that the statutes and laws of Israel, without regard to the conflicts of laws principles thereof and the United Nations Convention on the International Sales of Goods, will apply to all matters relating to the use of this site and the purchase of products and services available through this site. Each of us agrees and hereby submits to the exclusive personal jurisdiction and venue any court of competent jurisdiction within Israel with respect to such matters.\n17. Notices\nAll notices to a party shall be in writing and shall be made either via email or conventional mail. Notices to us must be sent to the attention of Customer Service at support@codenameone.com, if by email, or at Codename One Avraham Lev 1 Tel Aviv, Israel 64284 if by conventional mail. Notices to you may be sent to the address supplied by you as part of your Registration Data. In addition, we may broadcast notices or messages through the site to inform you of changes to the site or other matters of importance, and such broadcasts shall constitute notice to you at the time of sending.\n18. Entire Agreement\nThese terms and conditions constitute the entire agreement and understanding between us concerning the subject matter of this agreement and supersedes all prior agreements and understandings of the parties with respect to that subject matter. These Terms of Use may not be altered, supplemented, or amended by the use of any other document(s). Any attempt to alter, supplement or amend this document or to enter an order for products or services which are subject to additional or altered terms and conditions shall be null and void, unless otherwise agreed to in a written agreement signed by you and us. To the extent that anything in or associated with this site is in conflict or inconsistent with these Terms of Use, these Terms of Use shall take precedence.\n19. Miscellaneous\nIn any action to enforce these Terms of Use, the prevailing party will be entitled to costs and attorneys fees. Any cause of action brought by you against us or our Affiliates must be instituted with one year after the cause of action arises or be deemed forever waived and barred.\nYou may not assign your rights and obligations under these Terms of Use to any party, and any purported attempt to do so will be null and void. We may free assign our rights and obligations under these Terms of Use.\nYou agree not to sell, resell, reproduce, duplicate, copy or use for any commercial purposes any portion of this site, or use of or access to this site.\nIn addition to any excuse provided by applicable law, we shall be excused from liability for non-delivery or delay in delivery of products and services available through our site arising from any event beyond our reasonable control, whether or not foreseeable by either party, including but not limited to, labor disturbance, war, fire, accident, adverse weather, inability to secure transportation, governmental act or regulation, and other causes or events beyond our reasonable control, whether or not similar to those which are enumerated above.\nIf any part of these Terms of Use is held invalid or unenforceable, that portion shall be construed in a manner consistent with applicable law to reflect, as nearly as possible, the original intentions of the parties, and the remaining portions shall remain in full force and effect.\nAny failure by us to enforce or exercise any provision of these Terms of Use or related rights shall not constitute a waiver of that right or provision.\n20. Contact Information\nExcept as explicitly noted on this site, the services available through this site are offered by Codename One located at Avraham Lev 1 Tel Aviv. If you notice that any user is violating these Terms of Use, please contact us at\nsupport@codenameone.com.\n","permalink":"https://www.codenameone.com/terms/","summary":"\u003cul\u003e\n\u003cli\u003eHome\u003c/li\u003e\n\u003cli\u003eTerms\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"terms\"\u003eTerms\u003c/h2\u003e\n\u003cp\u003e1. User\u0026rsquo;s Acknowledgment and Acceptance of Terms\u003c/p\u003e\n\u003cp\u003eCodename One (\u0026ldquo;Us\u0026rdquo; or \u0026ldquo;We\u0026rdquo;) provides the Codename One site and various related services (collectively, the \u0026ldquo;site\u0026rdquo;) to you, the user, subject to your compliance with all the terms, conditions, and notices contained or referenced herein (the \u0026ldquo;Terms of Use\u0026rdquo;), as well as any other written agreement between us and you. In addition, when using particular services or materials on this site, users shall be subject to any posted rules applicable to such services or materials that may contain terms and conditions in addition to those in these Terms of Use. All such guidelines or rules are hereby incorporated by reference into these Terms of Use.\u003c/p\u003e","title":"Terms"},{"content":"Documentation \u0026amp; Demo Source Code JavaDocs of the API\u0026rsquo;s\nDevelopers Guide (HTML)\nThe Codename One Blog\nDevelopers Guide (PDF)\nHow Do I?\nThe Codename One Tutorials \u0026amp; Courses Hello World Tutorial\nShows off how to create a simple hello world application that works on all devices and looks native to all devices.\nHow Do I?\nShort video tutorials that walk you through common Codename One concepts and simple/basic ideas.\nCodename One Academy\nA complete set of free courses that cover everything from basics to full featured real world app development.\nTutorials \u0026amp; Documentation List\nAn exhaustive list of tutorials and references in both written and video form.\nTutorial Tag In the Blog\nThe Codename One blog publishes tutorials regularly and you can follow all of them in this tag.\n","permalink":"https://www.codenameone.com/developing-in-codename-one/","summary":"\u003ch2 id=\"documentation--demo-source-code\"\u003eDocumentation \u0026amp; Demo Source Code\u003c/h2\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/uploads/Group-2257.svg\"\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"/javadoc/\"\u003eJavaDocs of the API\u0026rsquo;s\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"/developer-guide\"\u003e Developers Guide (HTML)\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"/blog/\"\u003eThe Codename One Blog\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://www.codenameone.com/files/developer-guide.pdf\"\u003eDevelopers Guide (PDF)\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"/how-do-i/\"\u003eHow Do I?\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"the-codename-one-tutorials--courses\"\u003eThe Codename One Tutorials \u0026amp; Courses\u003c/h2\u003e\n\u003cp\u003e\u003ca href=\"https://youtu.be/rl6z7DD2-vg\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cimg loading=\"lazy\" src=\"/uploads/Group-2197.svg\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e\u003ca href=\"https://youtu.be/rl6z7DD2-vg\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHello World Tutorial\u003c/a\u003e\u003c/strong\u003e\u003cbr\u003e\nShows off how to create a simple hello world application that works on all devices and looks native to all devices.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e\u003ca href=\"/how-do-i/\"\u003eHow Do I?\u003c/a\u003e\u003c/strong\u003e\u003cbr\u003e\nShort video tutorials that walk you through common Codename One concepts and simple/basic ideas.\u003c/p\u003e","title":"Developing In Codename One"},{"content":"Introduction Part of what makes Codename One unique is its architecture. You write your app in Java or Kotlin, using the Codename One cross-platform, extensible class library, which includes a rich set of UI widgets and APIs for nearly everything a mobile app could need: location, contacts, maps, audio/video, and more.\nFull Access to Native Platform and Libraries Codename One allows full access to each platform\u0026rsquo;s native APIs via native interfaces. Native interfaces are easy to create in Codename One: create a Java interface that extends NativeInterface, then use the Codename One plugin to generate stubs for native implementations.\nYou can then fill in those stubs with native code. Using native interfaces, you can even integrate native UI widgets into your app seamlessly.\nLearn more about Native Interfaces\nCodename One Runtime The Codename One runtime consists of two layers:\nThe Java class library This includes a subset of JavaSE 8 classes (for example java.util, java.lang, and java.io), a set of UI widgets, and packages for accessing device functionality such as location, media, contacts, and maps.\nThe native layer This layer is written in each platform\u0026rsquo;s native language (Objective-C on iOS, Java on Android, C# for UWP, and so on). It is the glue that allows the Codename One class library to access native APIs.\n3rd-Party Libraries You can use third-party native libraries via native interfaces. You can embed native libraries directly in your project\u0026rsquo;s native directory, or use build hints to add dependencies in CocoaPods (iOS), Gradle (Android), and NuGet (UWP).\nThere is already a wide assortment of cn1libs developed by both Codename One and third-party developers. Notable cn1libs include Google Maps support, WebSocket support, and Parse support.\nLearn More about CN1libs\nPlatform Architecture (Accordion) iOS Architecture Android Architecture [ UWP Architecture Javascript Port Architecture Compiled to Native And the best part of Codename One apps is that they are compiled into 100% native code to be blazingly fast.\nGet Started\nLearn More\n","permalink":"https://www.codenameone.com/introduction/","summary":"\u003ch2 id=\"introduction\"\u003eIntroduction\u003c/h2\u003e\n\u003cp\u003ePart of what makes Codename One unique is its architecture. You write your app in Java or Kotlin, using the Codename One cross-platform, extensible class library, which includes a rich set of UI widgets and APIs for nearly everything a mobile app could need: location, contacts, maps, audio/video, and more.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Codename One Intro Illustration\" loading=\"lazy\" src=\"/uploads/Group-2326.svg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Codename One Architecture\" loading=\"lazy\" src=\"/uploads/Group-1851.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"full-access-to-native-platform-and-libraries\"\u003eFull Access to Native Platform and Libraries\u003c/h2\u003e\n\u003cp\u003eCodename One allows full access to each platform\u0026rsquo;s native APIs via native interfaces. Native interfaces are easy to create in Codename One: create a Java interface that extends \u003ccode\u003eNativeInterface\u003c/code\u003e, then use the Codename One plugin to generate stubs for native implementations.\u003c/p\u003e","title":"Introduction"},{"content":"FAQs What is Codename One? How does it work? Codename One is an open-source cross-platform WORA (Write Once Run Anywhere) mobile app development framework that lets Java and Kotlin developers build truly native multi-platform apps with high code reuse.\nApps are compiled down to native code for strong performance and smooth UX.\nIs Codename One free? Is it open source? Yes. Codename One is open source and can be used commercially and non-commercially with no royalties or restrictions.\nThe optional cloud build service includes a free quota and lets developers on Windows/Linux build native iOS apps.\nWhat are the limits of the free version? These limits apply to cloud builds only.\n100 build credits per month. 1 build credit per build (iOS uses 8 credits due to Mac build costs). 8.5 MB user JAR size limit. You can still use generated apps commercially. Paid plans mainly add higher quotas and advanced cloud features.\nCan I cancel or change plan anytime? Yes. Codename One includes a 30-day money back guarantee for paid purchases.\nWhat payment methods do you accept? Credit card and debit card through the Codename One secure signup flow.\nFor annual Pro/Enterprise subscriptions, SWIFT transfer and invoicing are available. Use the site chat to request a pro-forma invoice.\nAre there limits on number of apps? No. Pricing is per developer seat, not per app.\nWill my app still work if I cancel subscription? Yes. Built apps continue to work.\nCloud runtime services (e.g., push) require an active subscription.\nIs source code sent to the cloud? No source code is sent for normal builds. Cloud builds process compiled bytecode.\nNative platform sources may be uploaded when required for native compilation.\n","permalink":"https://www.codenameone.com/pricing/","summary":"\u003ch2 id=\"faqs\"\u003eFAQs\u003c/h2\u003e\n\u003ch3 id=\"what-is-codename-one-how-does-it-work\"\u003eWhat is Codename One? How does it work?\u003c/h3\u003e\n\u003cp\u003eCodename One is an open-source cross-platform WORA (Write Once Run Anywhere) mobile app development framework that lets Java and Kotlin developers build truly native multi-platform apps with high code reuse.\u003c/p\u003e\n\u003cp\u003eApps are compiled down to native code for strong performance and smooth UX.\u003c/p\u003e\n\u003ch3 id=\"is-codename-one-free-is-it-open-source\"\u003eIs Codename One free? Is it open source?\u003c/h3\u003e\n\u003cp\u003eYes. Codename One is open source and can be used commercially and non-commercially with no royalties or restrictions.\u003c/p\u003e","title":"Pricing"},{"content":" Home Codename One Simulator Codename One Simulator Test and Debug your app right inside your IDE\nDebug and test your app directly inside NetBeans with the integrated Codename One Simulator Just press \u0026ldquo;Run\u0026rdquo; on your project, and the simulator will open with your app running.\nSelect Your IDE: IntelliJ/IDEA Eclipse NetBeans Runs Instantly Unlike the emulators Xcode and Android Studio, the Codename One simulator launches instantly, and starts your app. This allows you to iterate more quickly and increase productivity.\nLarge Selection of \u0026ldquo;Skins\u0026rdquo; Choose from a large selection of device \u0026ldquo;skins\u0026rdquo; to see how your app will look on particular devices. The skin takes into account factors such as resolution and device density to provide a pixel-perfectre presentation of your app, as it would appear on the real device. Switching between device skins is nearly instant.\nInteractive Console Interact with your application’s APIs at runtime using the interactive Groovy Console. Inspect the application state or experiment with changes all while the app is running.\nLive Reload The Simulator let’s you take advantage of the \u0026ldquo;Apply Code Changes\u0026rdquo; feature in NetBeans so that changes you make in your Java source code will be applied immediately to your already-running app in the simulator.\nCSS Live Update When you make changes to your app’s CSS stylesheet, the changes are reflected instantly in the simulator.\nComponent Inspector Use the powerful component inspector to browse the UI component hierarchy in your app. This tool makes it easy to find out where that extra padding is coming from or why something just isn’t lining up the way you’d like.\nNetwork Monitor See all of the network connections that your app makes using the Network Monitor. This valuable tool comes in handy when you’re trying to figure out why an HTTP request isn’t working for you. Check the headers and bodies of both the request and the response. You can even throttle the network to simulate a slow network connection.\nRecord UI Unit Tests Use the Test Recorder tool to record unit tests for your app. Once you start recording, it will save your interactions into a unit test that can be played back later to verify that behaviour remains correct.\n","permalink":"https://www.codenameone.com/codename-one-simulator/","summary":"\u003cul\u003e\n\u003cli\u003eHome\u003c/li\u003e\n\u003cli\u003eCodename One Simulator\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"codename-one-simulator\"\u003eCodename One Simulator\u003c/h2\u003e\n\u003cp\u003eTest and Debug your app right inside your IDE\u003c/p\u003e\n\u003ch2 id=\"debug-and-test-your-app-directly-inside-netbeans-with-the-integrated-codename-one-simulator\"\u003eDebug and test your app directly inside NetBeans with the integrated Codename One Simulator\u003c/h2\u003e\n\u003cp\u003eJust press \u0026ldquo;Run\u0026rdquo; on your project, and the simulator will open with your app running.\u003c/p\u003e\n\u003ch2 id=\"select-your-ide\"\u003eSelect Your IDE:\u003c/h2\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/uploads/intellij-idea-1-logo-png-transparent.png\"\u003e\u003c/p\u003e\n\u003ch3 id=\"intellijidea\"\u003eIntelliJ/IDEA\u003c/h3\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/uploads/eclipse-11-logo-png-transparent-1.png\"\u003e\u003c/p\u003e\n\u003ch3 id=\"eclipse\"\u003eEclipse\u003c/h3\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/uploads/netbeans.png\"\u003e\u003c/p\u003e\n\u003ch3 id=\"netbeans\"\u003eNetBeans\u003c/h3\u003e\n\u003ch3 id=\"runs-instantly\"\u003eRuns Instantly\u003c/h3\u003e\n\u003cp\u003eUnlike the emulators Xcode and Android Studio, the Codename One simulator launches instantly, and starts your app. This allows you to iterate more quickly and increase productivity.\u003c/p\u003e","title":"Codename One Simulator"},{"content":"","permalink":"https://www.codenameone.com/getting-started/","summary":"","title":"Getting Started"},{"content":"Codename One’s Build Tools Codename One apps perform like native apps, because they are real native apps.\nThey are statically compiled into native binaries using the target platform’s official build tools.\nOn platforms that do not support Java natively, such as iOS, the app’s JVM bytecode is first transpiled into a form that the native build tools will accept. On iOS, the app’s JVM bytecode is transformed into C source code, in a real Xcode project.\nOn Android, since Java is supported natively, no such transformation is necessary. The app’s source code is bundled directly into an Android studio gradle project, which can be built directly using the Android SDK build tools.\nThe figure below shows the build process for each supported platform.\nAPP.JAR UWP/Windows 10 Windows Desktop Mac Desktop Javascript Android IOS\nTransplantation Step IKVM Translate JVM bytecode to .dll\na\nded ded TeaVM (Translate JVM bytecode to JavaScript source)\nded ParparVM (Translate JVM bytecode to C-Source)\na\nBuild Step Visual Studio Project a\nJava Packager a\nJava Packager a a\nAndroid Studio Gradle Project a\nXcode Project a\noutput UWP App (.appx)\nWindows App (.exe)\nMac app (.app)\nProgressive Web App (.war or .html)\nAndroid App (.apk)\niOS App (.ipa)\na a a a\ndistribution Windows App Store\nMac App Store\nGoogle Play Store\niOS App Store\n[build_tools_process_slider]\nSetting up the Build Tools You don’t need to set up any of these build tools. The Codename One Build cloud takes care of all that. If you have the IntelliJ/NetBeans/Eclipse plugin installed, you can build your Java or Kotlin project as a native mobile app with the press of a button. Get Started\n","permalink":"https://www.codenameone.com/build-tools/","summary":"\u003ch2 id=\"codename-ones-build-tools\"\u003eCodename One’s Build Tools\u003c/h2\u003e\n\u003cp\u003eCodename One apps perform like native apps, because they are real native apps.\u003c/p\u003e\n\u003cp\u003eThey are statically compiled into native binaries using the target platform’s official build tools.\u003c/p\u003e\n\u003cp\u003eOn platforms that do not support Java natively, such as iOS, the app’s JVM bytecode is first transpiled into a form that the native build tools will accept. On iOS, the app’s JVM bytecode is transformed into C source code, in a real Xcode project.\u003c/p\u003e","title":"Build Tools"},{"content":"Build Codename One apps in the IDE you already know. Keep a single workflow from first prototype to native app delivery.\nWhy this workflow works One Codebase Develop once in Java and deliver across mobile, desktop, and web targets.\nFast Iteration Use simulator, debugger, and live styling loops to shorten feedback time.\nNative Delivery Generate Android and iOS native apps from one project and one team flow.\nSupported IDEs IntelliJ IDEA VS Code Eclipse NetBeans From first project to native app Step 1 Create the project Scaffold a new project using the Codename One Initializr.\nStep 2 Run in simulator Test forms, flows, and behavior early so design and logic stay aligned throughout development.\nStep 3 Debug and refine Trace issues in your IDE and validate fixes quickly to keep development velocity high.\nStep 4 Build native apps Package and ship platform-native deliverables for Android and iOS from the same project.\nDesign and polish GUI Builder Compose screens visually where it accelerates delivery, then continue refining behavior in code.\nCSS Live Update Update styles and immediately validate visual changes in the simulator to speed up polish and theming work.\nContinue Exploring Getting Started Developing in Codename One Codename One Simulator Browse CN1libs Developer Guide ","permalink":"https://www.codenameone.com/development-environment/","summary":"\u003cp\u003eBuild Codename One apps in the IDE you already know. Keep a single workflow from first prototype to native app delivery.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Development Environment Overview\" loading=\"lazy\" src=\"/uploads/Group-2326.svg\"\u003e\u003c/p\u003e\n\u003ch2 id=\"why-this-workflow-works\"\u003eWhy this workflow works\u003c/h2\u003e\n\n\u003cdiv class=\"cn1-dev-value-grid\" aria-label=\"Development workflow benefits\"\u003e\n  \u003carticle class=\"cn1-dev-value-item\"\u003e\n    \u003csvg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\"\u003e\n      \u003crect x=\"4\" y=\"5\" width=\"16\" height=\"5\" rx=\"1.5\"\u003e\u003c/rect\u003e\n      \u003crect x=\"6\" y=\"11\" width=\"12\" height=\"4\" rx=\"1.2\"\u003e\u003c/rect\u003e\n      \u003crect x=\"8\" y=\"16\" width=\"8\" height=\"3\" rx=\"1\"\u003e\u003c/rect\u003e\n    \u003c/svg\u003e\n    \u003ch3\u003eOne Codebase\u003c/h3\u003e\n    \u003cp\u003eDevelop once in Java and deliver across mobile, desktop, and web targets.\u003c/p\u003e\n  \u003c/article\u003e\n  \u003carticle class=\"cn1-dev-value-item\"\u003e\n    \u003csvg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\"\u003e\n      \u003cpath d=\"M8 4h8\"\u003e\u003c/path\u003e\n      \u003cpath d=\"M10 4v6l-3.5 5.5A2 2 0 0 0 8.2 19h7.6a2 2 0 0 0 1.7-3.5L14 10V4\"\u003e\u003c/path\u003e\n      \u003cpath d=\"M9.2 14.5h5.6\"\u003e\u003c/path\u003e\n      \u003cpath d=\"M10.2 16.5h3.6\"\u003e\u003c/path\u003e\n    \u003c/svg\u003e\n    \u003ch3\u003eFast Iteration\u003c/h3\u003e\n    \u003cp\u003eUse simulator, debugger, and live styling loops to shorten feedback time.\u003c/p\u003e","title":"Development Environment"},{"content":"\nWe announced a while back that we’re working on a new website. This work was 90% complete but we decided to scrap it in favor of a complete rewrite of the site. That means some links might break and some functionality might be impacted but this is a crucial change for the continued growth of the company.\nOne thing that we plan to remove entirely is the old dashboard. It will be removed on September 18th in favor of the build cloud. Please let us know of any missing features or problems so we can address them in time for the migration.\nWe intend to provide support for:\nEmailing the build results\nQR code for OTA install\nThis is in addition to the UI overhaul which is worked on here. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDurank — September 11, 2020 at 1:19 pm (permalink) Durank says:\nbut this page it’ll continue working separately on the Dashboard or you will migrate all your web side?\nShai Almog — September 12, 2020 at 4:45 am (permalink) Shai Almog says:\nWe will migrate the entire site. To test this out we’ll remove this page earlier than the rest of the site but we will replace the entire thing. Since the new site will have a different architecture the current page just can’t physically work.\nCarlos Verdier — September 16, 2020 at 7:19 am (permalink) Carlos Verdier says:\nFor some reason, the \u0026ldquo;Install on device\u0026rdquo; and other links don’t work properly on my iPad (13.7). I need to repeatedly tap on the link and eventually it works.\nFrancesco Galgani — September 16, 2020 at 8:33 am (permalink) Francesco Galgani says:\nI have the same issue. I reported it here: https://github.com/codenameone/CodenameOne/issues/3264\nShai Almog — September 17, 2020 at 4:12 am (permalink) Shai Almog says:\nWe’re looking into this. It’s also possible this is related to limits in the HTML standard with opening links via code.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/removing-old-dashboard/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/removing-old-dashboard/generic-java-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe announced a while back that we’re working on a new website. This work was 90% complete but we decided to scrap it in favor of a complete rewrite of the site. That means some links might break and some functionality might be impacted but this is a crucial change for the continued growth of the company.\u003c/p\u003e\n\u003cp\u003eOne thing that we plan to remove entirely is the \u003ca href=\"/build-server.html\"\u003eold dashboard\u003c/a\u003e. It will be removed on September 18th in favor of \u003ca href=\"https://cloud.codenameone.com/buildapp/index.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ethe build cloud\u003c/a\u003e. Please let us know of any missing features or problems so we can address them in time for the migration.\u003c/p\u003e","title":"Removing Old Dashboard"},{"content":"\nA couple of weeks ago I answered a question on Quora about the security of cross platform tools. I try to rise about my confirmation bias when discussing these things. I won’t discuss Codename One in this context or any other specific tool. Only general ideas.\nSecurity depends a lot on the tools involved and their level of support for security features such as certificate pinning, storage/db encryption etc. Some tools also store the code of the app as plain text or obfuscated scripting code which is still fully readable, this can have a serious impact on security.\nIn fact this level of insecurity spawned a thriving cottage industry of repackaging. Where people unzip the application and repackage/sign it and upload it to the store under a different package name. Then use ads/payment to earn from the stolen app. This can be very profitable to them as the time gap until detection and takedown process can be pretty long.\nReverse Engineering Reverse engineering is possible no matter what tool you use. Cross platform tools can make this either easier or harder.\nThere are plenty of off the shelf tools to reverse engineer native apps. You can literally view the full UI design used by the developer and then search for the event handling code within the decompiled application. E.g. if you have a login form a hacker can find the login button, run the app and find out a lot about the process.\nHere the cross platform tools divide into three distinct categories:\nNative GUI tools — These are usually on par or worse than native apps when it comes to security. The native communication/layout is often visible via standard reverse engineering tools\nWeb tools — Cross platform tools that are based on web technologies are usually very easy to reverse engineer. To a level where a hacker can change JavaScript on the spot or even use web debugging tools to debug the app remotely\nLightweight Tools — Tools that render their own UI are usually more secure in that sense. Decompiler tools can’t always see some of these tools and find it really hard to deal with their UI. Such tools can be much harder to reverse engineer than native apps\nObfuscation Obfuscation is the first line of defense against reverse engineering. It’s an essential tool to make reverse engineering harder.\nSome tools and some common native 3rd party libraries, discourage obfuscation. A lot of tools limit the scope of obfuscation which is generally a bad thing to do.\nTips Things to ask your cross platform tool vendor:\nIs my code visible in the final binary?\nWhat level of obfuscation do I have here? Is there a separately obfuscated scripting language (e.g. javascript)?\nCan code be injected remotely? This is sometimes presented as a \u0026ldquo;feature\u0026rdquo; where you can circumvent the appstore submission process. Apple made that illegal and removed such tools in the past\nDo you support encrypted storage/DB?\nDo you support certificate pinning?\nDo you use custom socket communication and not the OS level connection (this is important as there might be a low level vulnerability in a custom implementation of SSL)?\nIt’s more secure to use the OS native APIs when doing networking operations\nI disable copy and paste?\nCan I disable the OS screenshot feature in the task manager (this isn’t possible on all OS’s)?\nCan I detect jailbroken devices?\nNotice that this isn’t always possible and is a bit flaky\nDo you support biometric authentication primitives\nWho do I contact when I find something and need help?\nArchived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — August 8, 2020 at 7:58 am (permalink) Francesco Galgani says:\nAlways remaining in a general discourse, my impression is that computer security is something non-existent, in the sense that no software or hardware can be said to be really secure. It’s usually a matter of compromises between being too paranoid or too relaxed.\nThe more complex a system made up of hardware and software (and many commonly used devices are terribly complex, from smartphones to the latest car models, from personal computers to the latest TV models), the more likely it is that something will get out of the control of both designers and users, sometimes because of real mistakes, sometimes because of unintended or unforeseen circumstances in which such devices operate, and sometimes for simply unknown reasons. Errors are an essential and inevitable part of any computer system, therefore, in an absolute sense, there is no security.\nOn a practical level, if while writing a software we think that our worst enemy can read its source code entirely and that, even in such a case, we do not put him in a position to do damage (or to do it easily), then the software is (maybe?) reasonably well designed in terms of security, but this does not exclude that there may be also important security problems. This applies to both open-source and cloused-source software.\nAnother consideration, always at the design stage, is that we should think about security on the assumption that all electronic communications are interceptable and, in the case of our apps, all outgoing and incoming traffic can be sniffed. In this regard, I like Shai’s advice not to use passwords in mobile apps: in fact they are not needed and the fact of not using them solves the security problems related to password management in the first place. Now I’m also doing password-free login systems with activation via email or sms link.\nAll this, however, is still not enough. As far as smartphones are concerned, it only takes five minutes, for someone with sufficient technical knowledge, to install invisible and pervasive spy programs that reveal every activity and movement of the victim, including the activities in the apps developed by us. So let’s be careful and don’t take anything for granted.\nBy the way, in the specific case of the mobile app world, a fundamental part of security is how server-side software is developed and how the server is configured and protected.\nOn the subject of computer security, I wrote a short section in my thesis \u0026ldquo;The Age of Technological Persuasion and Education in the Use of Technology\u0026rdquo;, I refer to paragraph 3.11.2, p. 56, 57 and 58. The text is in Italian: https://www.informatica-libera.net/content/era-della-persuasione-tecnologica\nJavier Anton — August 8, 2020 at 6:07 pm (permalink) Javier Anton says:\nThanks Shai and Francesco. I got a specific question, sorry for being so direct in such a general discussion.\nIf the source code is obfuscated, how can the NativeLogs reader tell me the specific file name and code lines in stack traces?\nShai Almog — August 9, 2020 at 1:36 am (permalink) Shai Almog says:\nThe default obfuscation settings from Google leave these things in place. So method names, variables etc. are all obfuscated and even the class names. But file names and line numbers are preserved so stack traces will make some sense. I think that’s a sensible default.\nYes it makes the code a bit less obfuscated but there’s always a trade-off. When we obfuscate completely stacks become ambiguous and really hard to follow even with the map file. BTW if you don’t know about the mapping file: \u0026lt;/blog/tip-obfuscation-mapping-file/\u0026gt;\nShai Almog — August 9, 2020 at 1:39 am (permalink) Shai Almog says:\nAgreed. I usually give the multi-layered security analogy as an \u0026ldquo;onion\u0026rdquo;. It’s hard to block a truly motivated hacker in some tiers but you can make him cry on every damn layer.\nFrancesco Galgani — August 9, 2020 at 10:38 am (permalink) Francesco Galgani says:\nI’ll try to add something about your question, compared to what Shai has already written. First, the source code of NativeLog Reader is really simple, it’s the first cn1lib I published, you can read the code here: https://github.com/jsfan3/CN1Libs-NativeLogsReader As you can see, in the case of Android it simply returns the output of \u0026ldquo;logcat\u0026rdquo; (on some phones it requires that the usb debug mode has been activated, even without usb connection), in the case of iOS it redirects the \u0026ldquo;standard output\u0026rdquo; (stdout) and the \u0026ldquo;standard error\u0026rdquo; (stderr) to a file. However, if you invoke Log.sendLogAsync() after a Log.e(ex), again you will see the file name and line number that launched the captured exception.\nAs for the obfuscation, here I published my own analysis of how easy or difficult it is to reverse engineer an app made with Codename One: https://www.informatica-libera.net/content/%C3%A8-possibile-il-reverse-engineering-di-unapp-fatta-con-codename-one-risalire-al-codice\nThe text is in Italian, however, if you search the page for the word \u0026ldquo;jadx\u0026rdquo;, you’ll see three snippets of code, one after the other: the first is the original source code written in Netbeans, the second is the result of the decompilation made when the apk is produced by Codename One in debug mode, the third is the result of the decompilation made when the apk is produced by Codename One in release mode (i.e. with ProGuard active): only in the latter case the code is almost unreadable. In both cases (debug mode and release mode), the comments, if present, are lost, while the text strings remain as they are (and therefore allow an attacker to look for something specific, unless the strings are obfuscated with Xor or other types of obfuscation). Note that the reverse engineering of Android applications made with Codename One is generally more difficult than \u0026ldquo;native\u0026rdquo; applications (those made with Android Studio, to understand) because Codename One does not use the XML format.\nThe article then continues by analyzing iOS: in this case I assert that decompiling is almost \u0026ldquo;mission impossible\u0026rdquo;.\nFinally, I examine the case of the web-apps made with Codename One, listing in detail the levels of obfuscation used, and then conclude that going back from the Javascript code produced by the Codename One build server to \u0026ldquo;usable\u0026rdquo; Java code is unrealistic (and I report an example to clarify any doubt).\nJavier Anton — August 10, 2020 at 7:05 pm (permalink) Javier Anton says:\nThank you both. My intuition told me that it must be something like what Shai said but it’s nice to have it confirmed. Really useful to see the resulting code in Francesco’s example\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/security-issues-cross-platform-tools/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/security-issues-cross-platform-tools/security.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA couple of weeks ago I \u003ca href=\"https://www.quora.com/Are-there-any-specific-security-issues-when-developing-cross-platform-banking-apps/answer/Shai-Almog?prompt_topic_bio=1\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eanswered a question on Quora\u003c/a\u003e about the security of cross platform tools. I try to rise about my confirmation bias when discussing these things. I won’t discuss Codename One in this context or any other specific tool. Only general ideas.\u003c/p\u003e\n\u003cp\u003eSecurity depends a lot on the tools involved and their level of support for security features such as certificate pinning, storage/db encryption etc. Some tools also store the code of the app as plain text or obfuscated scripting code which is still fully readable, this can have a serious impact on security.\u003c/p\u003e","title":"Security Issues of Cross Platform Tools"},{"content":"\nSteve just updated our CEF support which should now work on all platforms. We updated the original post with additional information. We’ve also updated the build servers to use API level 29 on Android.\nThe API level change should be seamless to most of you but might impact some edge case functionality and cause some native/cn1libs to fail in odd ways. So be sure to do extra checks on Android when building a new release.\nThis change is mandated by Google who require that you target the latest Android version within 6 months of its release.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/moving-api-level-29-cef/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/moving-api-level-29-cef/generic-java-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSteve just updated our CEF support which should now work on all platforms. We updated \u003ca href=\"/blog/big-changes-jcef.html\"\u003ethe original post\u003c/a\u003e with additional information. We’ve also updated the build servers to use API level 29 on Android.\u003c/p\u003e\n\u003cp\u003eThe API level change should be seamless to most of you but might impact some edge case functionality and cause some native/cn1libs to fail in odd ways. So be sure to do extra checks on Android when building a new release.\u003c/p\u003e","title":"Moving to API Level 29 and CEF Update"},{"content":"\nWith today’s update we’re releasing a design overhaul for the settings (preferences) application. This overhaul will improve the look and reliability/consistency of this app which is core to Codename One. During this transition period we also have the ability to go back to the legacy UI for 100% compatibility but it will be removed.\nCommon important features such as \u0026ldquo;Update Client Libs\u0026rdquo; are now available in the menu on the top right of the UI. The currently logged in user isn’t listed in the UI only in the about dialog. For most of the UI it doesn’t matter as much since we don’t change as much as we used to. E.g. we now let everyone create a push certificate. This is a pre-cursor to enabling push for everyone with a very low quota for free/basic users.\n__ This isn’t available yet in the servers and I’m not sure when we’ll have that out Figure 1. Light Mode\nFigure 2. Dark Mode\nFocus On Design This is one of the first signs of very big changes we have coming in the next few months. We intend to overhaul a lot of things in the UI, deep functionalities and even in the free/basic tier features.\nThe design was made by our new in-house designer Renzo whose work you’ve seen for a while now in our new orignal blog post images. He completely redesigned the website a while back but we’re still having issues in getting it all out there…​\nHe did a lot of great things and I’m confident he’ll help us improve the one part where we sorely lack: good looking by default.\nTo help him please check out the issues in the issue tracker assigned to him and feel free to provide feedback. Any feedback given during the UI design stage is far more valuable. Later on it’s much harder to revisit/adapt an implementation.\nTo get started check out and follow these two issues for GUI Builder Redesign and Codenme One Build Redesign. Once the tools incorporate this aesthetic, we’ll bring it to the themes we generate. We plan to overhaul project creation and make it easier to change the pre-existing templates in Codename One in an IDE agnostic way.\nI’m pretty excited about that…​ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — July 24, 2020 at 10:06 am (permalink) Now I notice the \u0026ldquo;File\u0026rdquo; menu from which you can change the size of the text, menu we talked about on Github.\nMy feedback is that the text is too little contrasted: it’s hard for me to read a light grey text on a white background, I would prefer a black text on a white background. I also find dark mode tiring for the eyes.\nI hope you can make the text black or at least add an option to it. Thank you\nShai Almog — July 26, 2020 at 2:09 am (permalink) We’ll try to increase contrast here to make it more readable.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-settings-ui/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-settings-ui/new-features-4.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWith today’s update we’re releasing a design overhaul for the settings (preferences) application. This overhaul will improve the look and reliability/consistency of this app which is core to Codename One. During this transition period we also have the ability to go back to the legacy UI for 100% compatibility but it will be removed.\u003c/p\u003e\n\u003cp\u003eCommon important features such as \u0026ldquo;Update Client Libs\u0026rdquo; are now available in the menu on the top right of the UI. The currently logged in user isn’t listed in the UI only in the about dialog. For most of the UI it doesn’t matter as much since we don’t change as much as we used to. E.g. we now let everyone create a push certificate. This is a pre-cursor to enabling push for everyone with a very low quota for free/basic users.\u003c/p\u003e","title":"New Settings UI"},{"content":"\nToday we released one of the biggest changes to Codename Ones simulator in ages. We added the ability to use CEF (Chrome Embedding Framework). This is currently off by default but even if you don’t use it you might feel the impact so it’s crucial that you read this post.\n__ Updated July 31st with additional platform instructions below __ Updated August 2nd with correction to the Linux install script __ Updated August 4th with another correction to the Linux install script The TL;DR The big change for those of you who don’t care about the details is this: FX will no longer install automatically if it’s missing. That might be a good thing for some applications. But if you rely on media/web things might break in the simulator/debugger.\nThe short term workaround is to install a JVM that supports JavaFX out of the box such as ZuluFX and make sure your IDE uses it. Make sure it’s first in your path and that JAVA_HOME points at it.\nAnother option is to migrate to CEF which might not be an option right now if your needs are mostly media related. Read on for the details.\nWhy? I wrote before about our desire to kick JavaFX and its problems to the curve. There’s no way around it. It’s outdated and buggy.\nCEF is literally Chrome. It’s modern and up to date, so newer browser features behave as expected. It’s also easy to debug and has a lot of other great features we can use. It would also free us from some of the JVM dependencies and let us build smaller desktop apps moving forward.\nThe reason we really need it at this moment is support for WebRTC which isn’t available in the JavaFX version of the browser but is available in Chromium.\n__ You can easily debug CEF BrowserComponent in Chrome by navigating to http://localhost:8088/ in Chrome How will this Impact Me? Hopefully you won’t run into any problem. If you’re using a JDK that doesn’t include JavaFX you might run into a problem in this transition period and things might fail. We recommend ZuluFX for now.\n__ Once this transition period is done this should work with any JVM By default CEF is off but you can turn it on explicitly instead of installing JavaFX.\nTurn on CEF This post was updated on July 31st with details on all platforms\nWhen complete we will automatically download and install CEF on the first activation effectively disabling the JavaFX mode.\nIf the ~/.codenameone/cef directory is present we assume CEF is installed and try to load it instead of JavaFX.\nMac Install To install manually download this file. Then perform the following command in the terminal:\nunzip ~/Downloads/cef-mac.zip -d ~/.codenameone To uninstall CEF in case of a problem do:\nrm -Rf ~/.codenameone/cef Windows Install If you’re using Win32 download this file.\nFor Win64 download this file.\nOpen your user directory and search for the .codenameone directory. In that directory unzip the downloaded zip file. It should include a cef directory. If not make sure to unzip the content into a directory named cef.\nYou can uninstall it by deleting the cef directory at any time.\nLinux Install __ We only support 64 bit Linux at this time. If there are developers using 32 bit Linux as their desktops please let us know Download the file this file.\nThen install using:\nmkdir ~/.codenameone/cef unzip cef-linux64.zip -d ~/.codenameone/cef chmod 755 ~/.codenameone/cef/lib/linux64/jcef_helper To uninstall CEF in case of a problem do:\nrm -Rf ~/.codenameone/cef What’s Missing? With the CEF pipeline media is implemented using the browser component. So videos literally play in the Chrome browser (seamlessly, you wouldn’t know). This removes the need for JavaFX completely and simplifies a lot of things.\nHowever, there’s one missing piece at the moment: h264 support.\nBy default JCEF doesn’t include the h264 codec due to patent restrictions. This isn’t a problem for our use case but it means we need to get a binary build of CEF working and the build environment for Chrome is \u0026ldquo;tough\u0026rdquo;. So right now h264 isn’t working.\nOther than that we’re still missing Windows and Linux support. We’re also missing an installer that will deliver CEF seamlessly. All of those will ship together as part of an update in the next couple of weeks once all issues are resolved.\nHow does this Work? Up until now the JavaSE port had one version which was JavaSEPort. This is now a base class for three implementations:\nJavaFX — a compatibility mode implementation which is currently the default.\nCEF — the new mode which will run if the cef directory is available/\nJMF — a special case that uses Java Media Framework for media playback instead of JavaFX or JCEF. It has the advantage of being very small. It works very similarly to the CEF approach by searching for the JMF jar in the .codenameone directory and using it if it’s available. We’re not sure this is a use case worth pursuing.\nOn launch we pick the best option. If CEF is available under the .codenameone directory we pick that implementation. This uses the native library and integrates directly into the UI.\nUp Next Once this migration is done we’ll follow up with some posts on debugging under CEF etc. Please let us know if you run into trouble ASAP. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDurank — July 17, 2020 at 12:12 pm (permalink) Durank says:\nwhen this post it will be available to windows? this means that the actual simulator will not work?\nShai Almog — January 20, 2021 at 2:26 am (permalink) Shai Almog says:\nSee the section titled: \u0026ldquo;Windows Install\u0026rdquo; above…\nSteve Hannah — July 17, 2020 at 1:48 pm (permalink) Steve Hannah says:\nWindows will be available soon.\nThe simulator will still work without CEF. If you are on Windows, and your app doesn’t use Media or BrowserComponent, then it will still work fine (without CEF). If your app uses Media or BrowserComponent, then just make sure you’re using a JDK that has JavaFX, such as ZuluFX – and it will work fine.\nAngelo — August 3, 2020 at 1:53 pm (permalink) Angelo says:\nI think that the CEF install instructions for Linux are wrong, because the zip file has not cef as root so the unzipping happens, but I had to create manually the cef folder and copy the zip content there. I hope it is useful.\nAngelo — August 3, 2020 at 2:01 pm (permalink) Angelo says:\nAs for the cef loading into the IDE, no updates are available for IntellJ Idea so, being that it seems that I cannot receive the codename updates as soon as they are published, I have to wait for the IDE update. Unless there is a workaround that you know to force the update.\nShai Almog — August 4, 2020 at 3:34 am (permalink) Shai Almog says:\nUgh. I’ll fix the instructions for that. Thanks.\nShai Almog — August 4, 2020 at 3:36 am (permalink) Shai Almog says:\nWe push updates separately from the plugins. That way we can support 3 IDEs with more common code. Just update via Codename One Settings using the menu on the top right.\nIf you still have the old settings UI it’s under the Basic section.\nAngelo — August 4, 2020 at 7:42 am (permalink) Angelo says:\nThe settings app found that there was a lock file in the .codename directory. I had to delete it to perform the update.\nIt is possible that also the other Codename plugin updates on my environment were blocked by that. Maybe the automatic update procedure should check it and inform the user, in case.\nRichard Matovu — August 9, 2020 at 9:13 am (permalink) Richard Matovu says:\nI have intergrated CEF in my project and it runs well. When i came to the point where it had to show a browser component, it showed an error \u0026ldquo;An internal application error occured: java.lang.RuntimeException: Failed to create CEF browser\u0026rdquo; and in the console it displayed:\nCEF Args: [–disable-gpu, –disable-software-rasterizer, –disable-gpu-compositing, –touch-events=enabled, –enable-media-stream, –device-scale-factor=4, –force-device-scale-factor=4, –autoplay-policy=no-user-gesture-required, –enable-usermedia-screen-capturing]\njava.lang.RuntimeException: Failed to create CEF browser\nat com.codename1.impl.javase.cef.JavaCEFSEPort.createCEFBrowserComponent(JavaCEFSEPort.java:106)\nat com.codename1.impl.javase.cef.JavaCEFSEPort.createBrowserComponent(JavaCEFSEPort.java:81)\nat com.codename1.ui.BrowserComponent$9.run(BrowserComponent.java:531)\n[EDT] 0:0:19,935 – Exception: java.lang.RuntimeException – Failed to create CEF browser\nat com.codename1.ui.Display.processSerialCalls(Display.java:1331)\nat com.codename1.ui.Display.edtLoopImpl(Display.java:1274)\nat com.codename1.ui.Display.mainEDTLoop(Display.java:1162)\nat com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)\nat com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)\nCaused by: java.lang.reflect.InvocationTargetException\nat java.desktop/java.awt.EventQueue.invokeAndWait(EventQueue.java:1367)\nat java.desktop/java.awt.EventQueue.invokeAndWait(EventQueue.java:1342)\nat com.codename1.impl.javase.cef.JavaCEFSEPort.createCEFBrowserComponent(JavaCEFSEPort.java:99)\n… 7 more\nCaused by: java.lang.UnsatisfiedLinkError: /home/donrix/.codenameone/cef/lib/linux64/libjcef.so: libjawt.so: cannot open shared object file: No such file or directory\nat java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)\nat java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2442)\nat java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2498)\nat java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2694)\nat java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2640)\nat java.base/java.lang.Runtime.loadLibrary0(Runtime.java:830)\nat java.base/java.lang.System.loadLibrary(System.java:1873)\nat org.cef.SystemBootstrap$1.loadLibrary(SystemBootstrap.java:24)\nat org.cef.SystemBootstrap.loadLibrary(SystemBootstrap.java:36)\nat org.cef.CefApp.startup(CefApp.java:536)\nat com.codename1.impl.javase.cef.CEFBrowserComponent.create(CEFBrowserComponent.java:178)\nat com.codename1.impl.javase.cef.CEFBrowserComponent.create(CEFBrowserComponent.java:170)\nat com.codename1.impl.javase.cef.CEFBrowserComponent.create(CEFBrowserComponent.java:167)\nat com.codename1.impl.javase.cef.JavaCEFSEPort.createCEFBrowserComponent(JavaCEFSEPort.java:112)\nat com.codename1.impl.javase.cef.JavaCEFSEPort$2.run(JavaCEFSEPort.java:102)\nat java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:303)\nat java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)\nat java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)\nat java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)\nat java.base/java.security.AccessController.doPrivileged(Native Method)\nat java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)\nat java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)\nat java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)\nat java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)\nat java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)\nat java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)\nat java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)\nat java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)\nShai Almog — August 10, 2020 at 5:09 am (permalink) Shai Almog says:\nThanks. Can you please post an issue about this in the issue tracker. Please also include some information about your system such as env output, distro etc. The issue tracker is here: https://github.com/codenameone/CodenameOne/issues/\nCarlos Verdier — August 14, 2020 at 9:28 am (permalink) Carlos Verdier says:\nNot working for me. Whenever I try to play a video or open a browser, it refuses with this output:\n\u0026ldquo;/Users/carlos/.codenameone/cef/macos64/libjcef.dylib: dlopen(/Users/carlos/.codenameone/cef/macos64/libjcef.dylib, 1): no suitable image found. Did find:\n/Users/carlos/.codenameone/cef/macos64/libjcef.dylib: code signature in (/Users/carlos/.codenameone/cef/macos64/libjcef.dylib) not valid for use in process using Library Validation: library load disallowed by system policy\u0026rdquo;\nTested on Mac OS Catalina 10.15.6\nSteve Hannah — August 14, 2020 at 12:52 pm (permalink) Steve Hannah says:\nI haven’t been able to reproduce this error, but I’ve found lots of bug reports around the internet related to Catalina. It could be related to the JDK that you’re using, if it is signed/notarized. Or it could be related to restrictive settings in Catalina.\nCan you file this in the issue tracker so we can track it. As a starting point, what JDK are you using?\nArtur Hefczyc — August 27, 2020 at 9:20 pm (permalink) Artur Hefczyc says:\nOn Macs downloaded files are often automatically unzipped. In such a case, you can add that info to install the cef using move command instead:\n\u0026ldquo; mv ~/Downloads/cef ~/.codenameone/ \u0026quot;\nArtur Hefczyc — August 28, 2020 at 7:21 pm (permalink) Artur Hefczyc says:\nI have installed cef as instructed above. However, when I run my app in simulator I still see\n\u0026ldquo; CSS\u0026gt; JavaFX is loaded \u0026quot;\nin the console output. Is this expected? I mean, do you still use JavaFX in simulator even if cef is installed?\nShai Almog — August 29, 2020 at 4:34 am (permalink) Shai Almog says:\nI think that’s a buggy printout from the prior condition. It indicates you have JavaFX in your system but it probably still uses CEF anyway. I filed an issue on that here: https://github.com/codenameone/CodenameOne/issues/3245\nArtur Hefczyc — September 11, 2020 at 3:44 am (permalink) Artur Hefczyc says:\nSo, how to make sure I am running in CEF mode instead of JavaFX? Is there any way to confirm the env my app us running in?\nShai Almog — September 11, 2020 at 3:45 am (permalink) Shai Almog says:\nIf http://localhost:8088/ in chrome shows the debugging options for the browser then CEF is working as expected\nArtur Hefczyc — September 11, 2020 at 4:49 pm (permalink) Artur Hefczyc says:\nNeither with my app running in simulator or running as a compiled desktop app Chrome shows anything at this address:\n\u0026ldquo; This site can’t be reached localhost refused to connect. \u0026quot;\nThe cef folder exist:\n\u0026ldquo; $ ll ~/.codenameone/cef total 720 -rw-r–r–@ 1 usr staff 170K Jul 10 15:12 jcef-tests.jar -rw-r–r–@ 1 usr staff 185K Jul 10 15:12 jcef.jar drwxr-xr-x@ 8 usr staff 256B Jul 10 15:12 macos64 \u0026quot;\nDo you have any suggestions on what can be wrong?\nShai Almog — September 11, 2020 at 4:51 pm (permalink) Shai Almog says:\nIs this not reachable when a browser component is physically on the screen?\nJulio Valeriron Ochoa — January 19, 2021 at 8:49 pm (permalink) Julio Valeriron Ochoa says:\nhow can I configure new cfe simulator in windows?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/big-changes-jcef/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/big-changes-jcef/generic-java-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eToday we released one of the biggest changes to Codename Ones simulator in ages. We added the ability to use CEF (Chrome Embedding Framework). This is \u003cstrong\u003ecurrently\u003c/strong\u003e off by default but even if you don’t use it you might feel the impact so it’s crucial that you read this post.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eUpdated July 31st with additional platform instructions below\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eUpdated August 2nd with correction to the Linux install script\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eUpdated August 4th with another correction to the Linux install script\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"the-tldr\"\u003eThe TL;DR\u003c/h3\u003e\n\u003cp\u003eThe big change for those of you who don’t care about the details is this: FX will no longer install automatically if it’s missing. That might be a good thing for some applications. But if you rely on media/web things might break in the simulator/debugger.\u003c/p\u003e","title":"Big Changes and CEF"},{"content":"\nRecently I got a question on stackoverflow about doing a diagonal badge that’s actually quite similar to the one on our website. This isn’t hard to do in Codename One but it requires a bit of tinkering so here’s how you would implement that.\nAs a matter of fact the original code I provided in the answer had a bit of a misbehavior which I’m fixing for this blog post so everything will look correct:\nForm hi = new Form(\u0026quot;Hi World\u0026quot;, BoxLayout.y()); // just filling some space so the layer below will be visible SpanLabel base = new SpanLabel(\u0026quot;Hi World,nLorem IpsumnLorem IpsumnLorem IpsumnLorem IpsumnLorem IpsumnLorem IpsumnLorem IpsumnLorem IpsumnLorem IpsumnLorem Ipsumn\u0026quot;); // this is the green label Label green = new Label(\u0026quot;Green Stuff\u0026quot;) { private int actualHeight = 10; // we ask for more space so when we rotate the label it won't be clipped out @Override protected Dimension calcPreferredSize() { Dimension d = super.calcPreferredSize(); // since we asked for more space the background will become a sqare // we don't want that so we save the \u0026quot;real\u0026quot; height here actualHeight = d.getHeight(); d.setHeight(d.getWidth()); return d; } @Override public void paint(Graphics g) { // I move the drawing context up and to the left otherwise // the banner will be cropped on the corner and look odd g.translate(-(actualHeight / 2), -(actualHeight / 2)); __**(1)** // we rotate by 45 degrees in radians around the pivot point // which is the center of the component g.rotateRadians((float)(-Math.PI / 4.0), getX() + getWidth() / 2, getY() + getHeight() / 2); // we save the old color and set a background color then // draw the background manually int c = g.getColor(); g.setColor(0xff00); // we take extra space so the banner will stretch further // I use fill here but I can use draw image if I have an // image from the designer that looks better g.fillRect(getX() - 50, getY() + getHeight() / 2 - actualHeight / 2, getWidth() + 100, actualHeight); // we let the label draw its content super.paint(g); // restoring the graphics context to the original value g.setColor(c); g.resetAffine(); } }; // we're drawing the background manually so we must make it transparent Style s = green.getUnselectedStyle(); s.setBgTransparency(0); // I want extra side padding because the rotation will cause the sides // to crop so the text needs to be in the center s.setPaddingUnit(Style.UNIT_TYPE_DIPS); __**(2)** s.setPadding(1, 1, 3, 3); // we're layering the component on top of one another. The green // label is positioned in the top left coordinate. Container cnt = LayeredLayout.encloseIn(base, FlowLayout.encloseIn(green)); hi.add(cnt); hi.show(); __1 The original post was missing this line to move the context up and to the left __2 It was also missing these two lines So this is what we see in the new code:\nFigure 1. The Correct Banner\nBut the older code cropped things badly causing an arrow effect:\nFigure 2. The Arrow Effect\nWhat we see here is the banner being drawn at the edge of the component bounds. As a result the component bounds crop it on the right and bottom producing an arrow.\nMoving the drawing a bit up and to the left makes sure we reach the edge at just the right place.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/diagonal-badging/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/diagonal-badging/learn-codenameone-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eRecently I got a \u003ca href=\"https://stackoverflow.com/questions/62639544/codename-one-how-to-design-an-inverted-status-badge/62669046\" target=\"_blank\" rel=\"noopener noreferrer\"\u003equestion on stackoverflow\u003c/a\u003e about doing a diagonal badge that’s actually quite similar to the one on our website. This isn’t hard to do in Codename One but it requires a bit of tinkering so here’s how you would implement that.\u003c/p\u003e\n\u003cp\u003eAs a matter of fact the original code I provided in the answer had a bit of a misbehavior which I’m fixing for this blog post so everything will look correct:\u003c/p\u003e","title":"Diagonal Badging"},{"content":"\nOn some devices, Capture APIs return images with the correct orientation, meaning that they do not need to be changed to display correctly; on other devices, they return images with a fixed orientation and an EXIF tag that indicates how they must be rotated or flipped to display correctly.\nMore precisely, the Orientation Tag indicates the orientation of the camera with respect to the captured scene and can take a value from 0 to 8, as illustrated on the page Exif Orientation Tag. For testing purposes, you can download landscape and portrait images with all possible orientation values from the EXIF Orientation-flag example images repository.\nWhat happens if we ignore the Orientation Tag Suppose we acquire an image with the following code:\nForm hi = new Form(\u0026quot;Capture Test\u0026quot;, BoxLayout.y()); Button button = new Button(\u0026quot;Take Photo\u0026quot;); ScaleImageLabel photoLabel = new ScaleImageLabel(); hi.addAll(button, photoLabel); hi.show(); button.addActionListener(l -\u0026gt; { String photoTempPath = Capture.capturePhoto(); if (photoTempPath != null) { __**(1)** try { String photoStoragePath = \u0026quot;myPhoto.jpg\u0026quot;; Util.copy(FileSystemStorage.getInstance().openInputStream(photoTempPath), Storage.getInstance().createOutputStream(photoStoragePath)); __**(2)** photoLabel.setIcon(EncodedImage.create(Storage.getInstance().createInputStream(photoStoragePath), Storage.getInstance().entrySize(photoStoragePath))); __**(3)** hi.revalidate(); } catch (IOException ex) { Log.p(\u0026quot;Error after capturing photo\u0026quot;, Log.ERROR); Log.e(ex); Log.sendLogAsync(); } } }); A few remarks:\n__1 photoTempPath is null if the user has cancelled the photo capture; __2 in this case, copying the file from the FileSystemStorage temporary folder to a \u0026ldquo;secure\u0026rdquo; location in FileSystemStorage or Storage is not strictly necessary, but it is a good habit that in certain circumstances prevents issues; __3 it is always preferable to use EncodedImage when we want to keep the impact on memory low. Desired result On my iPhone, the image is always in portrait orientation:\nUnwanted result This is the case of my Samsung Galaxy, the image was taken in portrait, but shown in a different orientation:\nSolving This Problem All it takes is a small change to the code to solve this issue.\nJust replace:\nString photoStoragePath = \u0026quot;myPhoto.jpg\u0026quot;; Util.copy(FileSystemStorage.getInstance().openInputStream(photoTempPath), Storage.getInstance().createOutputStream(photoStoragePath)); photoLabel.setIcon(EncodedImage.create(Storage.getInstance().createInputStream(photoStoragePath), Storage.getInstance().entrySize(photoStoragePath))); with:\nString photoSafePath = FileSystemStorage.getInstance().getAppHomePath() + \u0026quot;/myPhoto.jpg\u0026quot;; __**(1)** Image img = Image.exifRotation(photoTempPath, photoSafePath, 1000); __**(2)** photoLabel.setIcon(img); __**(3)** __1 In this case, we have to use FileSystemStorage rather than Storage due to a limitation of the exifRotation API, which maybe will be solved in the future; __2 the third parameter is optional, but as explained in the exifRotation Javadoc, the rotation of a high-resolution image is very inefficient, it is better to set the maximum size (width or height) that the image can assume, in this case 1000px, to obtain a significant advantage in processing time on less performing devices; __3 note that the instance of the Image object returned by exifRotation is an EncodedImage, to keep the impact on memory low. Final result On my iPhone the result is the same (as expected), while on my Android, taking the same photo, I get:\nThis is the desired result. As a final note, I mention the Image.getExifOrientationTag API which allows you to get the EXIF orientation tag of an image, if available.\nNetwork error resistant downloads with automatic resume When we download a big file, such as a high-resolution image or a video, there are problems that can prevent the download from finishing:\nThe user moves the app to the background or external conditions (such as a phone call) move the app to the background;\nThe operating system enters power saving mode;\nThe Internet connection is lost or any other network error interrupts the download.\nA server-side error may also occur, but this cannot be resolved client-side. All the other circumstances mentioned above can, provided that the server supports partial downloads via HTTP headers. Fortunately, this is a feature available by default on most common servers (such as Apache or Spring Boot). Almost all download managers allow to resume interrupted downloads, so I thought it was important to add such a feature to Codename One.\nThe solution THe new API Util.downloadUrlSafely safely download the given URL to the Storage or to the FileSystemStorage.\nThis method is resistant to network errors and capable of resume the download as soon as network conditions allow and in a completely transparent way for the user.\nServer requirements The server must correctly return the Content-Length header and it must supports partial downloads.\nGlobal network error handling requirements In the global network error handling, there must be an automatic .retry() of the ConnectionRequest in the case of a network error.\nI think the best way to show the use of this API is an actual complete example, which you can try as it is in the Simulator and on real devices:\npublic class MyApplication { private Form current; private Resources theme; public void init(Object context) { // use two network threads instead of one updateNetworkThreadCount(2); theme = UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;); // Enable Toolbar on all Forms by default Toolbar.setGlobalToolbar(true); // Pro only feature Log.bindCrashProtection(true); // Manage both network errors (connectivity issues) and server errors (codes different from 2xx) addNetworkAndServerErrorListener(); } public void start() { if(current != null){ current.show(); return; } String url = \u0026quot;https://www.informatica-libera.net/video/AVO_Cariati_Pasqua_2020.mp4\u0026quot;; // 38 MB Form form = new Form(\u0026quot;Test Download 38MB\u0026quot;, BoxLayout.y()); Label infoLabel = new Label(\u0026quot;Starting download...\u0026quot;); form.add(infoLabel); try { Util.downloadUrlSafely(url, \u0026quot;myHeavyVideo.mp4\u0026quot;, (percentage) -\u0026gt; { // percentage callback infoLabel.setText(\u0026quot;Downloaded: \u0026quot; + percentage + \u0026quot;%\u0026quot;); infoLabel.repaint(); }, (filename) -\u0026gt; { // file saved callback infoLabel.setText(\u0026quot;Downloaded completed\u0026quot;); int fileSizeMB = Storage.getInstance().entrySize(filename) / 1048576; form.add(\u0026quot;Checking files size: \u0026quot; + fileSizeMB + \u0026quot; MB\u0026quot;); form.revalidate(); }); } catch (IOException ex) { Log.p(\u0026quot;Error in downloading: \u0026quot; + url); Log.e(ex); form.add(new SpanLabel(\u0026quot;Error in downloading:n\u0026quot; + url)); form.revalidate(); } form.show(); } public void stop() { current = getCurrentForm(); if(current instanceof Dialog) { ((Dialog)current).dispose(); current = getCurrentForm(); } } public void destroy() { } private void addNetworkAndServerErrorListener() { // The following way to manage network errors is discussed here: // https://stackoverflow.com/questions/61993127/distinguish-between-server-side-errors-and-connection-problems addNetworkErrorListener(err -\u0026gt; { // prevents the event from propagating err.consume(); if (err.getError() != null) { // this is the case of a network error, // like: java.io.IOException: Unreachable Log.p(\u0026quot;Error connectiong to: \u0026quot; + err.getConnectionRequest().getUrl(), Log.ERROR); // maybe there are connectivity issues, let's try again ToastBar.showInfoMessage(\u0026quot;Reconnect...\u0026quot;); Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { err.getConnectionRequest().retry(); } }, 2000); } else { // this is the case of a server error // logs the error String errorLog = \u0026quot;REST ERRORnURL:\u0026quot; + err.getConnectionRequest().getUrl() + \u0026quot;nMethod: \u0026quot; + err.getConnectionRequest().getHttpMethod() + \u0026quot;nResponse code: \u0026quot; + err.getConnectionRequest().getResponseCode(); if (err.getConnectionRequest().getRequestBody() != null) { errorLog += \u0026quot;nRequest body: \u0026quot; + err.getConnectionRequest().getRequestBody(); } if (err.getConnectionRequest().getResponseData() != null) { errorLog += \u0026quot;nResponse message: \u0026quot; + new String(err.getConnectionRequest().getResponseData()); } if (err.getConnectionRequest().getResponseErrorMessage() != null) { errorLog += \u0026quot;nResponse error message: \u0026quot; + err.getConnectionRequest().getResponseErrorMessage(); } Log.p(errorLog, Log.ERROR); Log.sendLogAsync(); ToastBar.showErrorMessage(\u0026quot;Server Error\u0026quot;, 10000); } }); } } Safe Uploads? Implementing uploads with the same features (network error resistance and automatic resume) is more complex, because in this case we do not have a reference standard available by default on the most common servers.\nMoreover, the possibility of partial uploads assumes that, after a network error, the server must keep the partially uploaded file and there are no ambiguities about which client has partially uploaded which file.\nApplications such as Dropbox, Google Drive, OwnCloud and similar use specific internal standards. As far as I’m concerned, I’m almost completed deploying my own client-server solution to allow secure, network error-resistant with automatic resume uploads with Codename One and Spring Boot. This solution, however, is too specific to be included in the Codename One API and, anyway, I still have to do a lot of testing to make sure it works as it should. I’ll possibly publish a tutorial about it when it is finished. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJavier Anton — July 3, 2020 at 10:45 pm (permalink) Really useful stuff. Just wondering, the safe download always requires the app to be in fg to finish, right? I mean, the download won’t finish if the app goes into bg and never comes back? And my second question is: does the download effectively pause when the app is in bg? Thx\nShai Almog — July 4, 2020 at 4:50 am (permalink) This uses background fetch to download in the background so download continues automatically when the device is backgrounded. Normally when a device is sent to background a download will stop in this case it’s supposed to continue.\nFrancesco Galgani — July 5, 2020 at 5:46 am (permalink) I’m afraid there’s been a misunderstanding. As I wrote: \u0026ldquo;This method is resistant to network errors and capable of resume the download as soon as network conditions allow and in a completely transparent way for the user. This is regardless of whether the download continues or not when the app goes in background: if the operating system stops the download when the app goes in background, it will automatically resume when the app goes back in foreground, otherwise it will continue in background. More specifically, usually (but not necessarily always) the download will continue in the background on Android, while it will \u0026ldquo;pause\u0026rdquo; on iOS. Without this method, when the app goes into the background the download can be \u0026ldquo;killed\u0026rdquo; without finish, with this method the download will be restored to where it came from when the app returns to foreground. In this sense, it is normal to expect the download to end when the app is returned to foreground, although in some cases (such as Android) it may continue and complete in the background. Backgroundfetch is therefore not used.\nShai Almog — July 5, 2020 at 6:17 am (permalink) Shai Almog says:\nThanks for the clarification. I didn’t recall the PR exactly but recalled our stackoverflow discussion.\nWhat about adding something closer to what was done in stackoverflow with background fetch?\nMaybe as a secondary API we can add to the stop() call? E.g. convertOngoingDownloads()?\nI’m guessing we would need a DownloadManager sort of API to do something like that.\nFrancesco Galgani — July 5, 2020 at 7:17 am (permalink) Francesco Galgani says:\nI will try to study this problem to improve this API, the problem is that \u0026ldquo;background fetch\u0026rdquo; is not usable for heavy downloads. I quote:\n\u0026ldquo;You only have seconds to operate when doing a background fetch — the consensus figure is a maximum of 30 seconds, but shorter is better. If you need to download large resources as part of the fetch, this is where you need to use URLSession‘s background transfer service.\u0026rdquo; fonte: https://www.raywenderlich.com/5817-background-modes-tutorial-getting-started\nI don’t know this \u0026ldquo;URLSession‘s background transfer service\u0026rdquo;. Is this something that requires a native interface? Do you have any suggestions for me?\nShai Almog — July 6, 2020 at 5:35 am (permalink) Shai Almog says:\nNot sure. I’ll have to look into that too.\nJavier Anton — July 6, 2020 at 6:49 am (permalink) Javier Anton says:\nI hope you get this sorted – was on my todo list too. You can do iOS bg fetch and just catch whether the OS kills the download. The issue is that you will need to run it in a native interface and provide a callback static method somewhere in your java code. Perhaps you could also use some other method to notify your main thread (NSUserDefaults or writing a persisted file). I’m not sure which is best for your implementation. Good luck! 🙂\nJavier Anton — August 13, 2020 at 3:21 pm (permalink) Javier Anton says:\nWow. I was just testing with some photos my wife had taken with her pro camera and noticed that some pictures that showed up properly in the OS were being rotated by the Simulator. I then remembered this post, decided to see if it would fix this and… voila! Thanks for this Francesco, really great stuff\nOne question I have is: if I don’t set a maximum px in the 3rd parameter of exifRotation, will it make it harder for images that need rotating, or will it make it harder for all images?\nEdit: this will mistakenly rotate 90 degrees to the right images captured by my Galaxy A10 camera\nJavier Anton — August 13, 2020 at 4:15 pm (permalink) Javier Anton says:\nAnother question I have is: why use the ImageIO.save so much? A lot of the operations can be done without needing to re-save the image to a different file. Am I missing something?\nShai Almog — August 14, 2020 at 4:33 am (permalink) Shai Almog says:\nIf rotatedImage url is null it won’t save the rotated image to a file so there’s no need for that. Notice that it always returns an encoded image so there will always be an encoder overhead.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/exif-orientation-automatic-captured-image-rotation/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/exif-orientation-automatic-captured-image-rotation/guest-post-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOn some devices, \u003ccode\u003eCapture\u003c/code\u003e APIs return images with the correct orientation, meaning that they do not need to be changed to display correctly; on other devices, they return images with a fixed orientation and an EXIF tag that indicates how they must be rotated or flipped to display correctly.\u003c/p\u003e\n\u003cp\u003eMore precisely, the Orientation Tag indicates the orientation of the camera with respect to the captured scene and can take a value from 0 to 8, as illustrated on the page \u003ca href=\"http://sylvana.net/jpegcrop/exif_orientation.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eExif Orientation Tag\u003c/a\u003e. For testing purposes, you can download landscape and portrait images with all possible orientation values from the \u003ca href=\"https://github.com/recurser/exif-orientation-examples\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eEXIF Orientation-flag example images repository\u003c/a\u003e.\u003c/p\u003e","title":"Exif Orientation Tag and Smart Downloads"},{"content":"\nWe recently added support to detect whether a device is running in dark/light mode based on this issue. Some of the code in the implementation is also derived from that issue submitted by Javier.\nDetecting Dark Mode Dark mode can be detected using APIs in the CN and Display classes. Specifically isDarkMode() and setDarkMode(Boolean).\nNotice that isDarkMode() returns Boolean and not boolean. This means that null is a valid value for this method. The case of null indicates that dark mode detection isn’t available or isn’t working on this platform.\nYou can override the dark mode setting for the platform using setDarkMode().\nAt this time dark mode detection only works on iOS, Android and JavaScript. We tried adding desktop support for that, but it proved a bit challenging. UWP detection isn’t supported at the moment.\nWe don’t currently have an event based API for dark mode detection. While nice, this isn’t universally supported and can be circumvented with a simple timer.\nNative/Builtin Theme Support Ideally, the app would just switch to dark mode seamlessly but right now this isn’t the case. The theme constant darkModeBool changes some deep core theme styles to match dark mode if isDarkMode() is true. In the future it might trigger a dark version of the native theme. At the moment we don’t have dark versions of the themes.\nTo create a dark version of your app create a new resource file for dark mode and load it conditionally based on dark mode. You can do the same for CSS by creating a CSS file called dark.css and editing your build.xml file to replicate the CSS conversion line. Specifically:\n\u0026lt;target name=\u0026quot;-cn1-compile-css\u0026quot; if=\u0026quot;codename1.cssTheme\u0026quot;\u0026gt; \u0026lt;java jar=\u0026quot;${user.home}/.codenameone/designer_1.jar\u0026quot; fork=\u0026quot;true\u0026quot; failonerror=\u0026quot;true\u0026quot;\u0026gt; \u0026lt;jvmarg value=\u0026quot;-Dcli=true\u0026quot;/\u0026gt; \u0026lt;arg value=\u0026quot;-css\u0026quot;/\u0026gt; \u0026lt;arg file=\u0026quot;css/theme.css\u0026quot;/\u0026gt; \u0026lt;arg file=\u0026quot;src/theme.res\u0026quot;/\u0026gt; \u0026lt;/java\u0026gt; \u0026lt;java jar=\u0026quot;${user.home}/.codenameone/designer_1.jar\u0026quot; fork=\u0026quot;true\u0026quot; failonerror=\u0026quot;true\u0026quot;\u0026gt; \u0026lt;jvmarg value=\u0026quot;-Dcli=true\u0026quot;/\u0026gt; \u0026lt;arg value=\u0026quot;-css\u0026quot;/\u0026gt; \u0026lt;arg file=\u0026quot;css/dark-theme.css\u0026quot;/\u0026gt; \u0026lt;arg file=\u0026quot;src/dark-theme.res\u0026quot;/\u0026gt; \u0026lt;/java\u0026gt; \u0026lt;/target\u0026gt; Then in Java code you can load a different theme and change themes at runtime using our builtin theming.\n__ You can put two themes in a single resource file but since most settings can’t be reused between dark/light the benefit is limited You can load a new resource file theme by using:\ntheme = UIManager.initFirstTheme(\u0026quot;/resource\u0026quot;); You can then apply the theme to the current form dynamically using refreshTheme() on the form.\nMoving Forward We hope to add additional dark/light templates and also port the native themes to include dark counterparts. This work isn’t scheduled yet but this is the direction. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMohammed Hussein — August 28, 2022 at 8:55 pm (permalink) Mohammed Hussein says:\nHi Shai, just landed on this blog!! while searching on an issue with CSS theme switching, here’s what I did and please keep me right if misunderstood:\nI migrated successfully to Maven using my existing theme.css, following the KitchenSink demo, I try to add another dark-them.css, using :\nResources resources = Resources.openLayered( \u0026quot;/dark-theme\u0026quot;); Sadly, I keep getting \u0026ldquo;/dark-theme.res not found\u0026rdquo; and no sign to the .res file on my folders!\nAlso, please note that, build.xml does not exists on my Maven project!,\nCan you please advise with any hints on how to switch my theme with CSS?\nBest regards,\nMohammed Hussein — September 1, 2022 at 8:46 am (permalink) Mohammed Hussein says:\nThank you Shai,\nFor those landing on this and using Maven, please note the following:\nCompiling the dark theme is not yet supported by the Maven plugin. An issue for this can be track on:\nhttps://github.com/codenameone/CodenameOne/issues/3623\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/dark-mode/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/dark-mode/dark-mode.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe recently added support to detect whether a device is running in dark/light mode based on \u003ca href=\"https://github.com/codenameone/CodenameOne/issues/2979\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ethis issue\u003c/a\u003e. Some of the code in the implementation is also derived from that issue submitted by \u003ca href=\"https://github.com/javieranton-zz\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eJavier\u003c/a\u003e.\u003c/p\u003e\n\u003ch3 id=\"detecting-dark-mode\"\u003eDetecting Dark Mode\u003c/h3\u003e\n\u003cp\u003eDark mode can be detected using APIs in the \u003ca href=\"/javadoc/com/codename1/ui/CN/\"\u003eCN\u003c/a\u003e and \u003ca href=\"/javadoc/com/codename1/ui/Display/\"\u003eDisplay\u003c/a\u003e classes. Specifically \u003ccode\u003eisDarkMode()\u003c/code\u003e and \u003ccode\u003esetDarkMode(Boolean)\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eNotice that \u003ccode\u003eisDarkMode()\u003c/code\u003e returns \u003ccode\u003eBoolean\u003c/code\u003e and not \u003ccode\u003eboolean\u003c/code\u003e. This means that \u003ccode\u003enull\u003c/code\u003e is a valid value for this method. The case of \u003ccode\u003enull\u003c/code\u003e indicates that dark mode detection isn’t available or isn’t working on this platform.\u003c/p\u003e","title":"Dark Mode"},{"content":"\nCodename One itself never depended on JavaFX. This kept us small and performant. However, we need JavaFX to support HTML and media in the simulator and on the desktop ports. This was a choice we made easily back in the Java 8 days. JavaFX was integrated into the official JDK and this was an easy choice to make.\nThen Java 9 came out and everything broke. Most JVMs ship without JavaFX now and downloading it dynamically for the simulator is error prone to say the least. Even I had problems setting up our environment on some foreign machines. Every day we need to deal with multiple support queries and people who have issues with VM configuration. 99% are due to the pain of dealing with JavaFX installation on top of the VM.\nNot Worth Fixing There are many approaches we could take to try and solve this. All of them suck but they are possible…​\nWe could create different versions of Codename One for each platform and ship with our own OpenJDK port that includes everything we need. This would have ballooned the size of install and made it harder for you to customize/tinker with Codename One.\nThe problem is we’d still be stuck with FX.\nThe main reason for using FX is the BrowserComponent. Swing just doesn’t have a decent browser widget and FX provides the closest thing to a browser we can use…​\nThe thing is, it still sucks. Newer web standards aren’t supported. Debugging is difficult and it crashes…​ A lot.\nA Better Way Recently IntelliJ took the same path, they decided to deprecate the use of JavaFX in favor of JCEF.\nIf we migrate to JCEF we’d have access to the latest Chromium APIs and tools. Ideally we’d also enjoy better stability, control and JVM compatibility. The drawback is that we’d need to write native code and possibly increase the Codename One download size.\nThe big missing piece here is media. We’re still testing the waters on this but a good direction might be to use the media capabilities of Chromium to show things in the simulator and desktop ports.\nCompatibility In order to maintain compatibility for developers using the desktop port we’ll keep the existing implementation that relies on JavaFX for the short term. Since the desktop port packages the VM within this shouldn’t be a problem.\nHowever, we will change the default build to use JCEF once we deem this stable enough and might eventually sunset the FX port entirely based on your feedback. This will have a big size advantage for developers as we’ll be able to package a smaller VM without the JavaFX dependency. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — June 20, 2020 at 10:59 pm (permalink) Francesco Galgani says:\nJavaFX is necessary also for the CSS support, in particular for generating 9-piece image borders.\nShai Almog — June 21, 2020 at 1:46 am (permalink) Shai Almog says:\nYes, but it won’t be with JCEF as it can be used instead and would probably work better/faster as well.\nJavier Anton — June 24, 2020 at 8:52 pm (permalink) Javier Anton says:\nWe recently introduced (.net) CEF in one of the apps I make at work to replace embedded IEs. It increased the build size from 7 to 70MB. The business could not be happier as performance has really improved. People like performance. Desktop build size is not as much of a problem as mobile app size\nShai Almog — June 25, 2020 at 2:01 am (permalink) Shai Almog says:\nYes. Actually for the desktop apps I think it will be smaller than the full blown JavaFX VM and we will be able to download it dynamically if necessary in the future.\nThe main problem is the IDE libraries. Here size matters. Every week we release an update and if that update includes a 60mb CEF attachment this can be a problem. So we need this as a separate thing from the main JAR and ideally we’d want to keep it completely separate as our plugin is already freakishly huge.\nAngelo — July 15, 2020 at 2:47 pm (permalink) Angelo says:\nDo you cofirm it’s under active development and it wil be released in a few days?\nShai Almog — July 16, 2020 at 2:21 am (permalink) Shai Almog says:\nTake a look at our github commit history.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/moving-away-from-fx/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/moving-away-from-fx/generic-java-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One itself never depended on JavaFX. This kept us small and performant. However, we need JavaFX to support HTML and media in the simulator and on the desktop ports. This was a choice we made easily back in the Java 8 days. JavaFX was integrated into the official JDK and this was an easy choice to make.\u003c/p\u003e\n\u003cp\u003eThen Java 9 came out and everything broke. Most JVMs ship without JavaFX now and downloading it dynamically for the simulator is error prone to say the least. Even I had problems setting up our environment on some foreign machines. Every day we need to deal with multiple support queries and people who have issues with VM configuration. 99% are due to the pain of dealing with JavaFX installation on top of the VM.\u003c/p\u003e","title":"Moving Away from Java FX"},{"content":"\nA few weeks ago we got this question on stackoverflow. At first I didn’t think this issue was special…​ But as the investigation continued it became clear that we’re facing a weird issue…​\nThe issue started innocently enough. A device whose native resolution is high was rendering the UI in low resolution. This can happen because of a new DPI setting or configuration in a new SDK.\nBut the odd thing was this: if the apps package name was changed the resolution went back to normal!\nIt’s Samsung’s Fault Skipping to the end: it’s Samsung’s fault. The problem starts shortly after the submission to the play store. Samsung classifies the app as a game and in order to increase performance it runs it with a lower resolution/density.\nUse the contact option from this app and ask them to reclassify your app so it isn’t resized.\nThis information was available online but was remarkably hard to discover since we incorrectly assumed Google was at fault and didn’t think it was Samsung. There was no incriminating information in the console output that we could find or any hint of what had happened.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/samsung-lowers-resolution-randomly/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/samsung-lowers-resolution-randomly/from-stack-overflow.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA few weeks ago we got \u003ca href=\"https://stackoverflow.com/questions/61752978/codename-one-app-running-in-lower-resolution-android\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ethis question\u003c/a\u003e on stackoverflow. At first I didn’t think this issue was special…​ But as the investigation continued it became clear that we’re facing a weird issue…​\u003c/p\u003e\n\u003cp\u003eThe issue started innocently enough. A device whose native resolution is high was rendering the UI in low resolution. This can happen because of a new DPI setting or configuration in a new SDK.\u003c/p\u003e\n\u003cp\u003eBut the odd thing was this: if the apps package name was changed the resolution went back to normal!\u003c/p\u003e","title":"Samsung Lowers Resolution Randomly"},{"content":"\nThis is part 5 of the RAD Chatroom tutorial. You can find part 1 here, part 2 here, part 3 here and part 4 here.\nAdding A Photo Capture Feature Most messaging applications include the ability to add photos to messages. Let’s add this feature to our chat app now.\nFirst we’ll define a new action called \u0026ldquo;capturePhoto\u0026rdquo;, and add to the the TEXT_ACTIONS category of our view node.\npublic static final ActionNode capturePhoto = action( icon(FontImage.MATERIAL_CAMERA) ); ... ViewNode viewNode = new ViewNode( actions(ChatRoomView.SEND_ACTION, send), actions(ProfileAvatarView.PROFILE_AVATAR_CLICKED_MENU, phone, videoConference), actions(ChatBubbleView.CHAT_BUBBLE_LONG_PRESS_MENU, likeAction), actions(ChatBubbleView.CHAT_BUBBLE_BADGES, likedBadge), actions(ChatRoomView.TEXT_ACTIONS, capturePhoto) __**(1)** ); __1 Added capturePhoto action to the TEXT_ACTIONS category so that it will appear as a button beside the text field. And we’ll also add a handler for this action, which will capture a photo, and emed the photo in a message that we will add to the chat room’s view model.\naddActionListener(capturePhoto, evt-\u0026gt;{ evt.consume(); String photoPath = Capture.capturePhoto(); if (photoPath == null) { // User canceled the photo capture return; } File photos = new File(\u0026quot;photos\u0026quot;); __**(1)** photos.mkdirs(); Entity entity = evt.getEntity(); File photo = new File(photos, System.currentTimeMillis()+\u0026quot;.png\u0026quot;); try (InputStream input = FileSystemStorage.getInstance().openInputStream(photoPath); OutputStream output = FileSystemStorage.getInstance().openOutputStream(photo.getAbsolutePath())) { Util.copy(input, output); ChatBubbleView.ViewModel message = new ChatBubbleView.ViewModel(); message.attachmentImageUrl(photo.getAbsolutePath()); __**(2)** message.isOwn(true); message.date(new Date()); EntityList messages = entity.getEntityList(ChatRoom.messages); __**(3)** if (messages == null) { throw new IllegalStateException(\u0026quot;This chat room has no messages list set up\u0026quot;); } messages.add(message); __**(4)** } catch (IOException ex) { Log.e(ex); ToastBar.showErrorMessage(ex.getMessage()); } }); __1 We will create a directory named \u0026ldquo;photos\u0026rdquo; where we store all of the photos for the app. __2 Set the path of this photo under attachmentImageUrl. The ChatBubbleView will accept http, https, and file URLs, as well as storage keys. It will render them correctly in the view according to the type of URL it is. __3 The \u0026ldquo;entity\u0026rdquo; of this event is the view model for the ChatRoomView. Here we use the ChatRoom.messages tag to access the messages list in a loosely coupled way. This code will work even if we change the class that we use for the ChatRoomView’s view model. __4 Adding the message to the messages entity list will trigger a list change event and it will be rendered automatically in the chat room. Now, let’s fire the chat up again and take it for a test drive.\nFigure 1. The capturePhoto action is rendered as a button beside the input text field\nYou should now be able to click on the \u0026ldquo;capture photo\u0026rdquo; button to capture an image. In the simulator, it will open a file dialog to select an image. On device, it will activate the devices camera so that you can take a photo. After capturing an image, it should be added to the chat inside a message bubble as shown below:\nFigure 2. Photo appears in chat after capture\nLinking to a Back-end Chat Server In this tutorial we created a mock chat application in order to demostrate the ChatRoomView, which is a user interface component. It did not include any integration with a server so it doesn’t allow you to actually chat with other people. Linking to a server is not difficult, and the MVC architecture of this example should make it very clear how the integration should occur. I’ll leave this integration as an exercise for the reader. As a starting point, I recommend checking out the cn1-websockets library, and its chat demo. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nGareth Murfin — May 29, 2020 at 10:28 am (permalink) Super cool!!.. is there a github link for the finished product so we can check it out? I think you should cover the server side too to be honest, what would it link to, firebase?\nSteve Hannah — May 29, 2020 at 3:09 pm (permalink) I’ll likely add some sample servers at some point, but that isn’t really the focus here. Most people will either want to roll their own server anyways. There are so many different server-side technologies out there, and most devs are already married to one or another, so a sample server would basically just be to make the demo more interactive.\nThe most likely \u0026ldquo;server-side\u0026rdquo; sample would be to plug this into the existing WebSockets chat demo.\nLukman Jaji — May 29, 2020 at 7:29 pm (permalink) Lukman Jaji says:\nHi Steve. This is really cool. However, I installed the ap for this. When I snapped a photo, there is some delay before the photo is added to the chat. I am guessing it’s some resizing operations going on? No?\nSteve Hannah — May 29, 2020 at 9:41 pm (permalink) Steve Hannah says:\nThanks for reminding me. This has been reported by some other users as well. Yes, it is likely related to hi-res cameras and taking some time to resize the photos. This can be resolved by providing size parameters to the capturePhoto() method. I’ll be updating the sample to do this soon.\nGareth Murfin — July 14, 2020 at 10:52 pm (permalink) Gareth Murfin says:\nI’d like to see a way that we can link this chat system to firebase. Is there any starting point for this? examples etc in cn1.\nShai Almog — July 15, 2020 at 2:33 am (permalink) Shai Almog says:\nWe don’t have builtin support for firebase features other than push at this time.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/rad-chatroom-part-5/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/rad-chatroom-part-5/chat-ui-kit-feature.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is part 5 of the RAD Chatroom tutorial. You can find part 1 \u003ca href=\"/blog/rad-chatroom-part-1.html\"\u003ehere\u003c/a\u003e, part 2 \u003ca href=\"/blog/rad-chatroom-part-2.html\"\u003ehere\u003c/a\u003e, part 3 \u003ca href=\"/blog/rad-chatroom-part-3.html\"\u003ehere\u003c/a\u003e and part 4 \u003ca href=\"/blog/rad-chatroom-part-4.html\"\u003ehere\u003c/a\u003e.\u003c/p\u003e\n\u003ch3 id=\"adding-a-photo-capture-feature\"\u003eAdding A Photo Capture Feature\u003c/h3\u003e\n\u003cp\u003eMost messaging applications include the ability to add photos to messages. Let’s add this feature to our chat app now.\u003c/p\u003e\n\u003cp\u003eFirst we’ll define a new action called \u0026ldquo;capturePhoto\u0026rdquo;, and add to the the \u003ccode\u003eTEXT_ACTIONS\u003c/code\u003e category of our view node.\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003epublic static final ActionNode capturePhoto = action(\n        icon(FontImage.MATERIAL_CAMERA)\n);\n\n...\n\nViewNode viewNode = new ViewNode(\n    actions(ChatRoomView.SEND_ACTION, send),\n    actions(ProfileAvatarView.PROFILE_AVATAR_CLICKED_MENU, phone, videoConference),\n    actions(ChatBubbleView.CHAT_BUBBLE_LONG_PRESS_MENU, likeAction),\n    actions(ChatBubbleView.CHAT_BUBBLE_BADGES, likedBadge),\n    actions(ChatRoomView.TEXT_ACTIONS, capturePhoto) __**(1)**\n);\n\u003c/code\u003e\u003c/pre\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003cstrong\u003e1\u003c/strong\u003e\u003c/th\u003e\n          \u003cth\u003eAdded capturePhoto action to the TEXT_ACTIONS category so that it will appear as a button beside the text field.\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eAnd we’ll also add a handler for this action, which will capture a photo, and emed the photo in a message that we will add to the chat room’s view model.\u003c/p\u003e","title":"RAD Chat Room – Part 5"},{"content":"\nThis is part 4 of the RAD Chatroom tutorial. You can find part 1 here, part 2 here and part 3 here.\nAdding More Actions So far we’ve implemented the basic requirements of a chat room. It can display messages, show particpants, and it allows users to send new messages. Now let’s go a step further and add some more actions. CodeRAD views like ChatRoomView allow for customization in a variety of ways, but the two primary methods are:\nActions\nView properties\nWe’ve already used one action to implement the \u0026ldquo;send\u0026rdquo; function. As a reminder, we defined the action in our controller, then we passed it as an attribute to the ViewNode when creating the view:\npublic static final ActionNode send = action( __**(1)** enabledCondition(entity-\u0026gt; { return !entity.isEmpty(ChatRoom.inputBuffer); }), icon(FontImage.MATERIAL_SEND) ); .... ViewNode viewNode = new ViewNode( actions(ChatRoomView.SEND_ACTION, send) __**(2)** ); .... ChatRoomView view = new ChatRoomView(createViewModel(), viewNode, f); __**(3)** __1 \u0026gt;Defining the \u0026ldquo;send\u0026rdquo; action. __2 Adding the \u0026ldquo;send\u0026rdquo; action to the view node, under the ChatRoomView.SEND_ACTION category. The category is a hint to the view about where and how the action should be incorporated into the View. __3 Creating new ChatRoomView, passing our ViewNode as a parameter __ A ViewNode is a user interface descriptor that can be used to customize the behaviour of a View. It provides a declarative way to define complex user interfaces in a simple way. For the purpose of this tutorial, we will only use the node as a means to pass actions to the ChatRoomView. The \u0026ldquo;Send\u0026rdquo; action was added to the ChatRoomView.SEND_ACTION category, but the ChatRoomView also supports some other categories:\nChatBubbleView.CHAT_BUBBLE_CLICKED – An action that will be \u0026ldquo;fired\u0026rdquo; when the user clicks a chat bubble.\nChatBubbleView.CHAT_BUBBLE_LONG_PRESS – An action that will be \u0026ldquo;fired\u0026rdquo; when the user long presses a chat bubble.\nChatBubbleView.CHAT_BUBBLE_CLICKED_MENU – Actions that will be displayed in a popup-menu when the user clicks on a chat bubble. This category many include more than one action, and all of supplied actions will be included as menu items in the menu.\nChatBubbleView.CHAT_BUBBLE_CLICKED_MENU – Actions that will be displayed in a popup-menu when the user long presses on a chat bubble.\nChatBubbleView.CHAT_BUBBLE_LONG_PRESS_MENU – Actions that will be displayed in a popup-menu when the chat bubble is long pressed.\nChatBubbleView.CHAT_BUBBLE_BADGES – Actions in this category will be rendered as \u0026ldquo;badge\u0026rdquo; icons next to the chat bubble. This is useful, for example, for displaying a \u0026ldquo;Like/Heart\u0026rdquo; badge on a chat bubble.\nProfileAvatarView.PROFILE_AVATAR_CLICKED – An action that will be \u0026ldquo;fired\u0026rdquo; when the user clicks on one of the profile avatars next to a chat bubble, or in the title component.\nProfileAvatarView.PROFILE_AVATAR_LONG_PRESS – An action that will be \u0026ldquo;fired\u0026rdquo; when the user long presses on one of the profile avatars.\nProfileAvatarView.PROFILE_AVATAR_CLICKED_MENU – Actions in this category will be rendered in a popup menu when the user clicks on an avatar.\nProfileAvatarView.PROFILE_AVATAR_LONG_PRESS_MENU – Actions in this category will be rendered in a popup menu when the user long presses on an avatar.\nChatRoomView.TEXT_ACTIONS – Actions in this category will be rendered as buttons next to the text input field. This is an appropriate place to add \u0026ldquo;Photo\u0026rdquo; or \u0026ldquo;Video\u0026rdquo; capture capabilities.\nAdding Phone and Video Conferencing To get our feet wet with actions, let’s add some options to initiate a phone-call or video conference with one of the participants. When the user taps on a profile’s avatar, we’ll present the user with a menu to start a call or video conference.\nIn the ChatFormController, we’ll add a couple of new actions.\npublic static final ActionNode phone = action( icon(FontImage.MATERIAL_PHONE) ); public static final ActionNode videoConference = action( icon(FontImage.MATERIAL_VIDEOCAM) ); ... ViewNode viewNode = new ViewNode( actions(ChatRoomView.SEND_ACTION, send), actions(ProfileAvatarView.PROFILE_AVATAR_CLICKED_MENU, phone, videoConference) __**(1)** ); __1 We add the phone and videoConference actions to the ViewNode in the ProfileAvatarView.PROFILE_AVATAR_CLICKED_MENU category so that they’ll be rendered in a popup-menu when the user presses on an avatar. Now run the app and click on the title component:\nFigure 1. Menu when clicking on the title component\nOr tap on an avatar next to one of the chat bubbles:\nFigure 2. Pop-up menu when tapping on an avatar\nCurrently, clicking on the \u0026ldquo;phone\u0026rdquo; or \u0026ldquo;camera\u0026rdquo; icon doesn’t do anything because we haven’t defined a handler. Let’s do that now:\naddActionListener(phone, evt-\u0026gt;{ evt.consume(); if (!CN.canDial()) { Dialog.show(\u0026quot;Not supported\u0026quot;, \u0026quot;Phone calls not supported on this device\u0026quot;, \u0026quot;OK\u0026quot;, null); return; } if (evt.getEntity().isEmpty(Person.telephone)) { Dialog.show(\u0026quot;No Phone\u0026quot;, \u0026quot;This user has no phone number\u0026quot;, \u0026quot;OK\u0026quot;, null); return; } String phoneNumber = evt.getEntity().getText(Person.telephone); CN.dial(phoneNumber); }); In this handler we first check to see if the platform supports phone calls, and fail with a dialog if it doesn’t. Then we check if the entity in question has a phone number. This code makes use of loose-coupling as we using the Person.telephone tag to check for a phone number rather than a particular property. This will allow this code to work with any entity that has such a property. We also make use of the handy Entity.isEmpty(Tag) method, which will return true if this entity doesn’t have a matching property, or if the entity has the property, but has an \u0026ldquo;empty\u0026rdquo; value for it.\nIf you try the app out and attempt to phone any of the users, you’ll receive this dialog:\nFigure 3. Currently our ChatAccount entity doesn’t include any properties with the Person.telephone tag, so attempting to phone a user will yield this error dialog\nLet’s remedy this situation by adding a property to the ChatAccount entity type.\npackage com.codename1.cn1chat; import com.codename1.rad.models.Entity; import com.codename1.rad.models.EntityType; import static com.codename1.rad.models.EntityType.tags; import com.codename1.rad.models.StringProperty; import com.codename1.rad.schemas.Person; import com.codename1.rad.schemas.Thing; /** * View model for an account profile. * @author shannah */ public class ChatAccount extends Entity { // The name property public static StringProperty name, thumbnailUrl, phone; private static final EntityType TYPE = new EntityType() {{ name = string(tags(Thing.name)); thumbnailUrl = string(tags(Thing.thumbnailUrl)); phone = string(tags(Person.telephone)); __**(1)** }}; { setEntityType(TYPE); } public ChatAccount(String nm, String thumb, String phoneNum) { set(name, nm); set(thumbnailUrl, thumb); set(phone, phoneNum); } } __1 Creating the phone property as a string property with the Person.telephone tag. And we’ll update the code in our ChatFormController that creates our participants to add a phone number.\nAdding a phone number to the George account in the view controller. We leave Kramer’s phone number null:\nroom.addParticipants( new ChatAccount(\u0026quot;George\u0026quot;, georgeThumb, \u0026quot;712-555-1234\u0026quot;), new ChatAccount(\u0026quot;Kramer\u0026quot;, kramerThumb, null) ); Let’s start up the app again. There are a few things to notice here:\nIf you press on either George or Kramer’s avatar next to one of their chat bubbles, and try to phone them, they’ll both give you the \u0026ldquo;This user has no phone number\u0026rdquo; message. Thats because the avatar that appears next to the chat bubble is actually the ChatMessage.ViewModel entity, and not our ChatAccount entity. The ChatMessage.ViewModel entity doesn’t include a telephone field. The ChatAccount entities are only used to render the title component of the form.\nIf you try to phone Kramer via the title component, you’ll get the same \u0026ldquo;This user has no phone number\u0026rdquo; message. This is correct, because we didn’t give Kramer a phone number.\nIf you try to phone George via the title component, it will dial the number that we registered with the George account. (If you’re running in the simulator, it won’t dial…​ it will just display a message in the console indicating that it is dialing the number).\nThis is progress, but why don’t we save the user the agony of having to click \u0026ldquo;phone\u0026rdquo; to find out if the app can actually make a phone call to that user. We have two options for this, we can either \u0026ldquo;disable\u0026rdquo; the phone action conditionally, like we did for the \u0026ldquo;send\u0026rdquo; action when the input field is empty. This will still show the phone button in the menu, but it will be greyed out and disabled. Alternatively we could actually remove the phone action in such cases so that it isn’t displayed at all for entities that don’t support it.\nLet’s try it both ways:\npublic static final ActionNode phone = action( icon(FontImage.MATERIAL_PHONE), enabledCondition(entity-\u0026gt;{ return CN.canDial() \u0026amp;\u0026amp; !entity.isEmpty(Person.telephone); }) ); Result:\nFigure 4. Kramer’s phone button is disabled because we didn’t provide a phone number for him\nIf we want to remove the action from menus where it isn’t supported, then we simply change enabledCondition() to condition().\nRemoving the phone action for entities that don’t have a phone number:\npublic static final ActionNode phone = action( icon(FontImage.MATERIAL_PHONE), condition(entity-\u0026gt;{ __**(1)** return CN.canDial() \u0026amp;\u0026amp; !entity.isEmpty(Person.telephone); }) ); __1 We use the condition(…​) attribute instead of enabledCondition(…​) to disable/hide the action And the result:\nFigure 5. Kramer has no \u0026ldquo;phone\u0026rdquo; option now because he doesn’t have a phone number\nAdding a \u0026ldquo;Like\u0026rdquo; Badge Most messaging apps provide a way to \u0026ldquo;like\u0026rdquo; a chat message. Let’s add this functionality to our app by using the ChatBubbleView.CHAT_BUBBLE_BADGES category to display the \u0026ldquo;liked\u0026rdquo; badge. We’ll use the ChatBubbleView.CHAT_BUBBLE_LONG_PRESS_MENU category to display the toggle button for the user to \u0026ldquo;like\u0026rdquo; and \u0026ldquo;unlike\u0026rdquo; the message.\npublic static final ActionNode likedBadge = UI.action( UI.uiid(\u0026quot;ChatBubbleLikedBadge\u0026quot;), __**(1)** icon(FontImage.MATERIAL_FAVORITE), condition(entity-\u0026gt;{ __**(2)** return !entity.isFalsey(ChatMessage.isFavorite); __**(3)** }) ); public static final ActionNode likeAction = UI.action( icon(FontImage.MATERIAL_FAVORITE_OUTLINE), uiid(\u0026quot;LikeButton\u0026quot;), __**(4)** selected(icon(FontImage.MATERIAL_FAVORITE)), __**(5)** selectedCondition(entity-\u0026gt;{ return !entity.isFalsey(ChatMessage.isFavorite); __**(6)** }) ); ... ViewNode viewNode = new ViewNode( actions(ChatRoomView.SEND_ACTION, send), actions(ProfileAvatarView.PROFILE_AVATAR_CLICKED_MENU, phone, videoConference), actions(ChatBubbleView.CHAT_BUBBLE_LONG_PRESS_MENU, likeAction), __**(7)** actions(ChatBubbleView.CHAT_BUBBLE_BADGES, likedBadge) __**(8)** ); __1 We set the UIID of the badge to \u0026ldquo;ChatBubbleLikedBadge\u0026rdquo; which is a style defined in the RADChatRoom cn1lib’s stylesheet. It will make the badge small and red. __2 Use the condition() attribute to ensure that the \u0026ldquo;liked\u0026rdquo; badge only shows up if the message has been liked. __3 We are using the convenience method Entity.isFalsey(Tag) to determine if the chat message has been liked. This returns \u0026ldquo;true\u0026rdquo; if the value of this field is anything \u0026ldquo;falsey\u0026rdquo;, like null, or \u0026ldquo;\u0026rdquo;, or 0, or false. This allows for flexibility about how the view model wants to store whether the message is a favourite or not. __4 We define a UIID for the \u0026ldquo;Like\u0026rdquo; action so that we can make the button look how we like. __5 We use the selected(…​) attribute on the likeAction to define a different icon for the action when the action is \u0026ldquo;selected\u0026rdquo;. __6 We use selectedCondition() on the like action to cause the action to be selected conditionally on whether the message is \u0026ldquo;liked\u0026rdquo;. This works similar to the condition() and enabledCondition() attributes, except this will affect the selected state of the action’s button. The presence of this attribute causes the button to be rendered as a toggle button instead of a regular button. __7 We add the like action to the CHAT_BUBBLE_LONG_PRESS_MENU category. __8 We add the liked action to the CHAT_BUBBLE_BADGES category. And, of course, we need to handle the \u0026ldquo;like\u0026rdquo; action to toggle the property on and off in the view model.\naddActionListener(likeAction, evt-\u0026gt;{ evt.consume(); __**(1)** Entity chatMessage = evt.getEntity(); chatMessage.setBoolean( __**(2)** ChatMessage.isFavorite, __**(3)** chatMessage.isFalsey(ChatMessage.isFavorite) __**(4)** ); }); __1 We consume the event so that the view knows that we handled it. This prevents any default behaviour from conflicting. __2 We use the Entity.setBoolean(…​) method to signify that we are setting the value as a boolean. This will ensure that the value is converted to the correct type for the underlying property. __3 We use the ChatMessage.isFavorite tag to target the field for loose coupling. The ChatBubbleView.ViewModel class that we’re using does implement a property with this tag, but we are writing code in such a way that we don’t need to care about which property it is. __4 Again using isFalsey() to get the current value of the flag, and we toggle it to be opposite. Finally, our \u0026ldquo;Like\u0026rdquo; button will be a heart icon. When selected it will be a filled heart icon. When unselected, it will be contour of a heart. We specified a UIID of \u0026ldquo;LikeButton\u0026rdquo; for this action in its definition. We just need to add this style to our stylesheet. Open the project’s stylesheet (at css/theme.css) and add the following:\nLikeButton { background-color:transparent; cn1-border-type: none; color: red; } And the test drive…​ Open up the app again, long press on a chat message, and click the \u0026ldquo;Like\u0026rdquo; action. Then it should display a red heart badge next to the chat bubble.\nFigure 6. Menu appears when you long-press on a chat bubble. Clicking on the button will fire the \u0026ldquo;Like\u0026rdquo; action\nFigure 7. After we \u0026ldquo;like\u0026rdquo; George’s message, it displays the \u0026ldquo;liked\u0026rdquo; badge\nNext Week For our final part we’ll cover adding a photo capture feature.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/rad-chatroom-part-4/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/rad-chatroom-part-4/chat-ui-kit-feature.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is part 4 of the RAD Chatroom tutorial. You can find part 1 \u003ca href=\"/blog/rad-chatroom-part-1.html\"\u003ehere\u003c/a\u003e, part 2 \u003ca href=\"/blog/rad-chatroom-part-2.html\"\u003ehere\u003c/a\u003e and part 3 \u003ca href=\"/blog/rad-chatroom-part-3.html\"\u003ehere\u003c/a\u003e.\u003c/p\u003e\n\u003ch3 id=\"adding-more-actions\"\u003eAdding More Actions\u003c/h3\u003e\n\u003cp\u003eSo far we’ve implemented the basic requirements of a chat room. It can display messages, show particpants, and it allows users to send new messages. Now let’s go a step further and add some more actions. CodeRAD views like ChatRoomView allow for customization in a variety of ways, but the two primary methods are:\u003c/p\u003e","title":"RAD Chat Room – Part 4"},{"content":"\nThis is part 3 of the RAD Chatroom tutorial. You can find part 1 here and part 2 here.\nAdding Text Messages from Other Users Our current example only includes messages that the current user posted themself. I.e. We only have chat bubbles on the right-hand side of the view. Let’s add some more sample data to our view model to give us a feel for how a real chat will look. In the ChatFormController class, we’ll change the createViewModel() method as follows:\nCreating more interesting sample data for the ChatRoom’s view model. We add messages from both the current user and other users.\n// Create a view model for the chat room private Entity createViewModel() { ChatRoomView.ViewModel room = new ChatRoomView.ViewModel(); // Make up some dummy times for the chat messages. long SECOND = 1000l; long MINUTE = SECOND * 60; long HOUR = MINUTE * 60; long DAY = HOUR * 24; // Make first message 2 days ago. long t = System.currentTimeMillis() - 2 * DAY; // Some thumbnails for the avatars of the participants String georgeThumb = \u0026quot;https://weblite.ca/cn1tests/radchat/george.jpg\u0026quot;; String kramerThumb = \u0026quot;https://weblite.ca/cn1tests/radchat/kramer.jpg\u0026quot;; room.addMessages(createDemoMessage(\u0026quot;Why couldn't you have made me an architect? You know I always wanted to pretend that I was an architect. \u0026quot; + \u0026quot;Well I'm supposed to see her tomorrow, I'm gonna tell her what's goin on. Maybe she likes me for me.\u0026quot;, new Date(t), \u0026quot;George\u0026quot;, georgeThumb)); t += HOUR; room.addMessages(createDemoMessage(\u0026quot;Hey\u0026quot;, new Date(t), \u0026quot;Kramer\u0026quot;, kramerThumb)); t += MINUTE; room.addMessages(createDemoMessage(\u0026quot;Hey\u0026quot;, new Date(t), null, null)); return room; } // Create a single demo message private Entity createDemoMessage(String text, Date datePosted, String participant, String iconUrl) { ChatBubbleView.ViewModel msg = new ChatBubbleView.ViewModel(); msg.messageText(text) .date(datePosted) .iconUrl(iconUrl) .isOwn(participant == null); if (participant != null) { msg.postedBy(participant); } return msg; } To make things easier to read, I’ve broken out the code for creating a message into a separate method so we can call create new messages more easily. I’ve created a couple of pretend users, \u0026ldquo;George\u0026rdquo; and \u0026ldquo;Kramer\u0026rdquo;, and I’ve provided some thumbnail URLs for them, which can be used as avatars in the chat room.\nAnd the result:\nFigure 1. Chat room now includes messages from two other users, George and Kramer\nNotice that it shows the time of the first chat message, but not the others. This is intentional. The chat room will only show the time of messages if there is a long delay between it and the previous message. You can see the time of each message by swiping to the left:\nFigure 2. Swipe to the left to reveal the date and time of each message\nAdding the \u0026ldquo;Participants\u0026rdquo; Title Component\nRecall the screenshot of the finished app, in which the form title included a list of participants in the chat room with their avatars.\nFigure 3. Participants title component with avatars\nLet’s add this now by adding some participants to the view model. The ChatRoomView.ViewModel includes methods to directly add participants to the model via addParticpant(Entity…​ participants). Each participant entity should implement the Thing.name or Thing.thumbnailUrl tags, or both. If Only Thing.name is provided, then it will generate an avatar with the first letter of their name. If Thing.thumbnailUrl is provided, then it will use the image at this url as the avatar.\nLet’s begin by creating a custom entity/view model named \u0026ldquo;ChatAccount\u0026rdquo; which will be used as participants in the chat. Create a new Java class named \u0026ldquo;ChatAccount\u0026rdquo; with the following contents:\nThe ChatAccount entity will be used to encapsulate profiles for participants in the chat room.\npackage com.codename1.cn1chat; import com.codename1.rad.models.Entity; import com.codename1.rad.models.EntityType; import static com.codename1.rad.models.EntityType.tags; import com.codename1.rad.models.StringProperty; import com.codename1.rad.schemas.Thing; /** * View model for an account profile. * @author shannah */ public class ChatAccount extends Entity { // The name property public static StringProperty name; __**(1)** private static final EntityType TYPE = new EntityType() {{ __**(2)** name = string(tags(Thing.name)); __**(3)** }}; { setEntityType(TYPE); __**(4)** } public ChatAccount(String nm) { set(name, nm); } } __1 The \u0026ldquo;name\u0026rdquo; property of our entity. __2 Define an entity type for the ChatAccount entity. The entity type defines which properties are supported by the ChatAccount entity. __3 Generating the \u0026ldquo;name\u0026rdquo; property as a string property. Notice that we assign the Thing.name tag to this property, which will allow views to bind to it. __4 Set the entity type inside the \u0026ldquo;instance\u0026rdquo; initializer so that all ChatAccount objects have the same entity type. This could have been placed inside the constructor, but placing it simply inside the initializer (i.e. inside {..}) makes for a little less typing, and also helps to signify the declarative nature of this call. I’ve added some notes about the key lines of the code listing above which should help to get you up to speed if this is your first custom entity. This entity defines a single property, \u0026ldquo;name\u0026rdquo;. If we were to define this entity as a POJO (Plain-Old Java object), the class might look something like:\nWhat the ChatAccount entity would look like if implemented as a POJO (Plain old java object).\npublic class ChatAccount { private String name; public ChatAccount(String name) { this.name = name; } } So why not use a POJO for our entity?\nThe Entity class, together with EntityType provide lots of useful features such as bindable properties, property change events, data conversion, observability, and reflection. All of these features are necessary to enable the creation of loosely coupled components with clean separation between models, views, and controllers. As you’ll see, this loose coupling greatly enhances our ability to produce complex, reusable components, which results in better apps with less code.\nGetting and Setting Properties on Entities\nBefore proceeding, its worth discussing the basics of how to use entities. The Entity class allows us to get and set properties without needing to define getter and setter methods. It also includes a rich set of convenience methods for handling data-conversion. Finally, one of the most powerful features of entities is its loose coupling. It is possible to get and set property values without any knowledge of which properties exist in the entity, via tags.\nFirst things first: Getting and setting property values.\nGetting and setting property values using a direct property reference.\nChatAccount account = new ChatAccount(\u0026quot;George\u0026quot;); String name = account.get(ChatAccount.name); // \u0026quot;George\u0026quot; account.set(ChatAccount.name, \u0026quot;Kramer\u0026quot;); name = account.get(ChatAccount.name); // \u0026quot;Kramer\u0026quot; This code is tightly coupled to the ChatAccount entity because it directly references the ChatAccount.name property. In some cases, this tight coupling is fine. In other cases, such as when you want to develop a reusable component that requires a \u0026ldquo;name\u0026rdquo; property, you may prefer to use \u0026ldquo;loose\u0026rdquo; coupling, as follows:\nEntity account = ...; // Could be any entity, but happens to be a ChatAccount account.setText(Thing.name, \u0026quot;George\u0026quot;); String name = account.getText(Thing.name); // \u0026quot;George\u0026quot; __ The CodeRAD library includes a hierarchy of schemas which define tags that may be used to tag entity properties. These schemas were adapted from https://schema.org, which defines entities and properties for a large number of common object types. All schemas extend the base schema, Thing. Some common tags include name, identifier, and thumbnailUrl. When creating reusable components, you can use these schema \u0026ldquo;tags\u0026rdquo; to access property values of view models in loosely coupled way. The javadocs for View components should list the tags that it expects on its view models, so you can tag the properties on your entities accordingly. For a full list of schemas, check out https://schema.org/docs/full.html. Only a subset has been ported into the CodeRAD library. More will be added over time, and you may contribute your own with a pull request. Finally…​ Adding the Participants After a lengthy discussion of Entities, Entity types, Tags, and Properties, we can now go ahead and add some participants to the chat room. Add the following inside our createViewModel() method of the ChatFormController class:\nroom.addParticipants(new ChatAccount(\u0026quot;George\u0026quot;), new ChatAccount(\u0026quot;Kramer\u0026quot;)); This adds two profiles to the chat room as participants. Now, if we launch the app we’ll see the form title replaced with the following avatars.\nFigure 4. Title component with avatars generated from our participants\nNow, let’s go a step further and add a \u0026ldquo;thumbnail url\u0026rdquo; property to our ChatAccount entity.\nAdding a thumbnailUrl property to the ChatAccount entity:\npackage com.codename1.cn1chat; import com.codename1.rad.models.Entity; import com.codename1.rad.models.EntityType; import static com.codename1.rad.models.EntityType.tags; import com.codename1.rad.models.StringProperty; import com.codename1.rad.schemas.Thing; /** * View model for an account profile. * @author shannah */ public class ChatAccount extends Entity { // The name property public static StringProperty name, thumbnailUrl; private static final EntityType TYPE = new EntityType() {{ name = string(tags(Thing.name)); thumbnailUrl = string(tags(Thing.thumbnailUrl)); }}; { setEntityType(TYPE); } public ChatAccount(String nm, String thumb) { set(name, nm); set(thumbnailUrl, thumb); } } And modify our ChatFormController to set the thumbnail URL on our entity.\nroom.addParticipants( new ChatAccount(\u0026quot;George\u0026quot;, georgeThumb), new ChatAccount(\u0026quot;Kramer\u0026quot;, kramerThumb) ); And reload…​\nFigure 5. Title component after setting thumbnail URLs for our participants\nNext Week In part four we’ll discuss adding more actions.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/rad-chatroom-part-3/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/rad-chatroom-part-3/chat-ui-kit-feature.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is part 3 of the RAD Chatroom tutorial. You can find part 1 \u003ca href=\"/blog/rad-chatroom-part-1.html\"\u003ehere\u003c/a\u003e and part 2 \u003ca href=\"/blog/rad-chatroom-part-2.html\"\u003ehere\u003c/a\u003e.\u003c/p\u003e\n\u003ch3 id=\"adding-text-messages-from-other-users\"\u003eAdding Text Messages from Other Users\u003c/h3\u003e\n\u003cp\u003eOur current example only includes messages that the current user posted themself. I.e. We only have chat bubbles on the right-hand side of the view. Let’s add some more sample data to our view model to give us a feel for how a real chat will look. In the \u003ccode\u003eChatFormController\u003c/code\u003e class, we’ll change the \u003ccode\u003ecreateViewModel()\u003c/code\u003e method as follows:\u003c/p\u003e","title":"RAD Chat Room – Part 3"},{"content":"\nThis is part 2 of the RAD Chatroom tutorial. You can find part 1 here.\nAdding a \u0026ldquo;Send\u0026rdquo; Button A \u0026ldquo;Send\u0026rdquo; button is a pretty important part of any chat application. We’ll add a send button to our app by defining an action in our controller, and passing it to the ChatRoomView as follows. First we’ll define the action in our ChatFormController class:\n// We're going to use a lot of static functions from the UI class for creating // UI elements like actions declaratively, so we'll do a static import here. import static com.codename1.rad.ui.UI.*; // ... public class ChatFormController extends FormController { // Define the \u0026quot;SEND\u0026quot; action for the chat room public static final ActionNode send = action(icon(FontImage.MATERIAL_SEND)); Then we’ll create a ViewNode to pass to the ChatRoomView constructor. This is can contain properties that the chat room uses to render itself, including which actions it should \u0026ldquo;embed\u0026rdquo; and where.\nViewNode viewNode = new ViewNode( actions(ChatRoomView.SEND_ACTION, send) ); ChatRoomView view = new ChatRoomView(createViewModel(), viewNode, f); If this is the first time you’ve seen a ViewNode definition, this may look a little bit foreign. All this does is register our \u0026ldquo;send\u0026rdquo; action with the \u0026ldquo;ChatRoomView.SEND_ACTION\u0026rdquo; category so that the chat room view knows to use it as the \u0026ldquo;send\u0026rdquo; action in the chat room. The full source of the ChatRoomController class after these changes is as follows:\npackage com.codename1.cn1chat; import com.codename1.rad.controllers.Controller; import com.codename1.rad.controllers.FormController; import com.codename1.rad.models.Entity; import com.codename1.rad.nodes.ActionNode; import com.codename1.rad.nodes.ViewNode; import com.codename1.rad.ui.chatroom.ChatBubbleView; import com.codename1.rad.ui.chatroom.ChatRoomView; import static com.codename1.ui.CN.CENTER; import com.codename1.ui.FontImage; import com.codename1.ui.Form; import com.codename1.ui.layouts.BorderLayout; // We're going to use a lot of static functions from the UI class for creating // UI elements like actions declaratively, so we'll do a static import here. import static com.codename1.rad.ui.UI.*; public class ChatFormController extends FormController { // Define the \u0026quot;SEND\u0026quot; action for the chat room public static final ActionNode send = action(icon(FontImage.MATERIAL_SEND)); public ChatFormController(Controller parent) { super(parent); Form f = new Form(\u0026quot;My First Chat Room\u0026quot;, new BorderLayout()); // Create a \u0026quot;view node\u0026quot; as a UI descriptor for the chat room. // This allows us to customize and extend the chat room. ViewNode viewNode = new ViewNode( actions(ChatRoomView.SEND_ACTION, send) ); // Add the viewNode as the 2nd parameter ChatRoomView view = new ChatRoomView(createViewModel(), viewNode, f); f.add(CENTER, view); setView(f); } /** * Creates a view model for the chat room. * @return */ private Entity createViewModel() { ChatRoomView.ViewModel room = new ChatRoomView.ViewModel(); ChatBubbleView.ViewModel message = new ChatBubbleView.ViewModel(); message.messageText(\u0026quot;Hello World\u0026quot;); room.addMessages(message); return room; } } Now, let’s run the app in the simulator again.\nNotice that a \u0026ldquo;send\u0026rdquo; button has been added to the bototm-right of the form, next to the text entry box.\nThis is progress, but you may be disappointed, upon playing with the send button, to discover that it doesn’t do anything. In fact, when you click the \u0026ldquo;send\u0026rdquo; button, the view is sending an event to our controller. We just haven’t implemented a handler for it.\nLet’s do that now.\nHandling the \u0026ldquo;Send\u0026rdquo; Action Event To handle the \u0026ldquo;send\u0026rdquo; event, we simply add the following inside the constructor of our form controller:\naddActionListener(send, evt-\u0026gt;{ evt.consume(); ChatRoomView.ViewModel room = (ChatRoomView.ViewModel)evt.getEntity(); String textFieldContents = room.getInputBuffer(); if (textFieldContents != null \u0026amp;\u0026amp; !textFieldContents.isEmpty()) { ChatBubbleView.ViewModel message = new ChatBubbleView.ViewModel(); message.messageText(textFieldContents); message.date(new Date()); message.isOwn(true); // Indicates that this is sent by \u0026quot;this\u0026quot; user // so bubble is on right side of room view. // Now add the message room.addMessages(message); // Clear the text field contents room.inputBuffer(\u0026quot;\u0026quot;); } }); This listener will be called whenever the \u0026ldquo;send\u0026rdquo; action is fired. On mobile devices this will only occur when the user presses the \u0026ldquo;Send\u0026rdquo; button. But on desktop, it will also be fired when the user hits \u0026ldquo;Enter\u0026rdquo; while the text field is focused.\nThe event passed to this handler is an instance of ActionEventNode which includes all of the contextual information necessary to identify the source of the action, including the entity (the room), the UI component (the ChatRoomView) object, and the action (send), that triggered the event.\nThe logic in this handler should be pretty straight forward. It checks if the \u0026ldquo;input buffer\u0026rdquo; contains any text. Since the input buffer is bound to the text field, this is just checks if the text field contains any text. It then creates a new message with the input buffer contents, and clears the contents of the input buffer.\nAll of these property changes will fire PropertyChangeEvents to the view so that the view state will be updated automatically and instantly.\nIf you run the app in the simulator again, you should be able to enter text into the text field, and press send, to see a new chat bubble animated into place.\nBonus Points: Disable Send Button When Input Empty In out action handler, we include logic to prevent sending empty messages. But it would be nice if we game the user a cue in the user interface that \u0026ldquo;send\u0026rdquo; doesn’t work when the field is empty. We can do this using the enabledCondition attribute in our action definition:\npublic static final ActionNode send = action( enabledCondition(entity-\u0026gt; { return !entity.isEmpty(ChatRoom.inputBuffer); }), icon(FontImage.MATERIAL_SEND) ); This says that the send action should only be enabled when the \u0026ldquo;entity\u0026rdquo; is non-empty. The \u0026ldquo;entity\u0026rdquo; in this case is the view model for the chat room.\nStart the app again in the simulator and notice that the \u0026ldquo;send\u0026rdquo; button toggles between enabled and disabled depending on whether there is text in the input field.\nFigure 1. Send button is disabled because the input field is empty\nFigure 2. Send button is enabled because the input field has text\nNext Week Next week we’ll proceed with adding text messages from other users.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/rad-chatroom-part-2/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/rad-chatroom-part-2/chat-ui-kit-feature.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is part 2 of the RAD Chatroom tutorial. You can find part 1 \u003ca href=\"/blog/rad-chatroom-part-1.html\"\u003ehere\u003c/a\u003e.\u003c/p\u003e\n\u003ch3 id=\"adding-a-send-button\"\u003eAdding a \u0026ldquo;Send\u0026rdquo; Button\u003c/h3\u003e\n\u003cp\u003eA \u0026ldquo;Send\u0026rdquo; button is a pretty important part of any chat application. We’ll add a send button to our app by defining an action in our controller, and passing it to the ChatRoomView as follows. First we’ll define the action in our ChatFormController class:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e// We're going to use a lot of static functions from the UI class for creating\n// UI elements like actions declaratively, so we'll do a static import here.\nimport static com.codename1.rad.ui.UI.*;\n\n// ...\npublic class ChatFormController extends FormController {\n\n    // Define the \u0026quot;SEND\u0026quot; action for the chat room\n    public static final ActionNode send = action(icon(FontImage.MATERIAL_SEND));\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThen we’ll create a ViewNode to pass to the ChatRoomView constructor. This is can contain properties that the chat room uses to render itself, including which actions it should \u0026ldquo;embed\u0026rdquo; and where.\u003c/p\u003e","title":"RAD Chat Room – Part 2"},{"content":"\nThis tutorial describes how to use the RADChatRoom library to quickly and easily add a nice-looking, fully functional chat room to your Codename One application. This is part 1 of a multi-part series of posts over the next few weeks.\nThe finished product will look like the following:\nYou can download the full source of this tutorial’s project here.\nYou can also try it out yourself here.\n__ The demo link uses the CodeName One Javascript port, which allows you to deploy Codename One java applications as native Javascript apps inside the browser without any plugins or extensions. When you build a Codename One project for iOS, Android, Desktop, or any of the other build targets, they will be compiled as native apps, with native performance, and will not use Javascript. You may also try out an Android build of this project. For other platforms, you can download the sources and build it yourself.\nAbout the ChatRoomView Component The ChatRoomView component is the first in a new breed of Codename One UI components which go beyond the the fundamental building blocks of user interfaces to provide a rich, fully-functional user experience out of the box. It is built on top of the new CodeRAD library which enables a new level of code-reuse based on the tried-and-true MVC (Model-View-Controller) design pattern. As you’ll see, adding a chat feature to your app is not difficult. All of the minutiae of UI details come working and ready to go. You just need to bind it to your view model and controller.\nPrerequisites In order to create the project in this tutorial, you only need one thing:\nIntelliJ, NetBeans, or Eclipse with the Codename One plugin installed. Project Setup For this tutorial, we’ll create a basic Codename One project, and we’ll add the \u0026ldquo;CodeRAD\u0026rdquo; and \u0026ldquo;RADChatRoom\u0026rdquo; cn1libs as dependencies. I’ll use NetBeans in this tutorial, but you can use your preferred IDE (IntelliJ or Eclipse).\nFor the sake of this tutorial, I’m going to name the project CN1Chat, and my package will be \u0026ldquo;com.codename1.cn1chat\u0026rdquo;. I’ll be using the \u0026ldquo;Hello World\u0026rdquo; bare-bones project template.\nFigure 1. New project dialog in NetBeans\nFigure 2. Page 2 of new project wizard in NetBeans\nStep 1: Create a New Codename One project If you haven’t created a Codename One project before, you can refer to this tutorial, which walks you through the creation of your first Codename One project.\nStep 2: Activate CSS The CodeRAD and RADChatRoom libs require CSS to be activated in your project. See this tutorial for the steps on enabling CSS.\nStep 3: Add Dependencies In Codename One settings, add the following cn1libs:\nCodeRAD\nRADChatRoom\nIf you haven’t activated any cn1libs before in your Codename One projects, see this tutorial which explains the process.\nStep 4: Create Application Controller We’ll be using MVC for this app. The CodeRAD cn1lib includes a set of controller classes that help with the structure of such apps. We’ll begin by modifying our app’s main application class (CN1Chat.java) so that it extends ApplicationController, and we’ll replace the class contents with the following:\npackage com.codename1.cn1chat; import com.codename1.rad.controllers.ApplicationController; import com.codename1.rad.controllers.ControllerEvent; public class CN1Chat extends ApplicationController { @Override public void actionPerformed(ControllerEvent evt) { if (evt instanceof StartEvent) { evt.consume(); // The app has started } } } Step 5: Create A Form Controller Next we’ll create a controller for the form that will contain the chat. This will create a basic view model, and use it to create a ChatRoomView object, which we will add to the form. The code for the first iteration of this controller is as follows:\npackage com.codename1.cn1chat; // imports public class ChatFormController extends FormController { public ChatFormController(Controller parent) { super(parent); Form f = new Form(\u0026quot;My First Chat Room\u0026quot;, new BorderLayout()); ChatRoomView view = new ChatRoomView(createViewModel(), f); f.add(CENTER, view); setView(f); } /** * Creates a view model for the chat room. * @return */ private Entity createViewModel() { ChatRoomView.ViewModel room = new ChatRoomView.ViewModel(); ChatBubbleView.ViewModel message = new ChatBubbleView.ViewModel(); message.messageText(\u0026quot;Hello World\u0026quot;); room.addMessages(message); return room; } } A couple of things to note with this code:\nThe createViewModel() method creates a minimal view model for our chat room. It uses the ChatRoomView.ViewModel class for the view model. This class is only a reference implementation of a view model, and the ChatRoomView class doesn’t require you to use this class at all if you don’t want to. Later on, in this tutorial, I’ll show you how to use your own custom class for the view model.\nSimilarly, the ChatBubbleView.ViewModel is a reference implementation of a view model to encapsulate a message in the chat room, but you can use your own custom classes for these models also.\nStep 6: Show the Form Finally, we need to show the Chat form when the app launches. Modify your Application controller class to create a new instance of ChatFormController() and show its form as follows:\npublic class CN1Chat extends ApplicationController { @Override public void actionPerformed(ControllerEvent evt) { if (evt instanceof StartEvent) { evt.consume(); new ChatFormController(this).getView().show(); } } } Step 7: Run the App Now that we have the minimal foundation in place, let’s run the app in the simulator. If everything goes well, you should see something like the following.\nFigure 3. First run of Chat app in simulator\nThis looks good, but it’s not a fully functional chat app yet. You’ll notice that it is missing many of the features that are present in the screenshot I shared of the finished project. The finished project included a title component with avatars of the chat participants:\nFigure 4. Chat participants listed in title bar in finished version of the app\nThis is absent because we didn’t add any participants to the chat model.\nIn addition, there is no \u0026ldquo;Send\u0026rdquo; button, in this version, so there is no apparent way to send messages in this chat.\nWe’ll correct both of these omissions, and add some other features over the course of this tutorial.\nNext Week Next week we’ll continue by adding a send button and building from there.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/rad-chatroom-part-1/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/rad-chatroom-part-1/chat-ui-kit-feature.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis tutorial describes how to use the \u003ca href=\"https://github.com/shannah/RADChatRoom\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRADChatRoom\u003c/a\u003e library to quickly and easily add a nice-looking, fully functional chat room to your Codename One application. This is part 1 of a multi-part series of posts over the next few weeks.\u003c/p\u003e\n\u003cp\u003eThe finished product will look like the following:\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"rad chat room 1\" loading=\"lazy\" src=\"/blog/rad-chatroom-part-1/rad-chat-room-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eYou can download the full source of this tutorial’s project \u003ca href=\"https://github.com/shannah/RADChatRoom/CN1Chat\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eYou can also try it out yourself \u003ca href=\"https://shannah.github.io/RADChatRoom/demo\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere\u003c/a\u003e.\u003c/p\u003e","title":"RAD Chat Room – Part 1"},{"content":"\nI wrote before about EasyThread which makes it much easier to write multi-threaded code in Codename One. One problem in that scenario was the inability to define a generic exception handler for that scenario.\nWith the current version of Codename One we now have a new generic error handling API for easy threads:\npublic void addErrorListener(ErrorListener err); public static void addGlobalErrorListener(ErrorListener err); These methods add a callback for error events, either globally or for a specific thread. Notice that these methods aren’t thread safe and should be invoked synchronously. So make sure to invoke them only from one thread e.g. the EDT.\nThese methods must never be invoked from within the resulting callback code!\nSo you can’t do this:\nt.addErrorListener((t, c, e) -\u0026gt; { // do stuff ... // this is illegal: t.removeErrorListener(listener); }); The error listener interface looks like this:\npublic static interface ErrorListener\u0026lt;T\u0026gt; { /** * Invoked when an exception is thrown on an easy thread. Notice * this callback occurs within the thread and not on the EDT. This * method blocks the current easy thread until it completes. * @param t the thread * @param callback the callback that triggered the exception * @param error the exception that occurred */ void onError(EasyThread t, T callback, Throwable error); } This should provide you with all the details you need to handle an error in a generic way. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJavier Anton — April 14, 2020 at 9:42 am (permalink) Javier Anton says:\nGreat stuff. Is this wrapping an exception handler around the execution code or is it wrapping a threading exception around the EasyThread?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/thread-errors/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/thread-errors/error-detected.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI wrote before about \u003ca href=\"/blog/easy-thread/\"\u003eEasyThread\u003c/a\u003e which makes it much easier to write multi-threaded code in Codename One. One problem in that scenario was the inability to define a generic exception handler for that scenario.\u003c/p\u003e\n\u003cp\u003eWith the current version of Codename One we now have a new generic error handling API for easy threads:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003epublic void addErrorListener(ErrorListener err);\npublic static void addGlobalErrorListener(ErrorListener err);\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThese methods add a callback for error events, either globally or for a specific thread. Notice that these methods aren’t thread safe and should be invoked synchronously. So make sure to invoke them only from one thread e.g. the EDT.\u003c/p\u003e","title":"Thread Errors"},{"content":"\nWe hope you’re all keeping safe!\nWe announced a couple of weeks ago that we’re moving our build servers to use xcode 11.3 by default. As a recap, Apple requires a new version of xcode/iOS SDK for apps submitted to the appstore. As a result we had to update the version of xcode on our build servers.\nThis has been in the cloud servers for a while and is now the default when sending new builds. For most of you this should be seamless…​\nEverything should \u0026ldquo;just work\u0026rdquo;. But for some edge cases things might fail or behave differently. This is especially true if you rely on native libraries but also if you rely on some functionality that we missed in our testing.\nIf you run into such a problem first verify it by testing against xcode 10.1 using the build hint: ios.xcode_version=10.1.\n__ We suggest removing this build hint once your done so you can use the default target recommended by us Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/xcode-11-migration-now-default/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/xcode-11-migration-now-default/xcode-migration.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe hope you’re all keeping safe!\u003cbr\u003e\nWe announced a couple of weeks ago that we’re moving our build servers to use xcode 11.3 by default. As a recap, Apple requires a new version of xcode/iOS SDK for apps submitted to the appstore. As a result we had to update the version of xcode on our build servers.\u003c/p\u003e\n\u003cp\u003eThis has been in the cloud servers for a while and is now the default when sending new builds. For most of you this should be seamless…​\u003c/p\u003e","title":"Xcode 11 is now the Default"},{"content":"\nApple keeps moving the goal posts of xcode requirements for developers. This is good as it keeps the technology fresh but it means support for older devices becomes untenable. Unfortunately there isn’t much we can do and we need to move with the times as Apple will no longer accept apps built with older versions of xcode.\nThe main problem with this is another pain point for iOS developers. Newer versions of code require newer versions of Mac OS. That means we need to update the version of Mac OS on all of our servers. That’s a HUGE pain not just because of the drudge of upgrading every server…​\nIt’s a pain because Catalina (the new Mac OS) isn’t compatible with xcode 9.2. As a result we killed support for xcode 9.2 and if you explicitly request it in your build hints your build will fail starting today. Next week we’ll upgrade the OS’s and install the new version of xcode. At that point you should be able to send a build with xcode set to 11.3 as an option. To do that you can use the build hint: ios.xcode_version=11.3 or ios.xcode_version=10.1. By April we hope to make 11.3 the default value.\n__ We suggest removing this build hint once your done so you can use the default target recommended by us Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJavier Anton — March 8, 2020 at 9:03 pm (permalink) Javier Anton says:\nThanks for all your hard work guys, much appreciated\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/xcode-11-migration/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/xcode-11-migration/xcode-migration.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eApple keeps moving the goal posts of xcode requirements for developers. This is good as it keeps the technology fresh but it means support for older devices becomes untenable. Unfortunately there isn’t much we can do and we need to move with the times as Apple will no longer accept apps built with older versions of xcode.\u003c/p\u003e\n\u003cp\u003eThe main problem with this is another pain point for iOS developers. Newer versions of code require newer versions of Mac OS. That means we need to update the version of Mac OS on all of our servers. That’s a HUGE pain not just because of the drudge of upgrading every server…​\u003c/p\u003e","title":"Xcode 11 Migration"},{"content":"\nNot so long ago, we released a Sheet component that acts like a non-modal dialog box that slides up from the bottom. It occupies only the amount of space required to house its contents, and it provides built-in navigation controls to go \u0026ldquo;back\u0026rdquo; to the previous sheet. By default Sheets are displayed along the bottom of the screen, but we have recently added an update that allows you to position it along the north, east, west, south, or center of the screen, as shown below:\nIn addition we have added the ability to use a different position for tablets and desktop, than for phones. On desktop, it is more common for dialogs to pop up in the center of the screen, whereas on mobile, it is quite common to have a dialog (or sheet) pop up from the bottom.\nWhen positioning a sheet on the east or west, it is quite easy to create your own ad-hoc hamburger menu. This may be easier, in some cases, than using the ToolBar class, as it gives you more control over the result.\nFor a full working example, see the updated Sheet sample here.\nBelow is a 35 second screen cast of that demo: Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — February 29, 2020 at 11:27 am (permalink) Thank you, this is exactly what I need! 🙂\nAbout the Sheet in the bottom position, can it be placed at a given distance from the bottom and not exactly at the bottom like in the video? In other words, is it possible to slide up the Sheet from bottom to up, until it reaches a given distance from the bottom?\nJavier Anton — February 29, 2020 at 9:32 pm (permalink) Javier Anton says:\nWill definitely use this thx\nShai Almog — March 1, 2020 at 2:06 am (permalink) Shai Almog says:\nMaybe a creative use of margin can help with that?\nHaven’t tried it but I think it should work.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/sheet-positions/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"https://www.codenameone.com/img/blog/new-sheet-positioning.jpgnew\"\u003e\u003c/p\u003e\n\u003cp\u003eNot so long ago, we \u003ca href=\"/blog/sheets-samples/\"\u003ereleased\u003c/a\u003e a \u003ca href=\"/javadoc/com/codename1/ui/Sheet/\"\u003eSheet component\u003c/a\u003e that acts like a non-modal dialog box that slides up from the bottom. It occupies only the amount of space required to house its contents, and it provides built-in navigation controls to go \u0026ldquo;back\u0026rdquo; to the previous sheet. By default Sheets are displayed along the bottom of the screen, but we have recently added an update that allows you to position it along the north, east, west, south, or center of the screen, as shown below:\u003c/p\u003e","title":"New Sheet Positioning"},{"content":"\nWe’ve just added support for including CSS inside of Codename One library projects so that CSS styles can now be distributed inside a cn1lib. This opens up a world of possibilities for creating module UI libraries and themes.\nHow it works To begin, you just need to add a \u0026ldquo;css\u0026rdquo; directory inside your Codename One Library project, with a \u0026ldquo;theme.css\u0026rdquo; file in it.\nAdd your CSS styles into the theme.css file, and build the library project.\nIf you add this module to a Codename One application project, these styles will automatically be included.\n__ If you try to install a cn1lib that includes CSS into a Codename One application project that doesn’t have CSS activated, it will fail. You must activate CSS in the application project first. Bonus Tip: Auto-Installing Library into Apps when Building Library This tip is for those of you who are building your own cn1libs. When I’m developing a CN1lib, I always have a separate application project that uses the lib. This is because you can’t test a cn1lib directly inside a library project. The cn1lib first has to be installed into application project before it can be used and tested.\nThis can create a lot of manual steps each time you make changes to your cn1lib and want to test them out. You need to build the library project, then copy the cn1lib from the library’s dist directory, into the application project’s lib directory. Then you need to select \u0026ldquo;Refresh Cn1libs\u0026rdquo; from the Codename One menu in the IDE.\nAs far as I’m concerned, anything more than a single button press is too much for being able to test my changes. Luckily its really easy to eliminate the extra steps by adding a small snippet into your library project’s build.xml file.\nAt the end of the \u0026ldquo;jar\u0026rdquo; target, add the following:\n\u0026lt;copy file=\u0026quot;dist/${application.title}.cn1lib\u0026quot; todir=\u0026quot;path/to/AppProject/lib\u0026quot;/\u0026gt; \u0026lt;ant dir=\u0026quot;path/to/AppProject\u0026quot; target=\u0026quot;refresh-libs-impl\u0026quot; usenativebasedir=\u0026quot;true\u0026quot;/\u0026gt; Now, whenever you build the library project, it will automatically copy it into your application project, and refresh its CN1libs, so that you can test your changes instantly. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — February 23, 2020 at 10:06 am (permalink) Francesco Galgani says:\nThank you, however this can cause that the cn1lib CSS conflict with existing CSS. Another tip for the developer of a cn1lib could be the use of an unique prefix for every CSS included in the cn1lib. That prefix could be the name of the cn1lib, for example. Do you agree?\nShai Almog — February 24, 2020 at 3:06 am (permalink) Shai Almog says:\nI think that just using a unique name for a CSS element should be enough for most cases although a library specific prefix would probably be healthy.\nI don’t think this is something we should force as we’d like the option for CSS to override global theme settings when required e.g. in the case of a theme library. E.g. a cn1lib that offers dark mode theming.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/css-in-cn1libs/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/css-in-cn1libs/css-in-cn1llibs.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve just added support for including CSS inside of Codename One library projects so that CSS styles can now be distributed inside a cn1lib. This opens up a world of possibilities for creating module UI libraries and themes.\u003c/p\u003e\n\u003ch3 id=\"how-it-works\"\u003eHow it works\u003c/h3\u003e\n\u003cp\u003eTo begin, you just need to add a \u0026ldquo;css\u0026rdquo; directory inside your \u003cstrong\u003eCodename One Library\u003c/strong\u003e project, with a \u0026ldquo;theme.css\u0026rdquo; file in it.\u003c/p\u003e\n\u003cp\u003eAdd your CSS styles into the \u003cstrong\u003etheme.css\u003c/strong\u003e file, and build the library project.\u003c/p\u003e","title":"CSS in CN1Libs"},{"content":"\nIf you have an existing Codename One app that uses the designer for its theme, then you may have been reluctant to try to migrate it to CSS. Codename One projects are assumed to be using either CSS or the designer for their themes. But not both at the same time. When an app has CSS enabled, it compiles the css/theme.css to src/theme.res when the app is built, and it is kept in sync when changes are made to the theme.css file. Changes that you make manually to the theme.res file, would be lost the next time it synchronizes with the theme.css file. This doesn’t jive with legacy projects where you have customized the theme.res using the designer.\nI don’t blame you if you don’t feel like converting your theme.res file into CSS. After years of customization, a theme.res file may contain hundreds of images and styles. In addition, if your app is using the old GUI Builder, your theme.res file may include actual form designs, which can’t be migrated to CSS.\nFortunately, there is a way to add CSS support for your application without having to lose all of your work. Codename One allows you to \u0026ldquo;layer\u0026rdquo; themes over top of each other, thus allowing you to use multiple themes. It does this, for example, if you are using the native theme in your app. It uses the native theme for the platform as a base, but overrides it with the styles in your app’s theme.\nSteps:\nBefore you begin, make sure that your theme.res is not currently opened in the designer.\nRename your \u0026ldquo;theme.res\u0026rdquo; file to \u0026ldquo;theme_legacy.res\u0026rdquo; (This is found in the src directory)\nDelete the res/theme directory, and the res/theme.xml file from your project. Open the theme_legacy.res file in the designer.\nUnder theme constants, add the constant \u0026ldquo;OverlayThemes\u0026rdquo;, with a value of \u0026ldquo;theme\u0026rdquo;.\nThen Save\nOpen your app’s main file, and find where the \u0026ldquo;theme.res\u0026rdquo; file is loaded. Look for a line like: theme = UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;);\nAnd change it to\ntheme = UIManager.initFirstTheme(\u0026quot;/theme_legacy\u0026quot;);\nIf your app is an old GUI Builder app, then it might be new StateMachine(\u0026quot;/theme\u0026quot;) instead.\nSave\nOpen Codename One Preferences. Click on \u0026ldquo;CSS Support\u0026rdquo; Click \u0026ldquo;Activate CSS Now\u0026rdquo; The screen should then change to a menu as shown here:\nPress \u0026ldquo;Open CSS File For Editing\u0026rdquo;\nOpen the CSS file for editing, and make a change that you’ll definitely notice, for testing. Here I’ll just change the color of labels to \u0026ldquo;Green\u0026rdquo;. Save the CSS file, and run your project. You should see the CSS take effect. In my example, my label is now green.\nWhat did all this do? This tells the app to load your theme_legacy.res file instead of theme.res. Because of the \u0026ldquo;OverlayThemes\u0026rdquo; constant in your theme_legacy.res, Your app will automatically load the theme.res file’s styles over top of your legacy theme. The theme.res file will then be generated from your css/theme.css file, and kept in sync. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — February 14, 2020 at 11:06 am (permalink) Another tip about CSS is the support for multiple CSS files in the same project, as explained here: https://stackoverflow.com/a/53488737. I have thousands of lines of CSS, and I feel convenient to use multiple CSS files. This also allows me to have a separate CSS files for Android, for iOS and Javascript, that are useful in the (very few) cases that it’s necessary. The downside is that, in this way, the support for recompiling CSS on saving and the updating of UI on the fly is lost. It could be interesting a native support for multiple CSS that doesn’t require to manually edit the build.xml and that can update the UI on the fly.\nJavier Anton — February 16, 2020 at 7:22 am (permalink) Nice post, thanks. Once we have CSS enabled, are we able to continue editing our designer theme, or is that no longer editable?\nShai Almog — February 17, 2020 at 2:10 am (permalink) You can edit the non-CSS resource files using the designer. You can also open the CSS file in the designer but all changes will be overwritten so it’s mostly useful as a debugging tool to see what the CSS generated which is often interesting (e.g. it sometimes generates images to implement some UI settings).\nDurank — February 18, 2020 at 3:02 pm (permalink) this migration create all my styles, contants, containers, etc in the theme.css file from theme.res? when I migrated to css file I need to continue editting .css file ?\nShai Almog — February 19, 2020 at 3:12 am (permalink) No. You will need to maintain both.\nDurank — March 3, 2020 at 3:37 pm (permalink) When I made the migration following the up steps recommended. If I compile and run my app in simulator it will continue working with out doing nothing?\nWitch file I will edit in the future if In want make some change? theme_legacy.res or theme.css?\nDurank — March 3, 2020 at 4:52 pm (permalink) But could you tell me what is the purpose of this post? I need to migrate manually all my styles to the .css file?\nShai Almog — March 4, 2020 at 2:12 am (permalink) Both would be editable. The idea is that you’d want to start moving stuff to the css but do it at your own pace\nShai Almog — March 4, 2020 at 2:15 am (permalink) It looks like you created a recursive dependency between the CSS and the theme. Did you follow all the instructions?\nShai Almog — March 4, 2020 at 2:16 am (permalink) Shai Almog says:\nThat you can do it at a slower pace by mixing css and your existing work.\nDurank — March 5, 2020 at 5:27 pm (permalink) Durank says:\nI solve the issue. Other questiong to you. Can I write all my styles to css file from the theme_legacy.xml to modifie any uiid?\nwhat is the representation in css code this style\nShai Almog — March 6, 2020 at 5:15 am (permalink) Shai Almog says:\nThese map pretty closely to CSS. Which specifically is causing a problem?\nWe don’t support automatic CSS conversion from resources.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/migrating-legacy-applications-to-css/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/migrating-legacy-applications-to-css/migrating-legacy-apps-to-css.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIf you have an existing Codename One app that uses the designer for its theme, then you may have been reluctant to try to migrate it to CSS. Codename One projects are assumed to be using either CSS or the designer for their themes. But not both at the same time. When an app has CSS enabled, it compiles the css/theme.css to src/theme.res when the app is built, and it is kept in sync when changes are made to the theme.css file. Changes that you make manually to the theme.res file, would be lost the next time it synchronizes with the theme.css file. This doesn’t jive with legacy projects where you have customized the theme.res using the designer.\u003c/p\u003e","title":"Migrating Legacy Applications to CSS"},{"content":"\nApple is so very clever with its designs. With the iPhone X, they found way to squeeze in a larger screen without increasing the phone dimensions. The screen nearly covers the entire front face of the phone. The \u0026ldquo;notch\u0026rdquo;, as it has come to be known, may have been a practical concession (they needed to put the camera and speaker somewhere, after all) or an intentional design choice – or maybe a little of both. However the notch was conceived, it is here to stay, and we developers need to \u0026ldquo;work around\u0026rdquo; it.\nAnd it’s not only the notch that we have to work around. The iPhone X screen has round corners too. Not the old, boring, right angled corners that we’re used to. And the coup de gras is the task bar that now appears along the bottom of the screen, that allows the user to \u0026ldquo;swipe up\u0026rdquo; to minimize the app. This has made it more difficult to use bottom navigation in our apps because we have to make sure that the user doesn’t accidentally close the app when they try to click on one of our app’s buttons at the bottom of the screen.\nWe have recently added an API to help you work around these landmines. We’ve added the method Form.getSafeArea(), that will load the \u0026ldquo;safe\u0026rdquo; bounds of the current form. If you are drawing components on the screen and want to make sure that they aren’t clipped by \u0026ldquo;the notch\u0026rdquo;, the corners, or the task bar, then you can use this API to create a safe play-pen for yourself.\nWe’ve also added Container.setSafeArea(boolean) which you can use to ensure that the container renders its children inside the \u0026ldquo;Safe\u0026rdquo; area. The Tabs component has been updated to that its tab buttons are rendered inside a \u0026ldquo;safe area\u0026rdquo;. When run on the iPhone X, you’ll notice a little bit of extra padding under your tab buttons that appear at the bottom of the screen.\nSome Examples // Tab 1: A safe area. Will render all children inside safe area. Container tab1Contents = new Container(); tab1Contents.setSafeArea(true); // ... omitted code - building the tab 1 contents. // Tab 2: A non-safe area. Children may clip \u0026quot;unsafe\u0026quot; areas. Container tab2Contents = new Container(); // ... omitted code - building tab 2 contents. tabs.addTab(\u0026quot;Safe Tab\u0026quot;, tab1Contents); tabs.addTab(\u0026quot;Unsafe Tab\u0026quot;, tab2Contents); form.add(BorderLayout.CENTER, tabs); Figure 1. Tab 1 is a safe area, so its children will not get clipped by the notch\nFigure 2. Tab 2 is not a safe area, so some of its children may be clipped by the notch\nFurther Reading Check out the SafeAreasSample in the Samples project for the full working example from which the sample code above was taken. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — February 10, 2020 at 11:40 am (permalink) Thank you Steve, this solves a lot of issues in a simple way! 😀\nIs it fine if it’s applied to the contentPane?\nSteve Hannah — February 10, 2020 at 1:25 pm (permalink) You can apply it to the content pane as long as you don’t have any components that are supposed to bleed to the edge. E.g. If you have tabs, it would look weird because the tab buttons wouldn’t be at the very bottom of the screen.\nJavier Anton — March 10, 2021 at 1:33 pm (permalink) Javier Anton says:\nA bit late to the conversation, but thought I’d share an alternative to this. To have a bit more control over the \u0026ldquo;padding\u0026rdquo; one way is to manually detect the notches with the below code from SO\n– (BOOL)hasTopNotch{\nif (@available(iOS 13.0, *)) {\nreturn [self keyWindow].safeAreaInsets.top \u0026gt; 20.0;\n}else{\nreturn [[[UIApplication sharedApplication] delegate] window].safeAreaInsets.top \u0026gt; 20.0;\n}\nreturn NO;\n}\n– (UIWindow*)keyWindow {\nUIWindow *foundWindow = nil;\nNSArray *windows = [[UIApplication sharedApplication]windows];\nfor (UIWindow *window in windows) {\nif (window.isKeyWindow) {\nfoundWindow = window;\nbreak;\n}\n}\nreturn foundWindow;\n}\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/safe-areas/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/safe-areas/safe-areas.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eApple is so very clever with its designs. With the iPhone X, they found way to squeeze in a larger screen without increasing the phone dimensions. The screen nearly covers the entire front face of the phone. The \u0026ldquo;notch\u0026rdquo;, as it has come to be known, may have been a practical concession (they needed to put the camera and speaker somewhere, after all) or an intentional design choice – or maybe a little of both. However the notch was conceived, it is here to stay, and we developers need to \u0026ldquo;work around\u0026rdquo; it.\u003c/p\u003e","title":"Safe Areas"},{"content":"\nWe have just finished the initial release of our \u0026ldquo;Sign-in with Apple\u0026rdquo; cn1lib, which adds \u0026ldquo;Sign-in with Apple\u0026rdquo; support to Codename One apps. On iOS 13 and higher, this will use Apple’s native Authentication framework. On other platforms (e.g. Android, Desktop, and Simulator), this will use Apple’s Oauth2 authentication service.\nThe main motivation for adding this functionality is that Apple would require apps that use \u0026ldquo;sign in with…​\u0026rdquo; to support its service too. If you won’t support sign in with Apple but include support signin with Facebook/Google your app might be rejected in the future.\n__ If your app doesn’t require sign-in or uses custom login logic there’s no requirement to support \u0026ldquo;sign in with Apple\u0026rdquo; Getting Started The hardest part of adding Apple sign-in support house-keeping you need to perform in Apple’s developer portal. If you only intend to support Apple sign-in with your iOS app, and not on other platforms, then the process is pretty simple – you just check a box next to \u0026ldquo;Sign-in with Apple\u0026rdquo; in the capabilites section of your App ID details page. Set-up for other platforms is a bit more involved. You need to create a \u0026ldquo;Services ID\u0026rdquo; (used for the Oauth2 client ID), and generate a private key so you will be able to generate the Oauth2 client secret on-demand.\nFor full instructions see the setup documentation in the cn1lib’s wiki.\nYou can find the plugin in Codename One Settings. Once you’ve added the cn1lib to your Codename One project, you can begin using the AppleLogin class to provide Apple sign-in support.\nThe Code The following is an example of how to add Apple login support to your app.\nAppleLogin login = new AppleLogin(); // If using on non-iOS platforms, set Oauth2 settings here: // login.setClientId(...); // login.setKeyId(...); // login.setTeamId(...); // login.setRedirectURI(...); // login.setPrivateKey(...); if (login.isUserLoggedIn()) { new MainForm().show(); } else { new LoginForm().show(); } .... class LoginForm extends Form { LoginForm() { super(BoxLayout.y()); $(getContentPane()).setPaddingMillimeters(3f, 0, 0, 0); add(FlowLayout.encloseCenter(new Label(AppleLogin.createAppleLogo(0x0, 15f)))); Button loginBtn = new Button(\u0026quot;Sign in with Apple\u0026quot;); AppleLogin.decorateLoginButton(loginBtn, 0x0, 0xffffff); loginBtn.addActionListener(evt-\u0026gt;{ login.doLogin(new LoginCallback() { @Override public void loginFailed(String errorMessage) { System.out.println(\u0026quot;Login failed\u0026quot;); ToastBar.showErrorMessage(errorMessage); } @Override public void loginSuccessful() { new MainForm().show(); } }); }); add(FlowLayout.encloseCenter(loginBtn)); } } .... class MainForm extends Form { MainForm() { super(BoxLayout.y()); add(new SpanLabel(\u0026quot;You are now logged in as \u0026quot;+login.getEmail())); Button logout = new Button(\u0026quot;Logout from Apple\u0026quot;); logout.addActionListener(e-\u0026gt;{ login.doLogout(); new LoginForm().show(); }); add(logout); } } For full working demo, see the Demo app\nSome screenshots from the demo:\nMore information See the Github project for the Apple Sign-in cn1lib.\nSee the Demo project for an example.\nSee the set-up instructions detailed instructions on adding support for Apple Sign-in.\nSee Apple’s documentation for Sign-in with Apple.\nArchived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJavier Anton — April 1, 2020 at 12:30 pm (permalink) This cn1 lib breaks the host app that imports it at compile time. The reason is that the native javase bit of the lib has incorrect package names and some imports aren’t available (in AppleSignInNativeImpl and WebViewBrowserWindow). The host app will compile when manually commenting these things out, but it might be worth updating the cn1lib so it doesn’t throw these errors as currently the native interface gets reset to faulty code each time the cn1lib is refreshed\nAlso, even after doing these things the following error is thrown on the server when compiling AppleLogin:\ncom_codename1_social_AppleLogin.m:22:10: fatal error: ‘java_io_StringReader.h’ file not found\n\u0026ldquo;#\u0026ldquo;include \u0026ldquo;java_io_StringReader.h\u0026rdquo;\nCould it be that java.io.StringReader was used instead of com.codename1.util .regex.StringReader?\nSteve Hannah — April 1, 2020 at 1:52 pm (permalink) Steve Hannah says:\nI have replied inside the issue you opened in the issue tracker. https://github.com/codenameone/CodenameOne/issues/3068\nThe gist of it is that the build.xml file needs to be updated, and you need to run an update libs. This won’t be needed for long as the build.xml file will come updated with the next plugin update.\nJavier Anton — April 1, 2020 at 2:40 pm (permalink) Javier Anton says:\nI’ll wait until the next update then as I don’t need this right now, was just toying with it in preparation of Apple making this a requirement (apparently that has been rolled back to June last I heard because of the coronavirus crisis)\nThanks for this\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/sign-in-with-apple-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/sign-in-with-apple-support/sign-in-with-apple-header.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe have just finished the initial release of our \u003ca href=\"https://github.com/shannah/cn1-applesignin\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u0026ldquo;Sign-in with Apple\u0026rdquo; cn1lib\u003c/a\u003e, which adds \u0026ldquo;Sign-in with Apple\u0026rdquo; support to Codename One apps. On iOS 13 and higher, this will use Apple’s native Authentication framework. On other platforms (e.g. Android, Desktop, and Simulator), this will use Apple’s Oauth2 authentication service.\u003c/p\u003e\n\u003cp\u003eThe main motivation for adding this functionality is that Apple would require apps that use \u0026ldquo;sign in with…​\u0026rdquo; to support its service too. If you won’t support sign in with Apple but include support signin with Facebook/Google your app might be rejected in the future.\u003c/p\u003e","title":"Sign-in with Apple Support"},{"content":"\nThe duality of InteractionDialog and Dialog is often confusing to the Codename One newcomer (and to some degree to veteran developers too). This is in part due to the multiple behavior differences that extend far beyond the \u0026ldquo;official\u0026rdquo; functionality difference. This has its roots in history that predated Codename One.\nIn this post I’ll try to clarify the process of picking the \u0026ldquo;right one\u0026rdquo; and the tradeoffs involved.\nA dialog can be modal or non-modal but it isn’t interactive like an InteractionDialog. The modal dialog blocks the EDT internally using InvokeAndBlock so the current thread stops until there’s a response from the dialog. This is convenient but has some edge case issues. E.g. the event that launched the dialog might trigger other events that would happen after the dialog was dismissed and cause odd behavior.\nBut that’s not the big thing in modality. Modality effectively means the form behind you \u0026ldquo;doesn’t exist\u0026rdquo;. Everything that matters is the content of the dialog and until that is finished we don’t care about the form behind. This core idea meant that a Dialog effectively derives Form and as such it behaves exactly like showing another Form. In other words a Dialog IS A FORM. This effectively disables the current Form. What you see behind the dialog is a drawing of the previous Form, not the actual Form.\nText fields can pose a problem in this case. Because the way the dialog is positioned (effectively padded into place within its form using margin) the UI can’t be scrolled as text field requires when the virtual keyboard rises. Since people use dialogs in such scenarios we try to workaround most of these problems but sometimes it’s very hard e.g. if the dialog has a lot of top margin, the virtual keyboard is open and covering it. Or if the user rotates the screen at which point the margin positioning the dialog becomes invalid.\n__ In InteractionDialog Some of these issues such as the margin to position also apply so it’s also a bit problematic for text input InteractionDialog is a completely different beast that sprung out of a completely different use case. What if we want a Dialog such as a \u0026ldquo;color palette\u0026rdquo; that floats on top of the ui?\nWe can move it from one place to another but still interact with the underlying form. That’s the core use case for InteractionDialog. As such modality is no longer something we need so it was never baked into InteractionDialog although it technically could have been (but it doesn’t make sense to the core use case).\nIt’s implemented as a Container placed into the layered pane of the current Form so the Form around it is \u0026ldquo;real\u0026rdquo;. Because the Form is \u0026ldquo;live\u0026rdquo;, layout works better. The removal of modality makes some edge cases related to editing slightly better. There are still some inherent problems with Dialog positioning and rotation though. It also allows you to click outside of the Dialog while input is ongoing which might be a desirable/undesirable effect for your use case.\nOverall I try to use dialogs only for very simple cases and avoid input in any Dialog when possible. If I use input I never use more than one field (e.g. no-username and password fields) so I won’t need to scroll. These things work badly for native UIs as well e.g. with the virtual keyboard obscuring the submit button etc. Since those behaviors are very hard to get right for all resolution/virtual keyboard scenarios.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/picking-dialog-type/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/picking-dialog-type/picking-dialog-type.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe duality of \u003ccode\u003eInteractionDialog\u003c/code\u003e and \u003ccode\u003eDialog\u003c/code\u003e is often confusing to the Codename One newcomer (and to some degree to veteran developers too). This is in part due to the multiple behavior differences that extend far beyond the \u0026ldquo;official\u0026rdquo; functionality difference. This has its roots in history that predated Codename One.\u003cbr\u003e\nIn this post I’ll try to clarify the process of picking the \u0026ldquo;right one\u0026rdquo; and the tradeoffs involved.\u003c/p\u003e","title":"Picking a Dialog Type"},{"content":"\nTwo months ago I published the CN1Lib \u0026ldquo;Wowza Live Streaming Events\u0026rdquo;, as usual you can install that by the Extension Manager.\nThe purpose of this CN1Lib is to add live streaming capabilities to iOS and Android Codename One apps, hiding all the complexities and reducing the effort.\n__ The Wowza cn1lib has been deprecated since the publication of this post However, live events are not trivial. That’s why you should read this README carefully: https://github.com/jsfan3/CN1Libs-WowzaLiveStreaming/blob/master/README.md\nThis CN1Lib lets you to broadcast a live video streaming event from a mobile app. The streaming is identified by a unique id which is automatically assigned. You can then play the live video stream with a given id and an adaptive bitrate;\nYou can also record live streams to watch later.\nAll streaming operations (storage, processing, adapting to multi-bitrate, broadcasting to multiple devices, etc.) are automatically backed by the Wowza Cloud Service. This includes accurate logging and monitoring.\nMore specifically, this CN1Lib integrates and makes use of GoCoder SDK for iOS, GoCoder SDK for Android, and it performs RESTful requests to the Wowza Streaming Cloud service (live event plan).\nPlease consider this CN1Lib in alpha stage, not ready yet for production environments. I’d appreciate contributions/pull requests to improve this CN1Lib.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/live-streaming-wowza/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/live-streaming-wowza/wowza.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eTwo months ago I published the CN1Lib \u0026ldquo;Wowza Live Streaming Events\u0026rdquo;, as usual you can install that by the Extension Manager.\u003cbr\u003e\nThe purpose of this CN1Lib is to add live streaming capabilities to iOS and Android Codename One apps, hiding all the complexities and reducing the effort.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eThe Wowza cn1lib has been deprecated since the publication of this post\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eHowever, live events are not trivial. That’s why you should read this README carefully: \u003ca href=\"https://github.com/jsfan3/CN1Libs-WowzaLiveStreaming/blob/master/README.md\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttps://github.com/jsfan3/CN1Libs-WowzaLiveStreaming/blob/master/README.md\u003c/a\u003e\u003c/p\u003e","title":"Live Streaming with Codename One and Wowza"},{"content":"\nToday’s blog post will delve further into our new media features. We’ve recently added an API to access raw PCM data from the device’s microphone. Previously, the media recording API could only be configured to save audio to a file. This is fine for most use cases, but sometimes it is necessary to access the the raw PCM stream directly. For example for voice recognition, or audio processing, or audio visualization.\nHow it works In order to access an audio PCM stream, you need to create an AudioBuffer object, which will be used as a destination for microphone input.\nAudioBuffer buffer = MediaManager.getAudioBuffer(\u0026quot;mybuffer.pcm\u0026quot;, true, 4096); A couple of points here:\nThe \u0026ldquo;mybuffer.pcm\u0026rdquo; is the virtual path to the buffer. Think of it like a file path that doesn’t correspond to an actual file. This can be any arbitrary string. We will be referencing it later when we construct the media recorder, to redirect its output to this audio buffer.\nThe 2nd parameter (true) says to \u0026ldquo;create\u0026rdquo; the audio buffer object if it doesn’t already exist in the central registry.\nThe 3rd parameter, is the buffer size. You can put anything here, and the API will adapt. I’m using 4096 here, but that was chosen rather arbitrarily.\nNext, you add a callback which will be executed whenever the buffer’s contents are changed. This happens when a new chunk of PCM data is available from the microphone.\nfinal float[] sampleData = new float[buffer.getMaxSize()]; buffer.addCallback(buf-\u0026gt;{ buf.copyTo(sampleData); int sampleRate = buf.getSampleRate(); int numChannels = buf.getNumChannels(); int len = buf.getSize(); sendDataToServerForProcessing(sampleData, 0, len, sampleRate, numChannels); }); Some key points here:\nThe callback does NOT run on the EDT. It runs on its own thread.\nThe buf.copyTo() method will copy all new data from the buffer into our own float[] array. It will only write values in the range [0, buf.getSize()). Each entry will be a float between -1 and 1.\nbuf.getSize() may return a different value in each invocation, as the \u0026ldquo;size\u0026rdquo; of the buffer reflects the current data in the buffer. Not to be confused with the maxSize of the buffer, which is the original size of the buffer, as it was created in the getAudioBuffer() method.\nIf you are processing the data in any way, you’ll need to know both the sampleRate, and the number of channels of the input. It is important to collect this data from the audioBuffer inside this callback, and not depend on the settings you provided originally to createMediaRecorder().\nWe’ll use MediaRecorderBuilder to construct our media recorder now as follows:\nMediaRecorderBuilder mrb = new MediaRecorderBuilder() .path(\u0026quot;mybuffer.pcm\u0026quot;) .redirectToAudioBuffer(true); Media microphone = MediaManager.createMediaRecorder(mrb); Notice that, for the path() parameter of the builder, we use the same value we used in getAudioBuffer(). This is extremely important, otherwise the media recorder won’t run the callback in your AudioBuffer instance.\nWe can start recording now using microphone.play(), and pause using microphone.pause(). Or use the new async APIs, playAsync() and pauseAsync() to gain more clarity about the recording state.\nSaving PCM Stream to a WAV File In order to test the AudioBuffer class, we needed to be able to play the PCM stream that we capture to make sure that it is working correctly, and that it hasn’t been corrupted in any way. We added a class, WAVWriter, for writing a PCM stream to a WAV file to facilitate this testing. A WAV file, after all, just contains a raw stream of PCM data, with some headers to declare the data format, so this class is pretty minimal.\nThe following example records directly from the PCM stream to a WAV file in file system storage.\nWAVWriter wavWriter; AudioBuffer audioBuffer; private void record() throws IOException { audioBuffer = MediaManager.getAudioBuffer(bufferPath, true, 4096); final float[] floatSamples = new float[audioBuffer.getMaxSize()]; audioBuffer.addCallback(buf-\u0026gt;{ synchronized(clipLock) { if (wavWriter == null) { try { wavWriter = new WAVWriter( new File(fileName), buf.getSampleRate(), buf.getNumChannels(), 16 ); } catch (IOException ex) { Log.e(ex); return; } } buf.copyTo(floatSamples); try { wavWriter.write(floatSamples, 0, buf.getSize()); } catch (IOException ex) { Log.e(ex); } } }); } MediaRecorderBuilder builder = new MediaRecorderBuilder() .audioChannels(1) .path(bufferPath) .redirectToAudioBuffer(true); MediaManager.createMediaRecorder(builder)); synchronized(clipLock) { wavWriter = null; } } // … And when you’re finished recording, just close the WAVWriter // for the file to be written. wavWriter.close(); The key parts of this example are:\nWe don’t necessarily need to instantiate the WAVWriter object inside the AudioBuffer callback, but we do need some information that the callback provides: the sample rate, and number of channels. This information is supplied in the audiobuffer callback, and won’t change, so you could also just fetch this information in the first callback, and store it for when and where you do instantiate the WAVWriter object.\nThe WAVWriter.write(float[] samples, int offset, int len) method is where you can pass the PCM samples directly to WAV file.\nRemember to call close() on the WAVWriter to ensure that the file is written.\nYou can find some examples using the AudioBuffer and WAVWriter classes to write PCM streams to a WAV File in the Samples project. Specifically, the AsyncMediaSample and the AudioBufferSample.\nSample Rates and Downsampling A PCM data stream is a digital approximation of a sound wave form. The sample rate, usually expressed in Hz (hertz) is the number of samples we extract per second. A sample rate of 16000 Hz indicates that we are extracting 16000 floating point values (per channel) per second. The higher the sample rate, the better wave approximation will be, and therefore the better quality the sound will be. But higher sample rates also correspond to larger file sizes.\nWhen you construct a media recorder, you can request a specific sample rate, but there is no guarantee that the underlying platform will comply with your request. Some platforms only support the native sample rate of the audio hardware, so you’re at the mercy of the audio chip to a certain extent. You can find out the actual sample rate by calling audioBuffer.getSampleRate(), any time after the first callback is executed – as this is where the platform informs the audio buffer about the underlying sample rate.\nSome common sample rates you’ll see are 16000, 22050, 44100, and 48000. If you are passing the PCM data stream to service that only accepts a certain sample rate, then you may need to downsample the data. The AudioBuffer class includes a downsample() method with a rudimentary algorithm that may be sufficient for some cases. It is lacking some of the features of high-end down-sampling algorithms, such as low pass filtering, and it does noticeably lower the audio quality, but if your application doesn’t need \u0026ldquo;perfect sound\u0026rdquo;, then it might be appropriate for your needs. If you do need perfect sound, you should either perform the downsampling server-side, or use a 3rd-party sound library.\nThe downSample() method works as follows:\naudioBuffer.downSample(16000); // downsample to 16000Hz) You should call this method inside your callback, before copying the data to your float samples buffer. This is because it will modify the data in the audio buffer, and update both the \u0026ldquo;size\u0026rdquo; property, and the \u0026ldquo;sampleRate\u0026rdquo; property of the buffer, to accurately reflect the new sample rate.\nThe AudioBufferSample includes an example usage of this method.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-low-level-microphone-api/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-low-level-microphone-api/new-low-level-microphone-api.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eToday’s blog post will delve further into our new media features. We’ve recently added an API to access raw PCM data from the device’s microphone. Previously, the media recording API could only be configured to save audio to a file. This is fine for most use cases, but sometimes it is necessary to access the the raw PCM stream directly. For example for voice recognition, or audio processing, or audio visualization.\u003c/p\u003e","title":"New Low-level Microphone API"},{"content":"\nI’m Francesco Galgani, a developer and a Codename One enthusiast.\nFew days ago I published the first version of an Italian free preliminary course for mobile cross-platform development with Java + Codename One. I’ll probably write other articles, however the first module is complete. This course is intended for people interested in app development, but have no prior programming experience. That’s why my first article has no code, it’s preparatory to understand the magic and challenges of development.\nYou can start with the course by visiting this page: https://www.informatica-libera.net/content/sviluppare-app-multipiattaforma-indice-del-corso-introduttivo\nIn this course I tried to share my experience. The reader is gradually introduced to the first lines of Java code, that solve a simple math problem. After that, the same problem is used to see how to write the first app with Codename One. Finally, there is a lot of \u0026ldquo;homework\u0026rdquo; to learn Codename One.\nCurrently, there are seven articles.\nThe first is about Codename One, it’s a short introduction: I describe why I consider it the best tool for cross-platform development. I invite to spread the word about it.\nIn the second I discuss why it’s so difficult to find a good learning path in the chaotic and unstable world of software development. I explain why the real challenge is to find good indications that will last over time: about that, I report concrete examples of wrong paths. I indicate JAVA + Codename One + Spring Boot as a good direction.\nThe third is an introduction to the \u0026ldquo;algorithm\u0026rdquo; concept. I discuss what we need to know about the hardware and what are the programmable machines that we use every day (smart-phone, smart-tv, smart-car, etc.). I included an introduction to programming languages, written by me, as downloadable pdf slides. After that, I describe why software debugging is the longest, most difficult and most expensive part of software development. I conclude with the concepts of \u0026ldquo;device-agnostic\u0026rdquo;, \u0026ldquo;IDE-agnostic\u0026rdquo; and \u0026ldquo;language-agnostic\u0026rdquo;.\nIn the fourth I introduce a simple math problem (the linear motion of a car) that I use to describe the first lines of Java code and to show a good way to decompose a problem in algorithms. I suggest to use a Java online compiler to test the code examples. Then I describe why algorithms depend on the tools we have and on the logic of the chosen programming language. I suggest what we can try to do when the chosen programming language doesn’t have the functionality what we need, with examples.\nIn the fifth I deeply describe what we need about software, hardware and cloud services to do cross-platform development. After that, I suggest which chapters of a specific Java 8 learning book should be studied. I also include a Java introduction written by me, as downloadable pdf. Then I list several links about Codename One learning tools, documentation, technical support.\nThe sixth revisits the same math problem of the car in an Objected-Oriented Programming perspective. I guide the reader to write the first Codename One app to solve that problem. This article ends with a list of coding exercises to learn Codename One.\nIn the seventh I summarize sixteen points what I think are the best software engineering practices for managing complexity in a software project.\nI hope you or your friends will find this guide helpful and useful.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/preliminary-course-mobile-cross-platform-development/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/preliminary-course-mobile-cross-platform-development/learn-codenameone-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’m Francesco Galgani, a developer and a Codename One enthusiast.\u003c/p\u003e\n\u003cp\u003eFew days ago I published the first version of an Italian free preliminary course for mobile cross-platform development with Java + Codename One. I’ll probably write other articles, however the first module is complete. This course is intended for people interested in app development, but have no prior programming experience. That’s why my first article has no code, it’s preparatory to understand the magic and challenges of development.\u003c/p\u003e","title":"Preliminary course for mobile cross-platform development with Java and Codename One"},{"content":"\nCodename One provides play() and pause() methods as part of the Media interface, which you can use to start and stop media clips programmatically. If you are deploying your app to the browser using the Javascript port, then you should be aware of some restrictions imposed by modern web browsers on media playback, and how to work around them.\nModern browsers will only allow audio playback that is triggered by direct user interaction. This basically means that the user needs to press a button to trigger audio playback.\nIf your app fits into this model (playing sounds only in response to user button presses), then you don’t have to worry about this restriction. But if you want to play sounds in other contexts, you might bump into this restriction. For example, you might want to play a sound in a chat app, in response to someone else’s message being posted (i.e. in response to a server event). Or you might want to play a sound in response to voice input, or location changes, or when a timer goes off.\nSo what happens if you call mySoundClip.play(), and the browser disallows it on the grounds that it wasn’t in direct response to user interaction? Our media API catches this failure, and displays a popup-dialog saying \u0026ldquo;Media ready\u0026rdquo; with a \u0026ldquo;Play\u0026rdquo; button as shown here:\nWhen the user presses the \u0026ldquo;Play\u0026rdquo; button, then the media will start playing because this time it should \u0026ldquo;meet\u0026rdquo; the browser’s user-interaction requirements due to the user’s click on the ‘play’ button.\nMake Sure to Call cleanup() The \u0026ldquo;media ready\u0026rdquo; popup dialog shouldn’t present a major problem for your app’s user experience. However, if you’re playing several audio clips, one after another, it could become annoying for the user to have to keep pressing \u0026ldquo;Play\u0026rdquo; for each clip. Luckily, the browser will \u0026ldquo;remember\u0026rdquo; if the user has authorized audio playback on a particular media element, so if you play your cards right, you may only need to prompt the user to play the first sound clip, and the subsequent ones will just be allowed by the browser. In the Javascript port, each Media object is mapped to its own HTMLMediaElement (an \u0026lt;audio\u0026gt; or \u0026lt;video\u0026gt; DOM element). It uses a pool of media elements to try and reuse the underlying media elements if it can. A Media object’s underlying element is only returned to the pool when its cleanup() method is called. If you’re playing a series of audio clips in a row, you should make sure to call the cleanup() method on each sound clip, before the next one plays, to avoid being forced by the browser to display \u0026ldquo;Media Ready/Play\u0026rdquo; dialog.\nFor example, suppose you’re need to play a series of sound clips, one after another. You might do something like:\nMedia media; List\u0026lt;String\u0026gt; clipsUrls = ...; void play(int index) { If (media != null) { media.cleanup(); } media = createMedia(clipUrls.get(index), false, () -\u0026gt;{ callSerially(()-\u0026gt;{ play(index+1); }); }); } play(0); In this example, I’m using a single property, media, which we will reuse for each sound clip, and I have a list of URLs for sound clips I want to play sequentially. The play(index) method plays the clip at the specified index – but first, it cleans up the previous sound clip. This is extra important in the Javascript port since this will return the sound clip’s \u0026lt;audio\u0026gt; element to the pool, so that it (and it’s granted permissions) can be reused for the next sound clip.\nWe use the completion handler in createMedia() to be notified when the sound clip has finished playing, at which point it calls play(index+1) – i.e. it plays the next clip. Notice that I place the play() call inside callSerially() so that it is deferred to the next dispatch. This may not be strictly necessary, but it avoids any problems that might occur trying to call cleanup() from inside the media’s completed callback.\nFinally we start the chain off by calling play(0) to play the first sound clip. If play(0) is called in response to a user interaction (e.g. inside a button’s action listener), then the sound clip should play unimpeded. But if it is called outside of this context, then a dialog may be displayed to prompt the user to play the sound clip.\nCheck out the AsyncMediaSample in the Samples project for a complete working example that follows this workflow. That example just runs a continuous cycle of recording audio from the microphone, then playing back what you recorded. If you run this example on an iOS device (which seems to be the most strict about its media playback restrictions), you’ll be prompted to play the media at the beginning – but won’t be asked again for subsequent clips.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/javascript-media-restrictions/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/javascript-media-restrictions/html5-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One provides \u003ccode\u003eplay()\u003c/code\u003e and \u003ccode\u003epause()\u003c/code\u003e methods as part of the \u003ccode\u003eMedia\u003c/code\u003e interface, which you can use to start and stop media clips programmatically. If you are deploying your app to the browser using the Javascript port, then you should be aware of some restrictions imposed by modern web browsers on media playback, and how to work around them.\u003c/p\u003e\n\u003cp\u003eModern browsers will only allow audio playback that is triggered by direct user interaction. This basically means that the user needs to press a button to trigger audio playback.\u003c/p\u003e","title":"Javascript Media Restrictions to be Aware Of"},{"content":"\nWe’ve recently released a few updates to our Media APIs in order to support a wider variety of use cases. One of these upgrades is the new AsyncMedia interface, which includes async play and pause support.\nThe Media interface has always had play() and pause() methods, but it didn’t provide an easy way to detect when they had taken effect. On most platforms, this hasn’t been a major issue because the delay between when play() is called, and when the media actually starts playing is small, or negligible. But our Javascript port presented some new challenges due to strict browser permissions surrounding media playback. In some cases, which I’ll discuss in detail in my next blog post, the user will be prompted to provide permission to play audio, or access the microphone, when play() is called. This means that the delay between play() and when the media actually starts playing may be significant.\nNew AsyncMedia interface The new AsyncMedia interface extends Media and adds some new methods. Among these new methods, you’ll find playAsync() and pauseAsync() which return PlayRequest and PauseRequest objects respectively.\nSince MediaManager returns media as Media objects, you’ll need to convert them into AsyncMedia objects in order to access the new functionality. You can use the new MediaManager.getAsyncMedia(Media) method for this purpose. Almost all Media objects in Codename One already implement AsyncMedia, so the getAsyncMedia() will usually just return the same object, but casted to AsyncMedia. In the rare case where the Media object, doesn’t already implement AsyncMedia, getAsyncMedia() will return a proxy wrapper around the original media object, that includes support for the new Async APIs.\nLet’s look at an example:\nimport static com.codename1.media.MediaManager.*; import com.codename1.media.*; //... boolean playPending, playing; // ... AsyncMedia media = getAsyncMedia(createMedia(mediaUrl, false)); playPending = true; media.playAsync().ready(m-\u0026gt;{ playPending = false; Playing = true; }).except(ex-\u0026gt;{ playPending = false; Dialog.show(\u0026quot;Failed to play\u0026quot;, \u0026quot;Failed to play media: \u0026quot;+ex.getMessage(), \u0026quot;OK\u0026quot;, null); }); media.addMediaStateChangeListener(evt-\u0026gt;{ Playing = (evt.getNewState() == State.Playing); }); This code is a complete example of how you can keep track of the playing state of your media. It keeps track of both whether there is a play request pending, and whether it is currently playing. Technically you don’t need to keep your own variable for keeping track of the the \u0026ldquo;playing\u0026rdquo; state, as you can just call media.isPlaying(), or media.getState() at any time. I use a separate playing variable here just to illustrate how to synchronize your application state with the state of your media.\nHow it works playAsync() returns a PlayRequest object, which is a subclass of AsyncResource\u0026lt;Media\u0026gt;. Its \u0026ldquo;ready\u0026rdquo; callback will be executed once playing has begun. The \u0026ldquo;except\u0026rdquo; callback will be called if playback fails due to an error.\nYou can also use the mediaStateChangeListeners of the AsyncMedia object to keep track of changes to state. Whenever the media starts playing, or stops playing, it will fire one of these events.\nThe new pauseAsync() method works similarly.\nCheck out the AsyncMediaSample sample in the Samples project for a full working example that makes use of playAsync().\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/media-async-play-and-pause-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/media-async-play-and-pause-support/new-features-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve recently released a few updates to our Media APIs in order to support a wider variety of use cases. One of these upgrades is the new \u003ccode\u003eAsyncMedia\u003c/code\u003e interface, which includes async play and pause support.\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003eMedia\u003c/code\u003e interface has always had \u003ccode\u003eplay()\u003c/code\u003e and \u003ccode\u003epause()\u003c/code\u003e methods, but it didn’t provide an easy way to detect when they had taken effect. On most platforms, this hasn’t been a major issue because the delay between when \u003ccode\u003eplay()\u003c/code\u003e is called, and when the media \u003cstrong\u003eactually\u003c/strong\u003e starts playing is small, or negligible. But our Javascript port presented some new challenges due to strict browser permissions surrounding media playback. In some cases, which I’ll discuss in detail in my next blog post, the user will be prompted to provide permission to play audio, or access the microphone, when \u003ccode\u003eplay()\u003c/code\u003e is called. This means that the delay between \u003ccode\u003eplay()\u003c/code\u003e and when the media actually starts playing may be significant.\u003c/p\u003e","title":"Async Play and Pause Support"},{"content":"\nIn my last post I introduced the new CN.invokeWithoutBlocking() method as a means of ensuring that your UI construction code doesn’t run into any \u0026ldquo;blocking\u0026rdquo; that could negatively affect user experience. In cases where you need to perform a network request to help build your UI, I offered some recommendations for moving blocking code out of the critical paths. One recommended pattern was to insert placeholder content into your components, which you replace with the actual data once it has been received from the server. That pattern goes something like:\nForm f = new Form(\u0026quot;Hello\u0026quot;, BoxLayout.y()); Label nameLabel = new Label(); nameLabel.setText(\u0026quot;placeholder\u0026quot;); AsyncResource\u0026lt;MyData\u0026gt; request = fetchDataAsync(); request.ready(data -\u0026gt; { nameLabel.setText(data.getName()); f.revalidateWithAnimationSafety(); }); f.add(nameLabel); f.show(); The concept here is that, the fetchDataAsync() method is performing an asynchronous network request in the background but returns an AsyncResource object immediately which will be notified when the response if received. Therefore, the contents of the ready( data → {…​}) block are executed some time after the form has already been built and shown.\nThis solved a significant user experience problem, in that the form can be shown to the user immediately without waiting for the network request to complete. However, it introduced a new problem, which is that our nameLabel is displaying placeholder text for some period of time before it is replaced with the actual data.\nTo help solve this problem, I have added some new progress animations that are specifically designed to be used as placeholders while a component’s data is being loaded. These animations include methods for easily swapping themselves with other components while they are loading, and then seamlessly swapping back once the component is finished loading. Currently there are two ProgressAnimation classes:\nCircleProgress – A circle that progressively draws itself then erases itself. This is a variation on the classic infinite progress animation, but it is more flexible than the built-in InfiniteProgress class.\nLoadingTextAnimation – This animation appears to be a paragraph of text that is being typed progressively one word at a time – except instead of words, it just renders filled rectangles. This is useful for indicating that a block of text is loading.\nExample using CircleProgress Form f = new Form(\u0026quot;Hello\u0026quot;, new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE)); Form prev = CN.getCurrentForm(); Toolbar tb = new Toolbar(); f.setToolbar(tb); tb.addCommandToLeftBar(\u0026quot;Back\u0026quot;, null, evt-\u0026gt;{ prev.showBack(); }); Label nameLabel = new Label(); $(nameLabel).setAlignment(CENTER); nameLabel.setText(\u0026quot;placeholder\u0026quot;); f.add(BorderLayout.CENTER, nameLabel); // Replace the label by a CircleProgress to indicate that it is loading. CircleProgress.markComponentLoading(nameLabel) .getStyle().setFgColor(0xff0000); AsyncResource\u0026lt;MyData\u0026gt; request = fetchDataAsync(); request.ready(data -\u0026gt; { nameLabel.setText(data.getName()); // Replace the progress with the nameLabel now that // it is ready, using a fade transition CircleProgress.markComponentReady(nameLabel, CommonTransitions.createFade(300)); }); f.show(); And the result looks like:\nYour browser does not support the video tag.\nExample Using LoadingTextAnimation Form f = new Form(\u0026quot;Hello\u0026quot;, new BorderLayout(BorderLayout.CENTER_BEHAVIOR_SCALE)); Form prev = CN.getCurrentForm(); Toolbar tb = new Toolbar(); f.setToolbar(tb); tb.addCommandToLeftBar(\u0026quot;Back\u0026quot;, null, evt-\u0026gt;{ prev.showBack(); }); SpanLabel profileText = new SpanLabel(); profileText.setText(\u0026quot;placeholder\u0026quot;); f.add(BorderLayout.CENTER, profileText); // Replace the label by a CircleProgress to indicate that it is loading. LoadingTextAnimation.markComponentLoading(profileText); AsyncResource\u0026lt;MyData\u0026gt; request = fetchDataAsync(); request.ready(data -\u0026gt; { profileText.setText(data.getProfileText()); // Replace the progress with the nameLabel now that // it is ready, using a fade transition LoadingTextAnimation.markComponentReady(profileText, CommonTransitions.createFade(300)); }); f.show(); And the result looks like:\nYour browser does not support the video tag. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — February 8, 2020 at 7:21 am (permalink) Francesco Galgani says:\nThank you Steve!\nWhat is the utility of CommonProgressAnimations.EmptyAnimation?\nSteve Hannah — February 10, 2020 at 12:49 pm (permalink) Steve Hannah says:\nSometimes you may just want to hide a component until its data is properly loaded, but you don’t want to show any visual animation. That’s when EmptyAnimation is useful.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/data-loading-placeholders/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/data-loading-placeholders/new-features-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIn my last post I introduced the new \u003ccode\u003eCN.invokeWithoutBlocking()\u003c/code\u003e method as a means of ensuring that your UI construction code doesn’t run into any \u0026ldquo;blocking\u0026rdquo; that could negatively affect user experience. In cases where you need to perform a network request to help build your UI, I offered some recommendations for moving blocking code out of the critical paths. One recommended pattern was to insert placeholder content into your components, which you replace with the actual data once it has been received from the server. That pattern goes something like:\u003c/p\u003e","title":"Using Component Placeholders While Loading Data"},{"content":"\nWe recently added support for disabling invokeAndBlock() for certain sections of code. The syntax is:\nCN.invokeWithoutBlocking(()-\u0026gt;{ // This code is not allowed to call invokeAndBlock() }); If any attempt is made to execute invokeAndBlock() inside that block of code, it will throw a BlockingDisallowedException.\nThis can be useful for ensuring that your UI will be responsive, especially in cases where you’re building a new form to show to the user, and any delay will be noticed by the user.\nFor example:\nButton btn = new Button(\u0026quot;Show Details\u0026quot;); btn.addActionListener(evt-\u0026gt;{ DetailsForm form = new DetailsForm(); form.show(); }); The intention is that the user presses the \u0026ldquo;Show Details\u0026rdquo; button, and they are shown some sort of details form. But what if, somewhere in the construction of the DetailsForm, there is a call to invokeAndBlock()? A common reason for this is if a network call is performed during the building of the form. For example:\nDetailsModel model = loadDetailsFromServer(); // A synchronous call to the server nameField.setText(model.getName()); ... That loadDetailsFromTheServer() is a synchronous call to the server, so it uses invokeAndBlock() to be able to \u0026ldquo;block\u0026rdquo; control flow without actually blocking the EDT. It’s great that it doesn’t block the EDT, but it still blocks our ability to deliver the details form that the user is expecting. The form won’t be built until after the network request complete, then the user will experience a short delay before transitioning to the new form.\nA better way is to build and show the DetailsForm, perform an asynchronous network request, and then update the details form with the data received when the network request completes. E.g.\nloadDetailsFromServerAsync().ready(model-\u0026gt;{ nameField.setText(model.getName()); revalidateWithAnimationSafety(); }); An easy fix in this simple case. But in the real world apps are much more complex. Calls to invokeAndBlock() may be nested deep within your app, or its libraries, so it may not be easy to ensure that the DetailsForm can be created without blocking.\nThis is where invokeWithoutBlocking() comes in handy. Let’s wrap our form creation to make sure that it doesn’t get bogged down by a slow network request.\nButton btn = new Button(\u0026quot;Show Details\u0026quot;); btn.addActionListener(evt-\u0026gt;{ CN.invokeWithoutBlocking(()-\u0026gt;{ DetailsForm form = new DetailsForm(); form.show(); }); }); This is guaranteed to show the form instantly, or it will throw a BlockingDisallowedException. This may be useful, especially during development, to help you hunt down those pesky network requests to get them out of your way. You can also catch these exceptions in order to provide an alternate path in the case that you can’t build the form without blocking.\nButton btn = new Button(\u0026quot;Show Details\u0026quot;); btn.addActionListener(evt-\u0026gt;{ try { CN.invokeWithoutBlocking(()-\u0026gt;{ DetailsForm form = new DetailsForm(); form.show(); }); } catch (BlockingDisallowedException ex) { showAlternateForm(); } }); Background: When to Block the EDT Synchronous programming is easier to write and understand than asynchronous programming. You can follow the flow of the code line by line, knowing that line n is run after line n-1, and before line n+1. The problem with synchronous programming is that it causes problems for long-running tasks on threads that can never block. Threads like the event dispatch thread (EDT), which is where most application code runs since it is the only thread that is authorized to interact with the UI. Codename One’s invokeAndBlock() method is a nifty tool which allows you to \u0026ldquo;block\u0026rdquo; the current event dispatch, without blocking any other event dispatches. Other events and callSerially blocks will continue to be processed while this event is blocked.\nThis allows us to do cool things like:\nMyData data = loadSomeDataFromTheServer(); updateUIWithMyData(data); This can be run directly on the EDT without blocking it because events will continue to be delivered and processed while the single event dispatch that is running this code is waiting for the data to be retrieved from the server. In most cases, this is much more elegant than callbacks, promises, or workers. It is easier to write, and easier to understand.\nHowever, there is a cost to using invokeAndBlock(). It still blocks the current dispatch, which can be problematic in certain contexts. E.g. What if we block the pointer-press dispatch. This might cause components to receive the corresponding pointer-release before the pointer-press – which is counter-intuitive.\nI generally try to avoid using invokeAndBlock() directly inside event handlers like action events or pointer events, because you could be getting in the way of other event handlers that are relying on the order events. E.g., Instead of:\nbutton.addActionListener(evt-\u0026gt;{ doSomethingWithBlockingCode(); }); Prefer:\nbutton.addActionListener(evt-\u0026gt;{ CN.callSerially(evt-\u0026gt;{ doSomethingWithBlockingCode(); }); }); This way it will only block the contents of that particular callSerially() dispatch. The action event dispatch (which is probably running inside a pointer pressed or pointer release dispatch) can continue to be delivered to other listeners unimpeded.\nI also try to avoid blocking while constructing user interface components to show the user. Usually when I create a form, I want to create it now to show the user instantly.\nYou can also use callSerially() in this case to prevent the blocking.\nE.g.\nclass MyForm extends Form { public MyForm() { ... myLabel.setText(\u0026quot;Some placeholder\u0026quot;); callSerially(()-\u0026gt;{ MyData data = loadMyDataFromServer(); myLabel.setText(data.getSomeString()); revalidateWithAnimationSafefy(); } } } Conclusion invokeAndBlock() is a great tool for simplifying control flow, but in some circumstances, using it can negatively impact the user experience. Two places where invokeAndBlock() should be avoided is during the construction of UI forms to display to the user, and directly inside an event handler. In some cases you can mitigate the cost of invokeAndBlock() by simply wrapping it in a callSerially() (e.g. inside an event handler) so that it doesn’t block the current event. When constructing a UI component like a form, you can use invokeWithoutBlocking() to provide guarantees that your code doesn’t block, and be sure that the user will be shown your form without delay. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDurank — December 4, 2019 at 8:52 pm (permalink) Durank says:\ncan I used this code to avoid stopping my infinite rotating image animation while I paint others components in the screen?\nSteve Hannah — December 5, 2019 at 6:37 pm (permalink) Steve Hannah says:\nAre you referring to the InfiniteProgress.showInfiniteBlocking() method, or your own custom animation that you’ve made? In either case it probably wouldn’t be affected by this.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/invoke-without-blocking/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/invoke-without-blocking/new-features-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe recently added support for disabling \u003ccode\u003einvokeAndBlock()\u003c/code\u003e for certain sections of code. The syntax is:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eCN.invokeWithoutBlocking(()-\u0026gt;{\n      // This code is not allowed to call invokeAndBlock()\n});\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIf any attempt is made to execute \u003ccode\u003einvokeAndBlock()\u003c/code\u003e inside that block of code, it will throw a \u003ccode\u003eBlockingDisallowedException\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThis can be useful for ensuring that your UI will be responsive, especially in cases where you’re building a new form to show to the user, and any delay will be noticed by the user.\u003c/p\u003e","title":"When You Cannot Afford to Block the EDT"},{"content":"\nI haven’t blogged in a while. I’ve been busy working with a couple of startups, some enterprise customers and bringing new people on-board. Steve has been great in picking up some of the slack but his plate is too full to blog with the same frequency I had so the blog slowed down a bit during this time. I hope to pick it back up to a weekly post regiment but my schedule is just so tight I barely have time to breath.\nThe good news is that we’re expanding a bit and recently hired a much needed graphics designer to overhaul everything around here with a new coat of paint. Steve and I spent a lot of time with him and we’re super excited about this!\nWe’ve also made some hirings in the development area which I’m pretty bullish about, hopefully they will turn out nicely too!\nLocation Regression Over the weekend we had a hard time with the location API on Android. In fact we had that last weekend too and we eventually reverted last weeks release to the one from the prior week. This week we pushed through and hopefully we resolved the issues. However, if you’re experiencing issues with the location API please let us know ASAP.\nThe reason behind this is the usual flurry with Google. They keep changing the behavior of devices with every API update. This is very problematic for applications that rely on background location, as such it forced us to update to play services version 12.0.0 which caused a cascade of issues across the board. Unfortunately this is inevitable as Google requires updates to newer versions for app submissions.\nVersion 7.0 We postponed version 7.0 multiple times by now and I still don’t see how we’ll make the current deadline which is set to Christmas eve of all dates…​ I’m afraid we’ll need to push that back again with our current rate of progress, hopefully our additional developer resources will help us align more closely to these schedules in the future. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nBoniface Githinji — November 25, 2019 at 9:43 am (permalink) Boniface Githinji says:\nGreat progress Shai. Happy to hear that you are finally getting a graphic designer. A tool that was already great now will become even better.\nCh Hjelm — November 28, 2019 at 1:29 pm (permalink) Ch Hjelm says:\nGraphics designer, great, great news. Probably what will have the biggest impact on promoting CN1. Want to share any thoughts in what his top prio tasks will be? I’d put really nice, fully developed (all components covered, every detail fine-tuned to ‘Apple level’) themes, so truly beautiful out of the box. And we’ll structured so easy to customize fonts, text size, colors themes etc. And available in CSS as « best practice » examples 🙂\nShai Almog — November 29, 2019 at 3:04 am (permalink) Shai Almog says:\nI very much agree with that but some of that work (e.g. best practices and CSS examples) is something we need to do. I’m still thinking about the best way to represent CSS snippets/solutions for common UI designs.\nCh Hjelm — April 18, 2020 at 7:26 am (permalink) Ch Hjelm says:\nHi Shai, any updates on the business front you can share? It is obvious that something has changed (eg fewer blog posts), so it’d be great to hear news directly ‘from the horse’s mouth’\nShai Almog — April 18, 2020 at 7:52 am (permalink) Shai Almog says:\nHi,\nnot much has changed. I made an experiment a year or so ago of blogging daily because I wanted to check if it had a business impact.\nIt didn’t.\nI reduced it to weekly blogging in 2020 but I don’t always have inspiration so I blog even less.\nWe’re working hard on the new website, hopefully when that’s up we’ll also have more energy for that. Ideally we’ll have more personal time too when our environment better adopts to covid.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/updates-expansion/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/updates-expansion/generic-java-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI haven’t blogged in a while. I’ve been busy working with a couple of startups, some enterprise customers and bringing new people on-board. Steve has been great in picking up some of the slack but his plate is too full to blog with the same frequency I had so the blog slowed down a bit during this time. I hope to pick it back up to a weekly post regiment but my schedule is just so tight I barely have time to breath.\u003c/p\u003e","title":"Updates and Expansion"},{"content":"\nWe recently added a new tool to the\nCodename One simulator that will allow you to run arbitrary code\nsnippets in your app’s runtime environment. You can access\nit from \u0026ldquo;File\u0026rdquo; \u0026gt; \u0026ldquo;Groovy Console\u0026rdquo;, while your app is running in\nthe simulator.\nThis will open the following dialog\nthat will allow you to execute arbitrary Groovy code:\nAs you may suspect, you should use\nthe Groovy programming language in this console. If you’re\nnot familiar with Groovy, don’t worry. The language is\nbasically just Java with some nice short-cuts. In fact, in\nmany cases, you can probably just write Java code, and it will\nstill work. Personally, I like the way that Groovy lets you\nrefer to object properties via their property name, so you don’t\nneed to use the getter or setter methods explicitly. E.g. You\ncan do \u0026ldquo;form.title\u0026rdquo;, instead of \u0026ldquo;form.getTitle()\u0026rdquo;, to get the\nform’s title. The former is converted into the latter\nautomatically for you.\nFirst Example: Getting the Current form’s title\nAs a simple first example, let’s get\nthe current form’s title and print the value in the console.\nThe default content in the console already has a reference to the\ncurrent form via the \u0026ldquo;form=CN.currentForm\u0026rdquo; line. So all we\nneed to do is add:\nThen press \u0026ldquo;Command-Enter\u0026rdquo; (or\nCtrl-Enter on Windows/Linux\u0026quot;), to see the output. You should\nsee something like the following in the bottom-half of the\nconsole:\nSecond Example: Showing a Dialog:\nYou can also interact with the UI.\nCreate forms, components, dialogs – or essentially create\nentire apps. Below, you can see us displaying a simple dialog\ndirectly in the console.\nUsing the ComponentSelector\nMy most frequent uses of the console\nis to find out the properties on some component in the UI.\nFor this sort of thing, the ComponentSelector class is an\ninvaluable tool. It makes it easy to find the components that\nyou’re interested in, and to inspect its state.\nFor example, we might want to look\nat the font height of all instances of the Label class on the\ncurrent form:\nThe above example demonstrates some\nfundamentals of both Groovy, and of the ComponentSelector\nclass.\n$(‘*’, form) – This creates a set\nof all components in the current form. \u0026ldquo;*\u0026rdquo; matches\nall. .filter{ ..} – This method\nfilters the set so that only the components for which the closure\nreturns true are included. Notice the convenient\nnotation for a closure in Groovy: { .. }. And it\nprovides you with the implicit variable \u0026ldquo;it\u0026rdquo; which refers to the\nparameter in a single-parameter method closure. .each{…} – Allow you to execute\ncode on \u0026ldquo;each\u0026rdquo; element in the set. Again, we use the\nconvenient closure notation and implicit \u0026ldquo;it\u0026rdquo; object provided by\nGroovy. Useful for Troubleshooting Requests\nOne potential area where the console\nmay have some powerful uses, is in the area of trouble-shooting and\nbug reporting. If a developer asks the community for help in\ndebugging a problem in their app it is now possible for community\nmembers to share snippets that might help to diagnose the problem.\nIt was already possible to share snippets, but the console\nmakes it easier to provide advice like: \u0026ldquo;When you get to the\npart of your app that is having the problem, try running this\nsnippet of code inside the console, and let me know what the output\nis\u0026rdquo;.\nVersus Debugging in the IDE\nIt is worth noting that you could\nalready inspect the runtime state of your app using your IDE\ndebugger. You can pause the app, then evaluate arbitrary Java\nexpressions to see their output. You can Add break-points,\nand even make source code changes that are applied seamlessly at\nruntime. The console is not meant to replace this\nfunctionality. It is meant to provide a slightly\nlighter-weight approach to achieve many of the same things.\nYou’ll have to find your own usage\npatterns, but I have found that it is handy to be able to just open\nup a console, whether or not my app is being run in \u0026ldquo;Debug\u0026rdquo; mode,\nand start tinkering with some code to get a clearer picture of what\nis going on inside my app.\nShare Your Snippets\nI’ve only posted a couple of simple\nexamples of how you might use the console, but the sky is the\nlimit. Please share your own snippets and tips if you\ndiscover any tricks that might be helpful to other users. You\ncan share them below in the comments.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/runtime-debugging-with-groovy-console/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/runtime-debugging-with-groovy-console/new-features-5.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe recently added a new tool to the\u003cbr\u003e\nCodename One simulator that will allow you to run arbitrary code\u003cbr\u003e\nsnippets in your app’s runtime environment. You can access\u003cbr\u003e\nit from \u0026ldquo;File\u0026rdquo; \u0026gt; \u0026ldquo;Groovy Console\u0026rdquo;, while your app is running in\u003cbr\u003e\nthe simulator.\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/blog/runtime-debugging-with-groovy-console/image3.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThis will open the following dialog\u003cbr\u003e\nthat will allow you to execute arbitrary Groovy code:\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/blog/runtime-debugging-with-groovy-console/image5.png\"\u003e\u003c/p\u003e\n\u003cp\u003eAs you may suspect, you should use\u003cbr\u003e\nthe Groovy programming language in this console. If you’re\u003cbr\u003e\nnot familiar with Groovy, don’t worry. The language is\u003cbr\u003e\nbasically just Java with some nice short-cuts. In fact, in\u003cbr\u003e\nmany cases, you can probably just write Java code, and it will\u003cbr\u003e\nstill work. Personally, I like the way that Groovy lets you\u003cbr\u003e\nrefer to object properties via their property name, so you don’t\u003cbr\u003e\nneed to use the getter or setter methods explicitly. E.g. You\u003cbr\u003e\ncan do \u0026ldquo;form.title\u0026rdquo;, instead of \u0026ldquo;\u003ccode\u003eform.getTitle()\u003c/code\u003e\u0026rdquo;, to get the\u003cbr\u003e\nform’s title. The former is converted into the latter\u003cbr\u003e\nautomatically for you.\u003c/p\u003e","title":"Runtime Debugging with Groovy Console"},{"content":"\nWe still have features to cover from our summer vacation but we need to make a short de-tour through newer things that landed recently. One of the big highlights is the switch to WKWebView. We effectively changed the default iOS browser component to WKWebView instead of UIWebView. This resolved warnings Apple started sending out to developers about using the out of date UIWebView.\nThis mostly went unnoticed by most developers as it should. But if your browser starts acting up this is the reason. There isn’t much we can do here as we knew that day would come where Apple will demand a switch.\nVideo Library Francesco Galgani created an impressive cn1lib for low level video access named \u0026ldquo;VideoOptimizer\u0026rdquo;.\nIt supports compressing video files for distribution, grabbing video frame screenshots, getting the duration of a video etc.\nThis is pretty cool and also a pretty difficult task as it involved integrating the ffmpeg native library in an Android build with an AAR to package the whole thing.\nReleasableComponent ramsestom implemented a generic interface for releasable components in PR #2910. Before this Codename One had special cases for Button so if a user pressed a button and didn’t release it we made sure to let the button know about this at some point…​\nThis is now generic via the new ReleasableComponent (named IReleasable in the PR which was renamed in the following commit).\nPopup Direction and Mime Guessing Francesco Galgani submitted two PRs. First #2914 which lets you explicitly set the auto complete popup direction e.g.:\nautoComplete.setPopupPosition(AutoCompleteTextField.POPUP_POSITION_OVER); Valid values are: POPUP_POSITION_AUTO, POPUP_POSITION_OVER and POPUP_POSITION_UNDER.\nThe second PR #2925 includes an API to guess common file mime types from the first few bytes of a file. Using Util.guessMimeType e.g.:\nString mimeType = Util.guessMimeType(fileOrStorageFile); Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDurank — October 22, 2019 at 8:54 pm (permalink) Durank says:\nhi, In download the video library and I refresh my cn1 libs but the class VideoOptimizer isn’t imported. Please hel me.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/wkwebview-prs/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/wkwebview-prs/new-features-5.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe still have features to cover from our summer vacation but we need to make a short de-tour through newer things that landed recently. One of the big highlights is the switch to \u003ca href=\"/blog/wkwebview/\"\u003eWKWebView\u003c/a\u003e. We effectively changed the default iOS browser component to \u003ccode\u003eWKWebView\u003c/code\u003e instead of \u003ccode\u003eUIWebView\u003c/code\u003e. This resolved warnings Apple started sending out to developers about using the out of date \u003ccode\u003eUIWebView\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThis mostly went unnoticed by most developers as it should. But if your browser starts acting up this is the reason. There isn’t much we can do here as we knew that day would come where Apple will demand a switch.\u003c/p\u003e","title":"WKWebView and PRs"},{"content":"\nPush support is one of the most complicated features to set up, due to all of the red tape you have to cut through on each platform. Each platform has its own series of hurdles you have to jump through. Apple (iOS) requires you to generate push certificates. Google (Android) requries you to set up a project in Firebase console. Microsoft requires you to register your app for the Windows store. And that’s just the beginning.\nOur developer’s guide provides detailed instructions on how to perform each of these steps to get up and running, but it is quite verbose. If you’ve already gone through the guide to setup push for your first app, you may not require quite such a detailed guide to help you with your 2nd app. If you’re like me, you just want a birds-eye view of what is required to get push working, and not necessarily a step-by-step tutorial on how to meet those requirements.\nSo…​ I have created a Push Cheatsheet, to serve as a quick reference for setting up push notifications in your mobile apps.\nAs with all CN1 docs, this cheatsheet is a living document that will evolve based on your feedback. You can always download the latest PDF at https://www.codenameone.com/files/push-cheatsheet.pdf .\nI have tried to include all of the pertinent details required to get Push working on all platforms. Each platform has its own \u0026ldquo;box\u0026rdquo; with setup instructions. It also includes a minimal code snippet to show how to implement Push support in your codename one app – in particular how to register the device for push, and receive push messages. There is a box for \u0026ldquo;Sending a Push\u0026rdquo;, which shows the format of an HTTP request that you can use to send a push message to your app’s users.\n__ GET parameters in this snippet are color-coded and cross-referenced with other parts of the cheatsheet so you can easily see where to find this information. E.g. The FCM_SERVER_API_KEY in the HTTP request is purple and bold, corresponding to its mention in the \u0026ldquo;Android Client Setup\u0026rdquo; box, so you can see that this value comes from the google firebase console. Finally, there is a section documenting the different push message type values, so you can quickly decide which type of push is appropriate for a given situation.\nPlease let us know if you can think of anything that would improve the utility of this cheatsheet.\nHappy pushing!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/push-cheatsheet/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/push-cheatsheet/push-megaphone.png\"\u003e\u003c/p\u003e\n\u003cp\u003ePush support is one of the most complicated features to set up, due to all of the red tape you have to cut through on each platform. Each platform has its own series of hurdles you have to jump through. Apple (iOS) requires you to generate push certificates. Google (Android) requries you to set up a project in Firebase console. Microsoft requires you to register your app for the Windows store. And that’s just the beginning.\u003c/p\u003e","title":"Push Cheatsheet"},{"content":"\nThis is the 3rd installment of the updates we did over the summer and so far it isn’t the last one. We have at least one more part coming in next week…​\nTerse Table Layout TableLayout is pretty darn verbose e.g. this snippet from the TableLayout JavaDoc:\ncnt.add(tl.createConstraint(). horizontalSpan(2). heightPercentage(80). verticalAlign(Component.CENTER). horizontalAlign(Component.CENTER), new Label(\u0026quot;Span H\u0026quot;)). add(new Label(\u0026quot;BBB\u0026quot;)). add(tl.createConstraint(). widthPercentage(60). heightPercentage(20), new Label(\u0026quot;CCC\u0026quot;)); This is pretty verbose and a bit painful to write so we added shorthand methods:\nvs() = verticalSpan()\nhs() = horizontalSpan()\nwp() = widthPercentage()\nhp() = heightPercentage()\nha() = horizontalAlign()\nva() = verticalAlign()\ncc() = constraint()\nAs such we can rewrite the snippet above as such:\ncnt.add(tl.cc(). hs(2). hp(80). va(Component.CENTER). ha(Component.CENTER), new Label(\u0026quot;Span H\u0026quot;)). add(new Label(\u0026quot;BBB\u0026quot;)). add(tl.cc(). wp(60). hp(20), new Label(\u0026quot;CCC\u0026quot;)); RadarChart David Day contributed new support for RadarChart in this pull request. You can check out a sample of the radar chart in the samples. Specifically:\npublic void showChart() { Form f = new Form(\u0026quot;RadarChartSample\u0026quot;, new BorderLayout()); f.add(BorderLayout.CENTER, getSampleChart()); f.show(); } ChartComponent getSampleChart(){ // Create dataset AreaSeries dataset = new AreaSeries(); CategorySeries series1 = new CategorySeries(\u0026quot;May\u0026quot;); series1.add(\u0026quot;Health\u0026quot;, 0.8); series1.add(\u0026quot;Attack\u0026quot;, 0.6); series1.add(\u0026quot;Defense\u0026quot;, 0.4); series1.add(\u0026quot;Critical\u0026quot;, 0.2); series1.add(\u0026quot;Speed\u0026quot;, 1.0); dataset.addSeries(series1); CategorySeries series2 = new CategorySeries(\u0026quot;Chang\u0026quot;); series2.add(\u0026quot;Health\u0026quot;, 0.3); series2.add(\u0026quot;Attack\u0026quot;, 0.7); series2.add(\u0026quot;Defense\u0026quot;, 0.5); series2.add(\u0026quot;Critical\u0026quot;, 0.1); series2.add(\u0026quot;Speed\u0026quot;, 0.3); dataset.addSeries(series2); // Setup renderer DefaultRenderer renderer = new DefaultRenderer(); renderer.setLegendTextSize(32); renderer.setLabelsTextSize(24); renderer.setLabelsColor(ColorUtil.BLACK); renderer.setShowLabels(true); SimpleSeriesRenderer r1 = new SimpleSeriesRenderer(); r1.setColor(ColorUtil.MAGENTA); renderer.addSeriesRenderer(r1); SimpleSeriesRenderer r2 = new SimpleSeriesRenderer(); r2.setColor(ColorUtil.CYAN); renderer.addSeriesRenderer(r2); // Create chart return new ChartComponent(new RadarChart(dataset,renderer)); } Networking Enhancements Better Error Code Handling Up until recently if we got an error response code it wasn’t sent through the global error handler and was handled via the local error handling chain first. This is no longer the case and these errors are now handled correctly.\nHowever, if you relied on that misbehavior of older versions we have\nsetHandleErrorCodesInGlobalErrorHandler(boolean). This defaults to true, you can set it to false to change the default behavior.\nNetwork Monitor Stats Network monitor now has stats for time duration etc. You can see these by opening the network monitor and inspecting the values:\nFigure 1. Network Monitor Enhancements\nData Interface The Data interface can be used to abstract data that has size and can be appended to an OutputStream. This is very handy for providing large amounts of data for processing, so that the data itself doesn’t need to be passed around. This interface should be used in a few places in the API to facilitate working with large data objects, such as for file uploads.\nE.g. For multi-part file uploads the best way to deal with large objects right now is to store them in a file, and then provide the file path to the connection request, so that the platform’s native implementation can chunk or stream it appropriately.\nThis interface provides potentially a cleaner more generic way to pass large amounts of data to a connection request.\nThe main entry point for this functionality is ConnectionRequest.setRequestBody(Data data). The interface itself is pretty trivial and contains two methods:\npublic interface Data { /** * Appends the data's content to an output stream. * @param output The output stream to append to. * @throws IOException */ public void appendTo(OutputStream output) throws IOException; /** * Gets the size of the data content. * @return Size of content in bytes. * @throws IOException */ public long getSize() throws IOException; } Within the interface there are several concrete implementations specifically StringData,\nFileData, StorageData and ByteData. E.g.:\npublic static class StringData implements Data { private byte[] bytes; public StringData(String str) { this(str, \u0026quot;UTF-8\u0026quot;); } public StringData(String str, String charset) { try { bytes = str.getBytes(charset); } catch (UnsupportedEncodingException ex) { Log.e(ex); throw new RuntimeException(\u0026quot;Failed to create StringData with encoding \u0026quot;+charset); } } @Override public void appendTo(OutputStream output) throws IOException { output.write(bytes); } @Override public long getSize() throws IOException { return bytes.length; } } This makes things such as working with files in Storage (as opposed to FileSystemStorage) easier.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/terse-table-radar-chart-networking/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/terse-table-radar-chart-networking/new-features-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is the 3rd installment of the updates we did over the summer and so far it isn’t the last one. We have at least one more part coming in next week…​\u003c/p\u003e\n\u003ch3 id=\"terse-table-layout\"\u003eTerse Table Layout\u003c/h3\u003e\n\u003cp\u003e\u003ccode\u003eTableLayout\u003c/code\u003e is pretty darn verbose e.g. this snippet from the \u003ca href=\"/javadoc/com/codename1/ui/table/TableLayout/\"\u003eTableLayout JavaDoc\u003c/a\u003e:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003ecnt.add(tl.createConstraint().\n        horizontalSpan(2).\n        heightPercentage(80).\n        verticalAlign(Component.CENTER).\n        horizontalAlign(Component.CENTER),\n            new Label(\u0026quot;Span H\u0026quot;)).\n\n    add(new Label(\u0026quot;BBB\u0026quot;)).\n\n    add(tl.createConstraint().\n        widthPercentage(60).\n        heightPercentage(20),\n            new Label(\u0026quot;CCC\u0026quot;));\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis is pretty verbose and a bit painful to write so we added shorthand methods:\u003c/p\u003e","title":"Terse Table, Radar Chart and Networking Enhancements"},{"content":"\nAs I mentioned in the last post there are a lot of new features we need to go over and it will take time to cover everything. In fact this is still a partial list and there’s a lot more on the way…​\nEasier Icon Font Integration First off Thomas submitted a PR for a few new font icon methods:\nSpecifically in Label he added:\npublic void setFontIcon(Font font, char c); public void setFontIcon(Font font, char c, float size); And in FontImage he added:\npublic static void setFontIcon(Label l, Font font, char icon, float size); public static void setFontIcon(Label l, Font font, char icon); public static void setFontIcon(Command c, Font font, char icon, String uiid, float size); These new methods work in a similar way to the set material icon methods. However, they can work with an arbitrary icon font. That was possible to do before this change but this change makes that easier and makes the code more fluid. It also works similarly to the material API where icons are implicitly applied to all the states of the buttons. That means the pressed/selected/disabled styles will apply to the icon as well as the text.\nAdditional Icon Fonts Francesco Galgani came up with a solution for #2421 which finally allowed us to update the material font and font constants.\nThis has been a long time RFE which came up every few months. When we launched the material font support. Unfortunately, Google stopped updating that font a few years ago and everyone who relied on it was stuck. Thankfully Francesco found an up to date version of the font as well as the diffs between the old/new font.\nAs a result we now have a lot more constants you can use when setting an icon in a default Codename One app. You can see the full list here.\nLightweight Popup Dialog When Codename One was young we needed a popup arrow implementation but our low level graphics API was pretty basic. As a workaround we created a version of the 9-piece image border that supported pointing arrows at a component.\nSince we added a proper graphics pipeline we wanted to rewrite that logic to use proper graphics. This allows for better customization of the border (color, shape etc.) and it looks better on newer displays. It also works on all OSs. Right now only the iOS theme has the old image border approach.\nTo solve this we added new support for arrows into the RoundRectBorder API. If you style a popup dialog with a round rect border this should \u0026ldquo;just work\u0026rdquo; and use this API. By default popup dialogs are styled that way with the exception of iOS where they still have the image border styling for compatibility (although we might change that).\nThis works by setting the track component property on border. When that’s done the border implicitly points to the right location.\nContinue the Infinite InfiniteContainer and InfiniteAdapter work great for most use cases but they have a bit of an \u0026ldquo;undefined\u0026rdquo; behavior when it comes to failure. E.g. if we have a network error and don’t have anything to fetch as a result.\nto solve this we added this method to InfiniteContainer:\npublic void continueFetching(); And these to InfiniteScrollAdapter:\npublic void continueFetching(); public static void continueFetching(Container cnt); So when you get an error you can just add this error button and return null:\nSpanButton errorButton = new SpanButton(\u0026quot;Networking Error, Press to retry\u0026quot;); errorButton.addActionListener(e -\u0026gt; { errorButton.remove(); continueFetching(); }); add(errorButton); return null; The error button will let the user retry the operation and continue fetching the content even though it was previously \u0026ldquo;stopped\u0026rdquo;.\nMore Coming As I mentioned at the top of this post, this is still the tip of the iceberg of new features we’ve worked on over the summer. More is coming! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — September 14, 2019 at 8:23 am (permalink) Francesco Galgani says:\nI’ve just tested that a Popup Dialog works fine also with an Android skin, thank you! About the Popup Dialog, isn’t the developer guide section \u0026ldquo;Styling The Arrow Of The Popup Dialog\u0026rdquo; more valid? Should this part of the developer guide be changed? Link: https://www.codenameone.com…\nShai Almog — September 15, 2019 at 3:44 am (permalink) Shai Almog says:\nThanks, I updated that.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/icon-fonts-popups-infinite-scroll/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/icon-fonts-popups-infinite-scroll/new-features-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAs I mentioned in the last post there are a lot of new features we need to go over and it will take time to cover everything. In fact this is still a partial list and there’s a lot more on the way…​\u003c/p\u003e\n\u003ch3 id=\"easier-icon-font-integration\"\u003eEasier Icon Font Integration\u003c/h3\u003e\n\u003cp\u003eFirst off \u003ca href=\"https://github.com/ThomasH99\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eThomas\u003c/a\u003e \u003ca href=\"https://github.com/codenameone/CodenameOne/issues/2856\" target=\"_blank\" rel=\"noopener noreferrer\"\u003esubmitted a PR\u003c/a\u003e for a few new font icon methods:\u003c/p\u003e\n\u003cp\u003eSpecifically in \u003ccode\u003eLabel\u003c/code\u003e he added:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003epublic void setFontIcon(Font font, char c);\npublic void setFontIcon(Font font, char c, float size);\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eAnd in \u003ccode\u003eFontImage\u003c/code\u003e he added:\u003c/p\u003e","title":"Icon Fonts, Popups and Infinite Scroll"},{"content":"\nSummer is finally over and the kids are going back to school/kindergarten so it’s time to go back to our regularly scheduled posts. I won’t be posting as often as before as I’ll dedicate more time for support/development activities but still there’s a lot to write about…​\nDuring our time off we had a lot of changes, I’ll repeat a few big ones which you might have run into already and cover a few that might have gone under the radar.\nGCM Removal and FCM as Default During the month of August Google finally removed their old GCM servers. We’ve prepared for this ages ago but this still took us a bit off guard. We were ready for the switch itself but there were still a couple of things we weren’t prepared for.\nUsers who still used the old style of push notifications (prior to the google-services.json file approach) had push messages blocked. That was expected.\n__ You can read about the modern approach to push here Because that no longer works anyway we switched the default build mode to FCM. This solves an issue for developers who neglected to define the android.messagingService=fcm build hint (which you no longer need). However, this causes a build error if you don’t have that JSON file in place. You can get this to compile for now by explicitly stating the build hint android.messagingService=gcm. However, push won’t work if you do that since the Google run GCM push servers are no longer there. But it will compile which is a start.\nTo migrate to the new FCM approach check out the developer guide section on push.\nAPI Level 28 and HTTPS Requirement We migrated the build servers to Android API level 28 as required by Google. This migration was a bit painful because Google changed the way clipping works under Android so we had to make some extensive changes to our rendering pipeline.\nHowever, one thing we can’t mitigate is that Google now blocks HTTP connections (not HTTPS).This is generally a good practice and a requirement on iOS as well. However, if you have an HTTP URL you need to use you can do so with the build hint:\nandroid.xapplication_attr=android:usesCleartextTraffic=\u0026quot;true\u0026quot; Component Inspector Enhancements We implemented a couple of RFEs in the venerable component inspector, specifically 2695 and 1476.\nYou can now refresh the component tree and the selection would remain in place but more importantly you can select a component and it will be highlighted in the UI. This is very helpful as a debugging tool.\nFigure 1. Component inspector highlights current selection\nAutoCompleteTextComponent and TextComponentPassword Francesco Galgani contributed an implementation of\nAutoCompleteTextComponent which allows you to use an auto-complete with the text component framework for a more fluid input UI.\nHe also contributed TextComponentPassword which is a password field with the same convention. It carries the more modern \u0026ldquo;show password\u0026rdquo; icon convention which is far more convenient than the old \u0026ldquo;double type\u0026rdquo; approach.\nError Callbacks for URLImage It’s hard to handle errors in URLImage objects. Because they are so \u0026ldquo;seamless\u0026rdquo; the point for exception handling is deep withing the class. To solve issue 2703 we had to do something different.\nYou can now use the static method setExceptionHandler on URLImage. It accepts the inner interface ErrorCallback which has a single method:\npublic static interface ErrorCallback { public void onError(URLImage source, Exception err); } So effectively you can do something like this:\nURLImage.setExceptionHandler((img, err) -\u0026gt; handleError()); So Much More I’ll write about other things in the coming weeks as this post is getting a bit long. There’s a lot to cover. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — September 7, 2019 at 7:57 pm (permalink) The Component Inspector enhancements are very helpful! Thank you very much!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/back-vacation/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/back-vacation/new-features-6.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSummer is finally over and the kids are going back to school/kindergarten so it’s time to go back to our regularly scheduled posts. I won’t be posting as often as before as I’ll dedicate more time for support/development activities but still there’s a lot to write about…​\u003c/p\u003e\n\u003cp\u003eDuring our time off we had a lot of changes, I’ll repeat a few big ones which you might have run into already and cover a few that might have gone under the radar.\u003c/p\u003e","title":"We're Back from Vacation"},{"content":"\nYou might have noticed we’ve been a bit slow with updates over the past couple of weeks as we’re dealing with a bit of a backlog. With the kids on holiday from school it’s harder to keep up not to mention our travel plans for the summer. As such we’re officially in summer vacation until September.\nDuring this time we won’t update the blog as that takes a bit too much. We will probably have Friday releases if warranted but this depends on commits. It will take us longer to evaluate some issues but we’ll still try to respond to everyone in a reasonable timeframe.\nPro and enterprise support might be impacted as well due to personnel availability but should still provide fast response turnaround.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/summer-vacation/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/summer-vacation/generic-java-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eYou might have noticed we’ve been a bit slow with updates over the past couple of weeks as we’re dealing with a bit of a backlog. With the kids on holiday from school it’s harder to keep up not to mention our travel plans for the summer. As such we’re officially in summer vacation until September.\u003c/p\u003e\n\u003cp\u003eDuring this time we won’t update the blog as that takes a bit too much. We will probably have Friday releases if warranted but this depends on commits. It will take us longer to evaluate some issues but we’ll still try to respond to everyone in a reasonable timeframe.\u003cbr\u003e\nPro and enterprise support might be impacted as well due to personnel availability but should still provide fast response turnaround.\u003c/p\u003e","title":"Summer Vacation"},{"content":"\nBrowserComponent is a pretty powerful tool when you just want to integrate HTML into your application. We use it a lot in native apps, but surprisingly it’s just as useful when we compile an app as a web application. It lets us embed HTML into the web application. But there’s a big caveat known as SOP when we do that.\nSOP and CORS SOP is the \u0026ldquo;Same Origin Policy\u0026rdquo; enforced by browsers. It’s prevents CSRF (Cross Site Request Forgery) which essentially lets a site pretend it’s a different site.\nSOP makes sure all requests to the site come from the same origin, it’s enforced by the browser and essentially blocks manipulations across domains. This sounds great but if you need to communicate between two sites it might be a problem. That’s where CORS comes in.\nCORS (Cross Origin Resource Sharing) is essentially the SOP compliant way for a website to communicate with a different website. There are HTTP headers you need to add etc. I won’t go into it as there are better resources on all of this.\nPost Message So lets say we have a browser component from a different domain embedded in our app. Normally in a native app that’s no problem. We can inject JavaScript into it and do whatever we want.\nHowever with the JavaScript port this becomes a bit of an issue because of SOP. postMessage makes the communication between the two origins possible but to get it to work you need to have code that handles sends the messages on both sides.\nFor this we now have the following API’s in BrowserComponent:\npublic void postMessage(String message, String targetOrigin); __ This API will work correctly in native apps as well so you can still enjoy portability This method Calls the postMessage() method on the webpage’s window object.\nTo receive a message, the web page should register a \u0026ldquo;message\u0026rdquo; event listener, just as it would to receive messages from other windows in the browser. See MDN docs for postMessage() for more information.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/post-message/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/post-message/html5-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eBrowserComponent\u003c/code\u003e is a pretty powerful tool when you just want to integrate HTML into your application. We use it a lot in native apps, but surprisingly it’s just as useful when we compile an app as a web application. It lets us embed HTML into the web application. But there’s a big caveat known as SOP when we do that.\u003c/p\u003e\n\u003ch3 id=\"sop-and-cors\"\u003eSOP and CORS\u003c/h3\u003e\n\u003cp\u003eSOP is the \u0026ldquo;Same Origin Policy\u0026rdquo; enforced by browsers. It’s prevents CSRF (Cross Site Request Forgery) which essentially lets a site pretend it’s a different site.\u003c/p\u003e","title":"Post Message"},{"content":"\nA couple of years ago I wrote about our support for Flamingo which translates static SVG files to Java source files that you can treat as images within Codename One while getting pixel perfect resolution independent results. There were a few minor changes since until a month ago when Steve committed some work to address this RFE.\nWhat’s SVG and Why Should I Care?\nIf you’re new to SVG here’s a quick primer. There are two types of images: Vector and Raster. Raster is what most of us work with every day. They are our JPEG, GIF, BMP and PNG images. They store the pixels of the image. There are many nuances here but I’ll leave it at that…​\nVector images are something completely different. Instead of storing the pixels they store the primitive drawing operations. If we have an image of a triangle, a raster image will store a lot of pixel values representing the triangle whereas a vector image would just store the fact that a triangle is drawn at a specific size in a given coordinate.\nVector images work great for images that were designed to be vector images e.g. logos, drawings etc. They are useless for things such as photos. They have a couple of big advantages:\nThey are smaller than raster images both on disk and more importantly in RAM\nThey can scale to any size with no degradation in image quality, this is very helpful for mobile apps\nBut surprisingly they might not perform as well as a raster image for all cases. This might be offset by the RAM savings so I’d still recommend SVG for most cases.\nFlamingo works by translating SVG’s to Java source code that you can compile in Codename One. This means more elaborate features such as SVG animations are discarded as part of the process. It also means some SVG’s just won’t work. With the new update we added support for a lot of SVG’s and also updated the flamingo binary distribution which we didn’t have in the original project.\nThe recent changes include both improvement to the translation process and to the Codename One API. Our updated API now supports features such as paint and gradient drawing which is commonly used in SVG. Specifically Steve added a Paint interface, with concrete subclass LinearGradientPaint that can be used to fill a shape with a gradient via Graphics.setColor(Paint) then Graphics.fillShape(shape). There are quite a few other related changes such as MultipleGradientPaint and AffineTransform…​\nWith these in place you can convert a lot of typical SVG’s and use them in your app. The big question is whether we’ll integrate this deeper into Codname One by automating this process. Right now we’re not sure about that or how such integration will look. Maybe something similar to the CSS integration. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDurank — September 16, 2020 at 2:48 pm (permalink) Durank says:\nhow can I use svg image in code using flamingo? I have found some examples but without success\nShai Almog — September 17, 2020 at 4:10 am (permalink) Shai Almog says:\nThey are just images. Instead of loading it you create a class instance and use it as an image.\n\u0026ldquo; Image img = new SvgImage(); \u0026quot;\nDurank — October 20, 2020 at 3:06 pm (permalink) Durank says:\nhow can I to reference my image.svg?\nShai Almog — October 21, 2020 at 2:09 am (permalink) Shai Almog says:\nYou just create a new instance of the generated Java source image. It’s an Image. There’s no SVG anymore.\nDurank — October 21, 2020 at 3:23 pm (permalink) Durank says:\nplease provide an example. I never have worked with svg in codenameone.\nShai Almog — October 22, 2020 at 10:47 am (permalink) Shai Almog says:\nThere’s no example. You just create an instance of the generated class. It’s a subclass of Image so acts as an image.\nYou can see sample usage here: https://github.com/codenameone/flamingo-svg-transcoder/\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/flamingo-svg-transcoder-revisited/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/flamingo-svg-transcoder-revisited/uidesign.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA couple of years ago I wrote about our support for \u003ca href=\"/blog/flamingo-svg-transcoder.html\"\u003eFlamingo\u003c/a\u003e which translates static SVG files to Java source files that you can treat as images within Codename One while getting pixel perfect resolution independent results. There were a few minor changes since until a month ago when Steve committed some work to address this \u003ca href=\"https://github.com/codenameone/CodenameOne/issues/2797\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRFE\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eWhat’s SVG and Why Should I Care?\u003c/p\u003e\n\u003cp\u003eIf you’re new to SVG here’s a quick primer. There are two types of images: Vector and Raster. Raster is what most of us work with every day. They are our JPEG, GIF, BMP and PNG images. They store the pixels of the image. There are many nuances here but I’ll leave it at that…​\u003c/p\u003e","title":"Flamingo SVG Transcoder Revisited"},{"content":"\nOver the years we wrote a lot of demos for Codename One as well as a lot of test cases. This can get painful after a few dozen projects each of which with their own version of the JARs and build script. To solve this never ending need to organize samples Steve introduced a new samples folder into the open source project.\nThis makes it easy to build/run samples if you’re command line inclined. All you need is an install of Java and Ant to be in business. Steve introduced this quite a while back but it took a while to reach a critical mass of samples which it recently passed. By now the samples cover a lot of the functionality of Codename One. There’s a lot of documentation for the samples folder here so I won’t go too much into details. I will however refine a few steps in the getting started process…​\nTo run the samples you need to checkout the git cn1 project then do the following in the project root directory:\nant samples __ JAVA_HOME must point at a valid JDK for Codename One and ant must by in the system PATH variable. Otherwise this won’t work. Figure 1. The Sample Runner App\nIt doesn’t look pretty but you can run a sample for almost any Codename One component and see the applicable code. You can send device builds etc. This is a very convenient system for test cases.\nSheet As such the samples contain a sample for the new Sheet API which you can see here. This is it, there is no need for resources or anything, the file is self contained.\nSheet is a new API that lets you show the property sheet UI common in iOS and recently on Android as well. It was easy to do this in the past but there was no dedicated class to address it…​ Now there is.\nFigure 2. The Sheet Sample Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — June 8, 2019 at 10:42 pm (permalink) The \u0026ldquo;More -\u0026gt; Launch JS\u0026rdquo; option opens the url \u0026ldquo;http://localhost:40549/\u0026rdquo;. Do you have integrated a web server in this Codename One Samples? Just a curiosity, which server is it?\nShai Almog — June 9, 2019 at 3:49 am (permalink) It’s tomcat. The web target in the build XML file lets you do that.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/sheets-samples/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/sheets-samples/new-features-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOver the years we wrote a lot of demos for Codename One as well as a lot of test cases. This can get painful after a few dozen projects each of which with their own version of the JARs and build script. To solve this never ending need to organize samples Steve introduced a new samples folder into the open source project.\u003c/p\u003e\n\u003cp\u003eThis makes it easy to build/run samples if you’re command line inclined. All you need is an install of Java and Ant to be in business. Steve introduced this quite a while back but it took a while to reach a critical mass of samples which it recently passed. By now the samples cover a lot of the functionality of Codename One. There’s a lot of documentation for the samples folder \u003ca href=\"https://github.com/codenameone/CodenameOne/tree/master/Samples\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere\u003c/a\u003e so I won’t go too much into details. I will however refine a few steps in the getting started process…​\u003c/p\u003e","title":"Sheets and Samples"},{"content":"\nA month ago Francesco asked how to implement the common image cropping UI we see in many applications where the user can pan and zoom to decide the cropping area. We implemented that feature by effectively enhancing the ImageViewer class with two new methods:\npublic Image getCroppedImage(int backgroundColor); public Image getCroppedImage(int width, int height, int backgroundColor); But that’s just the first step, implementing the whole UI is still not trivial. We’d like to add a more general purpose component that does that but doing this with an approach that’s sufficiently generic is hard…​\nFrancesco wrote some code that used the API but it was still non-trivial. So I took that code as a starting point and implemented something that’s slightly more generic, it still isn’t perfect but it should be a good starting point for a more general purpose component.\nSince this uses the ImageViewer you can use pinch to zoom and drag to position the image the way you want:\nprivate void cropImage(Image img, int destWidth, int destHeight, OnComplete\u0026lt;Image\u0026gt; s) { Form previous = getCurrentForm(); Form cropForm = new Form(\u0026quot;Crop your avatar\u0026quot;, new LayeredLayout()); Label moveAndZoom = new Label(\u0026quot;Move and zoom the photo to crop it\u0026quot;); moveAndZoom.getUnselectedStyle().setFgColor(0xffffff); __**(1)** moveAndZoom.getUnselectedStyle().setAlignment(CENTER); moveAndZoom.setCellRenderer(true); cropForm.setGlassPane((Graphics g, Rectangle rect) -\u0026gt; { g.setColor(0x0000ff); g.setAlpha(150); __**(2)** Container cropCp = cropForm.getContentPane(); int posY = cropForm.getContentPane().getAbsoluteY(); GeneralPath p = new GeneralPath(); __**(3)** p.setRect(new Rectangle(0, posY, cropCp.getWidth(), cropCp.getHeight()), null); if(isPortrait()) { p.arc(0, posY + cropCp.getHeight() / 2 - cropCp.getWidth() / 2, cropCp.getWidth() - 1, cropCp.getWidth() - 1, 0, Math.PI*2); } else { p.arc(cropCp.getWidth() / 2 - cropCp.getHeight() / 2, posY, cropCp.getHeight() - 1, cropCp.getHeight() - 1, 0, Math.PI*2); } g.fillShape(p); g.setAlpha(255); g.setColor(0xffffff); moveAndZoom.setX(0); moveAndZoom.setY(posY); moveAndZoom.setWidth(cropCp.getWidth()); moveAndZoom.setHeight(moveAndZoom.getPreferredH()); moveAndZoom.paint(g); }); final ImageViewer viewer = new ImageViewer(); viewer.setImage(img); cropForm.add(viewer); cropForm.getToolbar().addMaterialCommandToRightBar(\u0026quot;\u0026quot;, FontImage.MATERIAL_CROP, e -\u0026gt; { previous.showBack(); s.completed(viewer.getCroppedImage(0). __**(4)** fill(destWidth, destHeight)); }); cropForm.getToolbar().addMaterialCommandToLeftBar(\u0026quot;\u0026quot;, FontImage.MATERIAL_CANCEL, e -\u0026gt; previous.showBack()); cropForm.show(); } __1 This label is drawn manually on top of the glass pane overlay __2 The glass pane highlights invisible portions although the cropped image in our case is still square, this is pretty common behavior as a UI will sometimes show the image rounded __3 This shape represents the blue tinted overlay on top The UI results in an image like this:\nFigure 1. The Crop UI on the Simulator\nTo get to that point we need the UI that invokes this code which looks like this:\nForm hi = new Form(\u0026quot;Cropped Image\u0026quot;, BoxLayout.y()); hi.getToolbar().addMaterialCommandToRightBar(\u0026quot;\u0026quot;, FontImage.MATERIAL_CAMERA, e -\u0026gt; { Capture.capturePhoto(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { if (evt == null || evt.getSource() == null) { // the user cancelled the image capturing return; } String file = (String) evt.getSource(); try { Image img = Image.createImage(file); cropImage(img, 256, 256, i -\u0026gt; { hi.removeAll(); hi.add(new ScaleImageLabel(i)); hi.revalidate(); }); } catch (IOException ex) { Log.p(\u0026quot;Error loading captured image from camera\u0026quot;, Log.ERROR); Log.e(ex); } } }); }); hi.show(); Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — May 29, 2019 at 5:08 pm (permalink) Thank you Shai 🙂\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/photo-cropping-wizard/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/photo-cropping-wizard/uidesign.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA month ago \u003ca href=\"https://github.com/codenameone/CodenameOne/issues/2778\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFrancesco asked\u003c/a\u003e how to implement the common image cropping UI we see in many applications where the user can pan and zoom to decide the cropping area. We implemented that feature by effectively enhancing the \u003ccode\u003eImageViewer\u003c/code\u003e class with two new methods:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003epublic Image getCroppedImage(int backgroundColor);\npublic Image getCroppedImage(int width, int height, int backgroundColor);\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eBut that’s just the first step, implementing the whole UI is still not trivial. We’d like to add a more general purpose component that does that but doing this with an approach that’s sufficiently generic is hard…​\u003c/p\u003e","title":"Photo Cropping Wizard"},{"content":"\nThere are a lot of fixes and new features that I don’t get to cover enough as I’ve been busy on several fronts. One of the new features is support for asynchronous media API’s. These let us create a media object without waiting for it to complete. This is very useful if you have a complex UI and want to play a media file while doing other things.\nE.g. if you’re scrolling in a social network feed and want to play a media preview. You might create a media object but don’t want it to block the current call. You can do this using code such as:\nAsyncResource\u0026lt;Media\u0026gt; async = Display.getInstance().createMediaAsync(URL_TO_MEDIA, isVideo, null); async.ready(mediaInstance -\u0026gt; playMedia(mediaInstance)); You will notice the usage of AsyncResource which is similar to a future or a promise in other platforms. It lets you monitor the status of an asynchronous approach. This block would execute quickly but the playMedia call would happen when loading is completed.\nRendering Hints One of the API’s I dislike in JavaSE is the Graphics2D rendering hints. It’s a bit opaque in the choices it exposes. I want fast and good looking graphics but the tradeoff isn’t always clear. How much would I \u0026ldquo;pay\u0026rdquo; for good looking in this case in terms of speed and visa versa.\nNow we also have one rendering hint in our graphics:\ngraphics.setRenderingHints(Graphics.RENDERING_HINT_FAST); I’m not too crazy about the name as it’s a bit misleading. I’m sure developers would just turn it on to make everything \u0026ldquo;go fast\u0026rdquo; then complain when it has no impact…​ It doesn’t do that.\nOnly iOS uses this and even then only when rendering images. Since copying images to textures is expensive, we keep the last generated texture cached. This works well if we are always rendering the image at the same size. If we are constantly rendering the same image at different sizes, then we’ll constantly be invalidating the cache, this results in artifacts. This affected pinch zoom in the image viewer causing it to be choppy as it had to regenerate a texture for every change in size. When Fast rendering is enabled, we now only invalidate the texture cache if the image is larger or smaller than the existing texture by more than a factor of 2.\nThis change also fixed a bug that caused images to be rendered as black if they are larger than the max OGL texture size. Now it will cap the size of the texture at the max OGL size, and it will use the GPU to scale the texture to the desired size.\nUppercase TextArea now supports a new UPPERCASE constraint which lets you request uppercase input. Generally it will just popup the keyboard with the capslock on. You can use it as such:\ntextFieldOrArea.setConstrainer(TextArea.UPPERCASE); Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/asynchronous-media/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/asynchronous-media/new-features-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThere are a lot of fixes and new features that I don’t get to cover enough as I’ve been busy on several fronts. One of the new features is support for asynchronous media API’s. These let us create a media object without waiting for it to complete. This is very useful if you have a complex UI and want to play a media file while doing other things.\u003c/p\u003e","title":"Asynchronous Media"},{"content":"Learn more about Codename One and getting started resources.\nWhat is Codename One? Codename One allows Java developers to write their mobile apps using Java or Kotlin. It generates native OS binaries that you can upload to Apple/Google/Microsoft etc.\nCodename One was founded by ex-Sun/Oracle mobile developers based on an open source project started back in 2007 within Sun Microsystems. The core vision of Codename One is to actualize the WORA (Write Once Run Anywhere) mantra of Java in the age of mobile devices.\nTo enable that vision Codename One created a one of a kind industry leading set of tools that allow Java developers to build native mobile OS applications with a single code base.\nCodename One works with all major Java developer environments (IDE\u0026rsquo;s) NetBeans, Eclipse, IntelliJ/IDEA or VSCode.\nhttps://youtu.be/rl6z7DD2-vg\nHow does Codename One work? To understand how Codename One works, its history etc. check the developer guide (also available as a PDF). It provide a birds eye view in the first chapter.\nYou can also refer to this stackoverflow answer. There is a video that goes into further details here (it\u0026rsquo;s a bit long).\nThe gist of this is that Codename One requires you to obey some restrictions in the way you develop Java applications and use our plugin/API. Once you abide by those the Codename One tooling makes portability seamless.\nHow do Codename One Apps Look? They can look like anything, check out the demos section where you can see the diversity and some of the potential of Codename One apps.\nIs Codename One Free? Codename One has a free version and paid versions. So yes \u0026amp; no.\nThe base product is open source but our build system requires servers (Macs, Windows machines etc.) and we place a quota on their usage to prevent overuse which would deprive paying users from service.\nWith the free version, there is a JAR size limit of 1 - 8.5mb. Notice that this is a very high limit as it applies only to your bytcode and not to the Codename One builtin API\u0026rsquo;s and you can create pretty remarkable apps within this limit (all our demos fit within that limit).\nThe free tier allows you to use your generated apps commercially and place have no restrictions on them. There are no nag screens or license limitations!\nThere are many additional benefits and additional features you can get in the paid plans, see the pricing details here.\nWhere can I learn more? For more about Codename One check out this post covering the extensive set of tutorials/docs/videos.\nYou can ask questions in stackoverflow with the codenameone tag or you can also ask in the discussion forum. Our engineers guarantee a response within 24 hours for such questions.\nNotice that Codename One assumes you already know Java so we don\u0026rsquo;t have any tutorials for complete beginners. However, we do have some courses available at Codename One Academy.\n","permalink":"https://www.codenameone.com/about-us/","summary":"\u003cp\u003eLearn more about Codename One and getting started resources.\u003c/p\u003e\n\u003ch3 id=\"what-is-codename-one\"\u003eWhat is Codename One?\u003c/h3\u003e\n\u003cp\u003eCodename One allows Java developers to write their mobile apps using Java or Kotlin. It generates native OS binaries that you can upload to Apple/Google/Microsoft etc.\u003c/p\u003e\n\u003cp\u003eCodename One was founded by ex-Sun/Oracle mobile developers based on an open source project started back in 2007 within Sun Microsystems. The core vision of Codename One is to actualize the WORA (Write Once Run Anywhere) mantra of Java in the age of mobile devices.\u003c/p\u003e","title":"About Us - What is Codename One and how Does it work?"},{"content":"Transcript In this short video I\u0026rsquo;ll try to address one of the most challenging basic features of Codename One: Layouts\nBefore we go into the actual code let\u0026rsquo;s explain the basics. Codename One Components are arranged within Containers. A Container can contain an arbitrary number of components\nSince it derives from Component a Container can also Contain other Containers and so forth. By nesting these Containers one into another we can build any type of user interface\nThis begs the question: Why? Why not place the components where we want them to be on the screen?\nDevices can have different resolution, pixel density, font sizes and form factors. So a specific position that looks good on one device can look awful in another.\nWith device orientation changes, tablets, desktop/web versions of the app etc. You would expect the UI to adapt \u0026ldquo;automatically\u0026rdquo;. It gets worse with localization for instance languages like German have very long words and you would expect components to resize accordingly\nLayout managers convey the logic of component placement in a way that Codename One understands and can adapt e.g. Let\u0026rsquo;s say I want to say put a label on the left and put a text area next to it. I also want to give that text area the rest of the available space\nWe can do this in many ways but a common way would be to use a Border Layout. We can place the label in the WEST \u0026amp; the text field in the center\nThis can be abbreviated using this shorthand syntax so the initial container will have the east component\nAnd can be further abbreviated using this one line of code, this also brings us to one of the more important aspects of layout managers. Constraints.\nThere are two types of layout managers in Codename One, those that have component constraints and those that don’t. Border layout requires a constraint for every addition (like the center or east constraint we used), layouts like table layout can work without one but add it implicitly. Layouts like Box Layout don’t need a constraint at all.\nLet\u0026rsquo;s go over some of the layout managers at a high level using the kitchen sink demo to show them off\nFirst we have the flow layout which is the default layout manager in Codename One, it arranges components from left to right and gives each component its preferred size.\nFlow layout can be aligned to the left, center or right. Vertically it can be aligned to the top middle or the bottom of the available space. It implicitly breaks a line when it reaches the end of the line. This is a bit of a long discussion to get into but if you add complex/large components into flow layout it might fail as Codename One doesn’t reflow for performance reasons. You should be careful when using it for anything non-trivial.\nNext we have border layout that we discussed briefly, it can place components in the north (top), south (bottom), east (right), west (left) and center. Components placed in the north \u0026amp; south have their preferred height but are stretched to fill up available width. Likewise components placed in the east \u0026amp; west have their preferred width but stretch to fill up the available height.\nThe center component is a special case, it’s stretched to fill the available space. There is a special absolute center mode that allows it to be in the actual center based on the preferred size of the component. Border layout doesn’t make sense as a scrollable component since the behavior heavily depends on the fixed size of the available space. Hence it will implicitly disable scrolling when set to a Container or Form. We often use Border Layout for components that need to be sized explicitly such as Map or BrowserComponent as the center location makes sure to give them the available space.\nBox layout places components in a row or a column. When we place elements in Box X the row has the same height but the elements are given their preferred width. When we use Box Y elements occupy the available width but have their preferred height. This helps components align property on the given axis as they have the same size on that axis.\nGrid layout gives all the components the same size based on their preferred size and places them in rows/columns. This is useful for the icon grid style of user interface and also useful for button bars where you want all the elements to have the exact same size regardless of their text\nTable layout is more flexible, it’s very useful for input and forms. Table layout allows spanning columns or rows between table cells. It uses constraints to define behaviors of table elements.\nAnd finally Layered Layout places elements one on top of the other so we can do things like overlays. Here we set a bit of margin on each entry so the difference between the layers are clearer\nNow here is a neat trick to learn about components, open the component inspector on a UI and look within the hierarchy to see what we did for that specific hierarchy. You can also look at the code but that isn’t always clear… In the contacts section of the kitchen sink demo we can inspect the various elements and understand which layout was used for what purpose.\nWe have a layered layout for the root, this allows the floating action button on the bottom.\nA bit deeper we can see the Box Layout Y that contains all of the \u0026ldquo;Swipeable Container\u0026rdquo; classes,\nSwipeable container is a layered layout that we can swipe to show the buttons below\nThese buttons under the swipeable container use a grid layout so they can occupy the same size\nThe top component in the swipeable container is the multi button, this button is really just a border layout Container with text in the center and an icon label in the west!\nI could talk about layouts for another hour (and I will at a later date) but for now we’ll call this a day. Thanks for watching and I hope it was helpful\n","permalink":"https://www.codenameone.com/layout-basics/","summary":"\u003ch2 id=\"transcript\"\u003eTranscript\u003c/h2\u003e\n\u003cp\u003eIn this short video I\u0026rsquo;ll try to address one of the most challenging basic features of Codename One: Layouts\u003c/p\u003e\n\u003cp\u003eBefore we go into the actual code let\u0026rsquo;s explain the basics. Codename One Components are arranged within Containers. A Container can contain an arbitrary number of components\u003c/p\u003e\n\u003cp\u003eSince it derives from Component a Container can also Contain other Containers and so forth. By nesting these Containers one into another we can build any type of user interface\u003c/p\u003e","title":"Layout Basics"},{"content":"Pricing: Unlimited number of apps, no royalties, no restrictions! Simple Fair Transparent Pricing, 30 day money back guarantee you can cancel at any time\u0026hellip;\nHome Pricing Free $0/mo\ndiscussion forum within 24 hours typically.\u0026quot; data-original-title=\u0026quot;\u0026quot; title=\u0026quot;\u0026quot;\u0026gt;Community Support Royalty Free iOS Builds Android Builds Windows UWP Builds 1 - 8.5mb build jar size Sign Up\nBasic $19/mo\nUnlimited Build Credits Access To Native Sources 50mb build jar size Sign Up\nProfessional $70.75 Annually\n$79/mo\nPush Notification Crash Reporting Concurrent Builds Versioning (5 months) E-Mail Support Native Desktop Apps Sign Up (Monthly) Sign Up (Annually)\nEnterprise $316.6 Annually\n$399/mo\nin this tutorial.\u0026quot; data-original-title=\u0026quot;\u0026quot; title=\u0026quot;\u0026quot;\u0026gt;JavaScript App Generation Offline Builds High Priority Builds Versioning (18 months) Continuous Integration On Device Unit Tests Office Hours/Phone Support Sign Up (Monthly) Sign Up (Annually)\nPrices above are per developer seat and include multiple platforms with no royalties or hidden fees.\nFor a detailed pricing matrix and FAQ check out this page. Codename One provides 100% no questions asked 30 day money back guarantee for all purchases made via PayPal.\nPayment can be done using credit cards (thru PayPal) or via SWIFT bank transfers (and invoice) for annual accounts of pro grade or higher. To use the SWIFT invoicing/purchase order option just signup for a free account and click the right invoicing option within the subscription tab.\nBuild size restrictions relate to the size of the user JAR before compilation not the final app on which there is no such restriction.\nNotice you can increase the quotas for the builds by inviting your friends to use Codename One!\nPlease notice that accounts can\u0026rsquo;t be shared and must be uniform within the organization. E.g. a single company can\u0026rsquo;t have one developer in enterprise grade and another one in pro grade.\nPlease contact us for volume discounts by using the chat button on the bottom right of the page\n","permalink":"https://www.codenameone.com/mobile-app-development-cost-codename-one/","summary":"\u003ch1 id=\"pricing-unlimited-number-of-apps-no-royalties-no-restrictions\"\u003ePricing: Unlimited number of apps, no royalties, no restrictions!\u003c/h1\u003e\n\u003cp\u003eSimple Fair Transparent Pricing, 30 day money back guarantee you can cancel at any time\u0026hellip;\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003ePricing\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"free\"\u003eFree\u003c/h3\u003e\n\u003cp\u003e \u003c/p\u003e\n\u003cp\u003e$0/mo\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"#/\"\u003ediscussion forum\u003c/a\u003e within 24 hours typically.\u0026quot; data-original-title=\u0026quot;\u0026quot; title=\u0026quot;\u0026quot;\u0026gt;Community Support\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#/\"\u003eRoyalty Free\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#/\"\u003eiOS Builds\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#/\"\u003eAndroid Builds\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#/\"\u003eWindows UWP Builds\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#/\"\u003e1 - 8.5mb build jar size\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eSign Up\u003c/p\u003e\n\u003ch3 id=\"basic\"\u003eBasic\u003c/h3\u003e\n\u003cp\u003e \u003c/p\u003e\n\u003cp\u003e$19/mo\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"#/\"\u003eUnlimited Build Credits\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#/\"\u003eAccess To Native Sources\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#/\"\u003e50mb build jar size\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eSign Up\u003c/p\u003e\n\u003ch3 id=\"professional\"\u003eProfessional\u003c/h3\u003e\n\u003cp\u003e$70.75 Annually\u003c/p\u003e","title":"Mobile App Development Cost – Codename One"},{"content":"Terms Terms of service and privacy policy\nHome About Privacy Codename One doesn\u0026rsquo;t track users who aren\u0026rsquo;t logged in. However, we make use of 3rd party GDPR compliant services who do: Google Analytics \u0026amp; Crisp. In the past we used Intercom.. We maintain user data closely and make no commercial use of said data. User data is the property of the user and thus we don\u0026rsquo;t transfer it to 3rd parties in any way. We use the data strictly to provide our service and improve upon it.\nUse of Crisp Services: We use third-party analytics services to help understand your usage of our services. In particular, we provide a limited amount of your information (such as sign-up date and some personal information like your email address) to Crisp and utilize it to collect data for analytics purposes when you visit our website or use our product. As a data processor acting on our behalf, Crisp analyzes your use of our website and/or product and tracks our relationship by way of cookies and similar technologies so that we can improve our service to you. For more information on Crips use of cookies, please visit crisp.chat/en/privacy/. We may also use Crisp as a medium for communications, either through email, or through messages within our product(s). As part of our service agreements, Crisp collects publicly available contact and social information related to you, such as your email address, gender, company, job title, photos, website URLs, social network handles and physical addresses, to enhance your user experience. For more information on the privacy practices of Crisp. If you would like to opt out of having this information collected by or submitted to Crisp, please contact us. Notice that this will limit your ability to use some forms of support within the site.\nUse of Google Analytics: Google Analytics doesn\u0026rsquo;t collect any private information and doesn\u0026rsquo;t bind to user account data. No private data is tracked by analytics.\n","permalink":"https://www.codenameone.com/privacy-old/","summary":"\u003ch1 id=\"terms\"\u003eTerms\u003c/h1\u003e\n\u003cp\u003eTerms of service and privacy policy\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eAbout\u003c/li\u003e\n\u003cli\u003ePrivacy\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eCodename One doesn\u0026rsquo;t track users who aren\u0026rsquo;t logged in. However, we make use of 3rd party GDPR compliant services who do: Google Analytics \u0026amp; Crisp. In the past we used Intercom.. We maintain user data closely and make no commercial use of said data. User data is the property of the user and thus we don\u0026rsquo;t transfer it to 3rd parties in any way. We use the data strictly to provide our service and improve upon it.\u003c/p\u003e","title":"Privacy-old"},{"content":"\nThe Tabs class is pretty powerful and flexible as I mentioned before. One thing it doesn’t support is drag and drop to re-order the tabs. Here the flexibility of Codename One takes over and allows us to accomplish it.\nWe can use the builtin drag and drop support for components within the tabs container. This is exactly how the code below works. In the drop listener we block the the default processing of drop behavior so we can move the tab manually to the new location:\nForm hi = new Form(\u0026quot;Tabs\u0026quot;, new BorderLayout()); Tabs t = new Tabs(); t.addTab(\u0026quot;T1\u0026quot;, new Label(\u0026quot;Tab 1\u0026quot;)); t.addTab(\u0026quot;T2\u0026quot;, new Label(\u0026quot;Tab 2\u0026quot;)); t.addTab(\u0026quot;T3\u0026quot;, new Label(\u0026quot;Tab 3\u0026quot;)); t.addTab(\u0026quot;T4\u0026quot;, new Label(\u0026quot;Tab 4\u0026quot;)); Container tabsC = t.getTabsContainer(); tabsC.setDropTarget(true); for(Component c : tabsC) { c.setDraggable(true); c.addDropListener(e -\u0026gt; { e.consume(); Component dragged = c; int x = e.getX(); int y = e.getY(); int i = tabsC.getComponentIndex(dragged); if(i \u0026gt; -1) { Component dest = tabsC.getComponentAt(x, y); if(dest != dragged) { Component source = t.getTabComponentAt(i); int destIndex = tabsC.getComponentIndex(dest); if(destIndex \u0026gt; -1 \u0026amp;\u0026amp; destIndex != i) { String title = t.getTabTitle(i); t.removeTabAt(i); t.insertTab(title, null, source, destIndex); } } tabsC.animateLayout(400); } }); } hi.add(CENTER, t); hi.show(); Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nStefan Eder — May 16, 2019 at 10:06 am (permalink) Stefan Eder says:\nDragging and dropping a tab as in this example doesn’t feel right. Instead the tabs should make room while dragging and not move again into place when dropping. That way it would be much more natural.\nSee https://github.com/codename…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-reordering-tabs/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-reordering-tabs/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003eTabs\u003c/code\u003e class is pretty powerful and flexible as I \u003ca href=\"/blog/tip-customize-tabs-behavior/\"\u003ementioned before\u003c/a\u003e. One thing it doesn’t support is drag and drop to re-order the tabs. Here the flexibility of Codename One takes over and allows us to accomplish it.\u003c/p\u003e\n\u003cp\u003eWe can use the builtin drag and drop support for components within the tabs container. This is exactly how the code below works. In the drop listener we block the the default processing of drop behavior so we can move the tab manually to the new location:\u003c/p\u003e","title":"TIP: Reordering Tabs"},{"content":"\nText editing is implemented natively in Codename One. This provides a huge benefit as it allows us to ignore a lot of complex topics such as virtual keyboard localization etc. If we had to implement all that logic the overhead of Codename One would have been huge…​\nOne free benefit is seamless support for copy \u0026amp; paste. It \u0026ldquo;just works\u0026rdquo; thanks to the usage of the native widget we don’t need to worry about that UI. However, this breaks down when we want to provide the ability to select \u0026amp; copy without the ability to edit. E.g. in a web app we can usually select any bit of text and copy it…​ That’s convenient for some cases.\n__ A good example would be listing user details within the app that the user might want to copy e.g. his user ID As part of an RFE we added support for that through a lightweight copy mechanism, this works for uneditable TextAreas and TextFields. It will also work for Labels and SpanLabels. Notice that this is off by default you need to enable this using parentForm.getTextSelection().setEnabled(true). Even then it will only work for TextAreas and TextFields by default. You will need to explicitly enable it on other components using setTextSelectionEnabled(true).\nForm hi = new Form(\u0026quot;Tabs\u0026quot;, BoxLayout.y()); hi.getTextSelection().setEnabled(true); SpanLabel s = new SpanLabel(\u0026quot;Long label text that would still be selectable in this case\u0026quot;); s.setTextSelectionEnabled(true); hi.add(s); hi.show(); Figure 1. Lightweight Text Selection\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/lightweight-text-selection/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/lightweight-text-selection/new-features-5.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eText editing is implemented natively in Codename One. This provides a huge benefit as it allows us to ignore a lot of complex topics such as virtual keyboard localization etc. If we had to implement all that logic the overhead of Codename One would have been huge…​\u003c/p\u003e\n\u003cp\u003eOne free benefit is seamless support for copy \u0026amp; paste. It \u0026ldquo;just works\u0026rdquo; thanks to the usage of the native widget we don’t need to worry about that UI. However, this breaks down when we want to provide the ability to select \u0026amp; copy without the ability to edit. E.g. in a web app we can usually select any bit of text and copy it…​ That’s convenient for some cases.\u003c/p\u003e","title":"Lightweight Text Selection"},{"content":"\nThe native low level camera API on Android is a disaster. It’s often cited as one of the worst API’s on Android. To make matters worse there are two separate API’s Camera and Camera2 (yes really). You need to use Camera2 where it’s available but that means no support for older devices. To solve this we picked the Android Camera Kit library when we started building our low level camera support. This proved to be a mistake.\nCamera Kit was supposed to reach 1.0 status for about a year now. It constantly moved the goal posts and eventually moved the entire implementation to Android X which meant breaking compatibility on a large scale with existing code. After waiting endlessly for 1.0 we eventually tried to move to the latest beta but this proved unworkable due to the usage of Android X. So we decided to solve this by moving to Golden Eye. It’s a far simpler solution and as a result a stabler one.\n__ As I write this it looks like Camera Kit is moving towards 1.0 but it’s still unclear We still kept the name for the cn1lib which might breed some confusion so we’re open to suggestions here and might update it in the future.\nAs part of this overhaul we the library now supports the JavaScript port. It doesn’t support all the features but you should be able to get low level camera access in your web apps as well.\nThe nice thing is that the API is mostly unchanged. It can still be used with roughly the same API as we had before: https://github.com/codenameone/CameraKitDemo/ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nThomas McNeill — May 1, 2019 at 12:20 am (permalink) Thomas McNeill says:\nAwesome. Call it CameraKit2. I was trying to use it in the middle of the transition and was having issues. Glad it’s out now.\nDurank — May 3, 2019 at 5:03 pm (permalink) Durank says:\nhow can I launch camera in landscape with this api?\nShai Almog — May 4, 2019 at 4:43 am (permalink) Shai Almog says:\nForce landscape in the app using setPortait (this will work on Android only) then embed the camera in the form.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/camerakit-rewrite/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/camerakit-rewrite/camera-kit-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe native low level camera API on Android is a disaster. It’s often cited as one of the worst API’s on Android. To make matters worse there are two separate API’s \u003ccode\u003eCamera\u003c/code\u003e and \u003ccode\u003eCamera2\u003c/code\u003e (yes really). You need to use \u003ccode\u003eCamera2\u003c/code\u003e where it’s available but that means no support for older devices. To solve this we picked the Android Camera Kit library when we started building our low level camera support. This proved to be a mistake.\u003c/p\u003e","title":"Camera Kit Rewrite"},{"content":"\nA couple of years ago I posted a tip about rich text view which worked out reasonably well. But it’s a bit outdated by now and it’s worth revisiting. During these two years we published the Facebook Clone which used this component.\nIn the facebook clone I did a lot of work for the rich text. This work added support for alignment and clickable hyperlinks as well as a couple of bug fixes. Following is the code I used in the Facebook Clone for the rich text.\npublic class RichTextView extends Container { private String text; private float fontSize = 2.6f; private EventDispatcher listeners = new EventDispatcher(); private Font currentFont; private int currentColor = 0; private String currentLink; private Style lastCmp; private Font defaultFont; private Font boldFont; private Font italicFont; private int sizeOfSpace; public RichTextView() { init(null); } public RichTextView(String text, String uiid) { init(uiid); setText(text); } public RichTextView(String text) { init(null); setText(text); } private void init(String uiid) { boldFont = Font.createTrueTypeFont(NATIVE_MAIN_BOLD, fontSize); italicFont = Font.createTrueTypeFont(NATIVE_ITALIC_LIGHT, fontSize); if(uiid == null) { defaultFont = Font.createTrueTypeFont(NATIVE_MAIN_LIGHT, fontSize); } else { Style s = UIManager.getInstance().getComponentStyle(uiid); defaultFont = s.getFont(); boldFont = boldFont.derive(defaultFont.getHeight(), Font.STYLE_BOLD); italicFont = italicFont.derive(defaultFont.getHeight(), Font.STYLE_ITALIC); } sizeOfSpace = defaultFont.charWidth(' '); currentFont = defaultFont; } public void setAlignment(int align) { ((FlowLayout)getLayout()).setAlign(align); } private void createComponent(String t) { if(t.indexOf(' ') \u0026gt; -1) { for(String s : StringUtil.tokenize(t, ' ')) { createComponent(s); } return; } Label l; if(currentLink != null) { Button b = new Button(t, \u0026quot;Label\u0026quot;); final String currentLinkValue = currentLink; b.addActionListener(e -\u0026gt; listeners.fireActionEvent( new ActionEvent(currentLinkValue))); l = b; } else { l = new Label(t); } Style s = l.getAllStyles(); s.setFont(currentFont); s.setFgColor(currentColor); s.setPaddingUnit(Style.UNIT_TYPE_PIXELS); s.setPadding(0, 0, 0, sizeOfSpace); s.setMargin(0, 0, 0, 0); lastCmp = s; add(l); } public final void setText(String text) { this.text = text; removeAll(); try { char[] chrs = (\u0026quot;\u0026lt;body\u0026gt;\u0026quot; + text + \u0026quot;\u0026lt;/body\u0026gt;\u0026quot;).toCharArray(); new Parser().eventParser(new CharArrayReader(chrs)); } catch(IOException err) { log(err); } } public String getText() { return text; } public void addLinkListener(ActionListener al) { listeners.addListener(al); } public void removeLinkListener(ActionListener al) { listeners.removeListener(al); } class Parser extends XMLParser { @Override protected void textElement(String text) { if(text.length() \u0026gt; 0) { if(lastCmp != null \u0026amp;\u0026amp; text.startsWith(\u0026quot; \u0026quot;)) { lastCmp.setPadding(0, 0, 0, sizeOfSpace); } createComponent(text); if(!text.endsWith(\u0026quot; \u0026quot;)) { lastCmp.setPadding(0, 0, 0, 0); } } } @Override protected boolean startTag(String tag) { switch(tag.toLowerCase()) { case \u0026quot;a\u0026quot;: currentColor = 0x4267B2; break; case \u0026quot;b\u0026quot;: currentFont = boldFont; break; case \u0026quot;i\u0026quot;: currentFont = italicFont; break; } return true; } @Override protected void endTag(String tag) { currentColor = 0; currentLink = null; currentFont = defaultFont; } @Override protected void attribute( String tag, String attributeName, String value) { if(tag.toLowerCase().equals(\u0026quot;a\u0026quot;) \u0026amp;\u0026amp; attributeName.toLowerCase().equals(\u0026quot;href\u0026quot;)) { currentLink = value; } } @Override protected void notifyError(int errorId, String tag, String attribute, String value, String description) { log(\u0026quot;Error during parsing: \u0026quot; + tag); } } } Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDurank — September 30, 2020 at 12:19 pm (permalink) Durank says:\nPlease provide an example to use this class and its results\nShai Almog — October 1, 2020 at 6:38 am (permalink) Shai Almog says:\nThis is available in the post I linked above: \u0026lt;/blog/tip-lightweight-rich-text-view/\u0026gt;\n\u0026ldquo; hi.add(new RichTextView(\u0026quot;This is plain text **this is bold** and _this is italic_ and all of this breaks lines nicely as well….\u0026quot;)); \u0026quot;\nJulio Valeriron Ochoa — September 23, 2021 at 12:51 pm (permalink) Julio Valeriron Ochoa says:\nhow can I add a tag to set color to specific text?\nLianna Casper — September 23, 2021 at 4:27 pm (permalink) Lianna Casper says:\nJust like the a tag only instead of the href get the value of the color there.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-rich-view-revisited/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-rich-view-revisited/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA couple of years ago I posted a \u003ca href=\"/blog/tip-lightweight-rich-text-view/\"\u003etip about rich text view\u003c/a\u003e which worked out reasonably well. But it’s a bit outdated by now and it’s worth revisiting. During these two years we published the \u003ca href=\"https://codenameone.teachable.com/p/build-real-world-full-stack-mobile-apps-in-java\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFacebook Clone\u003c/a\u003e which used this component.\u003c/p\u003e\n\u003cp\u003eIn the facebook clone I did a lot of work for the rich text. This work added support for alignment and clickable hyperlinks as well as a couple of bug fixes. Following is the code I used in the Facebook Clone for the rich text.\u003c/p\u003e","title":"TIP: Rich View Revisited"},{"content":"\nA common pain point in most GUI frameworks is the hidden stack traces. When we have an app in production we get occasional emails from crash protection which are cryptic and hard to figure out. They usually start with the EDT loop and make no sense.\nThe reason for that is callSerially(). When we have code that invokes callSerially we essentially lose the previous stack trace. So your stack trace would look roughly like this:\njava.lang.RuntimeException: at com.mycompany.MyClass.myMethod(MyClass.java:400) at com.codename1.ui.Display.edtLoopImpl(Display.java:1166) at com.codename1.ui.Display.mainEDTLoop(Display.java:1070) at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120) at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176) For most cases you can just fix line 400 of MyClass so it won’t throw an exception but you might be hiding a worse bug. Lets say that line fails because it expects a specific condition to exist in the app and that condition isn’t met. A good example for this would be logged in users. Lets say your app expects the user to be logged in before myMethod is invoked but for some reason he isn’t.\nThat means the real bug occurred elsewhere probably in the area of code where callSerially() → myClass.myMethod(; was called. Lets say you looked over the entire body of code and you have suspects but can’t tell which part is at fault. Narrowing this down would help…​\nThat’s where Display.setEnableAsyncStackTraces() comes in. When set to true it creates a \u0026ldquo;fake\u0026rdquo; exception for every callSerially if there’s a \u0026ldquo;real\u0026rdquo; exception thrown within the callSerially it uses this \u0026ldquo;fake\u0026rdquo; one as the cause. That means you will be able to see the cause for a specific bug when this is enabled.\nNotice that this API is potentially prohibitive in terms of performance. As such we recommend that people don’t turn this on by default. You can include this as a user configuration or use it in debug builds. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — April 17, 2019 at 3:10 pm (permalink) Francesco Galgani says:\nIn the Javadoc of Display.getInstance().setEnableAsyncStackTraces(…);, it’s written: «Currently this is only supported in the JavaSE/Simulator port». Is it true? In that case, it’s not useful for crash reports…\nShai Almog — April 18, 2019 at 2:43 am (permalink) Shai Almog says:\nIt should work for desktop builds and Android as far as the code goes. Some platforms might fail because of the way stack traces are handled but I don’t see anything in the code that indicates this was actually enforced. It might not work everywhere e.g. on iOS.\nFrancesco Galgani — April 23, 2019 at 1:58 pm (permalink) Francesco Galgani says:\nThere is something strange, maybe you can help me to better understand the logic of setEnableAsyncStackTraces. Without setEnableAsyncStackTraces, I have a NullPointerException without any indication of the line of code that thrown the exception (so the log is useless), while with setEnableAsyncStackTraces(true) I have a com.codename1.ui.Display$EdtException, but in the log there is no mention of any NullPointerException, so it’s unclear where is the exception and why is there an exception.\nFrancesco Galgani — April 23, 2019 at 2:21 pm (permalink) Francesco Galgani says:\nI identified the cause of this exception, it was a popup.remove() (note\nthat \u0026ldquo;popup\u0026rdquo; and its parent weren’t null), however the solution that I\nfound is to use removeComponent (from the parent of the parent) instead\nof popup.remove(). It’s unclear to me the logic of this exception,\nhowever my question is the same: why does a NullPointerException become a\nDisplay$EdtException using setEnableAsyncStackTraces?\nShai Almog — April 23, 2019 at 4:55 pm (permalink) Shai Almog says:\nThis sounds like a bug in Codename One that triggered a cascading error.\nWhat’s popup? What type of component is it?\nFrancesco Galgani — April 23, 2019 at 5:57 pm (permalink) Francesco Galgani says:\nThis is the code: https://gist.github.com/jsf…\nAs you can see, I’m trying to adapt AutoCompleteTextField to my needs. Note at the bottom of the code the commented popup.remove(). I’m trying to close the popup list immediately when setEditable(false) is called. A safe and correct way to do it could fit with my use case, but maybe my code is not safe. Moreover, calling setEditable(true) after setEditable(false) causes that the popup list will not appear again when the user start typing in the field. I hope that few changes can fix this code. Do you have any suggestion? (I know that Stack Overflow is more suitable for this type of questions, however we started the discussion here. Thank you for your support)\nShai Almog — April 24, 2019 at 4:04 am (permalink) Shai Almog says:\nMaybe this is related to an ongoing animation which triggered this. That might explain the broken stack trace. It might be necessary to flush animations first for this method to work.\nFrancesco Galgani — April 24, 2019 at 6:20 am (permalink) Francesco Galgani says:\nYou’re right!!! Thank you! You gave me the right hint to solve half of this issue: the first half is what you supposed (that solved the issue in several cases), the second half was that an override of initComponent() and deinitalize() allowed me to solve the exception in other cases. This is my fixed code: https://gist.github.com/jsf…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/better-error-logging/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/better-error-logging/debugging.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA common pain point in most GUI frameworks is the hidden stack traces. When we have an app in production we get occasional emails from crash protection which are cryptic and hard to figure out. They usually start with the EDT loop and make no sense.\u003c/p\u003e\n\u003cp\u003eThe reason for that is \u003ccode\u003ecallSerially()\u003c/code\u003e. When we have code that invokes \u003ccode\u003ecallSerially\u003c/code\u003e we essentially lose the previous stack trace. So your stack trace would look roughly like this:\u003c/p\u003e","title":"Better Error Logging"},{"content":"\nSometimes you pick up a task and know in advance it’s going to be hell to implement it. Sometimes, the hell you were expecting turns out to be WAY worse than you anticipated. This is the case for modern Java desktop deployment. Amazingly, Java was able to take one of the worse deployment processes possible and make it MUCH worse than before.\nIf you haven’t used the Codename One desktop port I’ll sum it up to you. We use javapackager (formerly javafxpackager) to essentially wrap the jar file as a DMG/pkg on Mac OS and as an EXE/MSI on Windows. This \u0026ldquo;worked\u0026rdquo; in the broad sense of the word. It had a lot of issues and we had to create a lot of workarounds.\nHowever, Oracle effectively killed Java 8. This left us in a bind with an out of date VM that we need to maintain. Some Java advocates came out a while back with an open document claiming that \u0026ldquo;Java is still free\u0026rdquo;…​\nIf you think that a 23 page document explaining that something is \u0026ldquo;free\u0026rdquo; sounds problematic…​ Well, you have a point.\nZuluFX Unfortunately we need JavaFX. My opinion of JavaFX hasn’t changed, if anything I think it’s worse off than ever before. But in the Java world there is no other option. We need video, HTML and other capabilities for our simulator and desktop port so we need JavaFX support.\nLuckily, Azul releases a packaged OpenJDK distribution called ZuluFX which includes JavaFX within sparing us the need to package it ourselves. Unfortunately, basic things in javapackager just don’t work properly with Zulu. It seems it picks the full JDK instead of the JRE causing it to produce a 200mb hello world application. It doesn’t work at all on Windows and on Mac OS it’s remarkably flaky, it just fails on random.\nAfter struggling with this approach for a couple of weeks we gave up. Using javapackager is no longer a tenable approach so we’re using a manual approach of generating installers using 3rd party tools. Technically this is the same approach used by javapackager internally so this shouldn’t be too different, just a whole lot of more work for us.\nNew Build Hints This should land on the build servers tomorrow but this is highly experimental so I would suggest caution for at least a few weeks. It’s very likely compilation will fail for some builds right now as we’re ironing out the kinks. Still if you run into a problem let us know as we might not be aware of it.\nYou can use the build hints win.desktop-vm=zuluFx8 or mac.desktop-vm=zuluFx8 to hint that you want to use the Zulu VM instead of the default Oracle JRE. Once this becomes stable we might flip the switch and make this the default target moving forward as it gives us more control over the end result.\nAt the moment we only support unsigned EXE/DMG targets for this. Hopefully we’ll be able to address the full range of supported targets as we migrate to this approach.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/zulu-desktop-builds/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/zulu-desktop-builds/new-features-6.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSometimes you pick up a task and know in advance it’s going to be hell to implement it. Sometimes, the hell you were expecting turns out to be \u003cstrong\u003eWAY\u003c/strong\u003e worse than you anticipated. This is the case for modern Java desktop deployment. Amazingly, Java was able to take one of the worse deployment processes possible and make it \u003cstrong\u003eMUCH\u003c/strong\u003e worse than before.\u003c/p\u003e\n\u003cp\u003eIf you haven’t used the Codename One desktop port I’ll sum it up to you. We use \u003ccode\u003ejavapackager\u003c/code\u003e (formerly \u003ccode\u003ejavafxpackager\u003c/code\u003e) to essentially wrap the jar file as a DMG/pkg on Mac OS and as an EXE/MSI on Windows. This \u0026ldquo;worked\u0026rdquo; in the broad sense of the word. It had a lot of issues and we had to create a lot of workarounds.\u003c/p\u003e","title":"Zulu Desktop Builds"},{"content":"\nWhen we released Codename One 6.0 we mentioned that Codename One build is going through the approval process on iOS. We didn’t mention that this was a process where Apple repeatedly rejected us and we had to appeal over and over again.\nWe wanted to have a native app because they look/feel slightly better. We also wanted native in-app-purchase as an alternative to PayPal. But it seems Apple won’t allow a native app to do basic things that a web app can easily pull off on its platform.\nFor iOS we had to hide the fact that builds can exist for other OS’s. So we can’t mention Android support or even show the logo. That’s prohibited by Apples terms. But the sticking point was the ability to install the app you built. A pretty basic feature for an app building service. It works for web apps without a problem, we just launch a link and the app installed.\nIt seems that Apple guideline 2.5.2 prohibits 3rd party app installations. This makes a lot of sense on the surface. It’s meant to stop spam applications from constantly pushing you to install additional apps or stop a hacker from leveraging a loophole. But this is a legitimate use that works on the web and it’s crucial for this type of app. In a sense these guidelines make native apps less powerful than their web based equivalents.\nAfter spending ages back and forth with Apples bureaucrats over this requirement it seems that this just won’t happen. But I also had an epiphany of sort…\nWeb is Sometimes Better I’m strongly in the \u0026ldquo;native first\u0026rdquo; camp as this is our core business: we sell a cross platform native development tool. While it supports targeting web UI’s as well, that’s a secondary function and not its primary value.\nHowever, in this specific case, Apples restrictions make no sense. Amazingly, web provides the same level of functionality as the native app. It also has a couple of other advantages:\nFast/instant deployment\nNo restrictions about mentioning other platforms\nSubscriptions – Without the \u0026ldquo;Apple tax\u0026rdquo;\nThe disadvantages for our case are:\nNo appstore discoverability - This isn’t a big deal as there are so many apps in the stores today\nNo in-app-subscriptions - This is a benefit and a curse. In app purchase is a \u0026ldquo;low touch\u0026rdquo; solution for subscriptions but the cost and restrictions are prohibitive\nNo push – This is the most painful downside of this, it seems all browsers on iOS don’t support push at this time\nAnother disadvantage is the seamless login support. We invoke the app with a token from the web in order to login without a password. That’s both secure and convenient as one doesn’t need to type a password on the device.\nThis is problematic for the web app and as a result we need to show a typical email/password box. That’s not a deal breaker but it’s still a slight annoyance.\nDo We Still Need Native? Not as much as we used to and this gap is eroding fast. There are still annoyances with small things that are trivial to accomplish in native but require multiple steps in the web version. But for the most part they are easy to circumvent.\nOne of the nice things about cross platform development is the fact that we don’t rely on Apples whims. We can just release the web version of the app and keep working. That’s a huge advantage. It’s still not perfect but it looks as close as possible to a native app even though it’s technically a web app. So for this particular case this can work.\nFor the Android version we still have the native app that works just fine. It also looks slightly better than the web version on the same device (mostly due to fonts). It supports push and in-app-purchase so it provides that full app experience. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — March 31, 2019 at 8:13 am (permalink) Francesco Galgani says:\nDear Shai,\nI understand the problem: I have an app with high votes on Android (4.8/5) and +1000 installations, but Apple rejected the same identical app multiple times because the reviewers consider it \u0026ldquo;useless\u0026rdquo;…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/build-app-not-coming-ios/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/build-app-not-coming-ios/codename-one-build.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen we \u003ca href=\"/blog/codename-one-6-0-chat-live/\"\u003ereleased Codename One 6.0\u003c/a\u003e we mentioned that Codename One build is going through the approval process on iOS. We didn’t mention that this was a process where Apple repeatedly rejected us and we had to appeal over and over again.\u003c/p\u003e\n\u003cp\u003eWe wanted to have a native app because they look/feel slightly better. We also wanted native in-app-purchase as an alternative to PayPal. But it seems Apple won’t allow a native app to do basic things that a web app can easily pull off on its platform.\u003c/p\u003e","title":"The Native Version of Build isn't Coming to iOS"},{"content":"\nI recently became frustrated by the amount of work I had to put into recreating a Component hierarchy programmatically. For a test case, I needed to create a Form with a text field in the bottom, and a button just above it on the right.\nI ended up with code that looked like:\nForm f = new Form(\u0026quot;Test Form\u0026quot;, new BorderLayout()); Container south = new Container(new BorderLayout()); south.add(BorderLayout.SOUTH, new TextField()); south.add(BorderLayout.NORTH, FlowLayout.encloseRight(new Button(\u0026quot;Submit\u0026quot;))); f.add(BorderLayout.SOUTH, south); f.show(); The result looks something like:\nThis isn’t all that bad, but it feels like it could be made simpler. It isn’t entirely obvious what the finished result will look like by looking at the Java code. This is largely due to the imperative notation. A declarative notation would be easier to read.\nCodename One uses XML, a declarative language, as the underlying format for its GUI builder but this isn’t designed to be written or read by a human. It would be nice if I could express this UI using a notation that is both optimally succinct, and easy to read.\nSo, I created such a notation, and wrapped it in a class named UIFragment.\nA New Declarative UI Notation UIFragment supports both an XML and a JSON notation. Both are compiled down to the same underlying structure, which is based on the XML notation. I.e. If you use the JSON notation, it will just be converted to the XML version under the hood.\nLet’s take a look at the above example, using XML:\n\u0026lt;border\u0026gt; \u0026lt;border constraint=\u0026quot;south\u0026quot;\u0026gt; \u0026lt;$myTextField constraint=\u0026quot;south\u0026quot;/\u0026gt; \u0026lt;flow constraint=\u0026quot;north\u0026quot; align=\u0026quot;right\u0026quot;\u0026gt; \u0026lt;$submitButton/\u0026gt; \u0026lt;/flow\u0026gt; \u0026lt;/border\u0026gt; \u0026lt;/border\u0026gt; This XML can be transformed into a Component using\nComponent cmp = UIFragment.parseXML(xmlString) .set(\u0026quot;myTextField\u0026quot;, new TextField()) .set(\u0026quot;submitButton\u0026quot;, new Button(\u0026quot;Submit\u0026quot;)) .getView(); While this notation is slightly easier to read than it’s pure-java equivalent, it is still quite lengthy. For a UI like this, I’d like a notation that I can easily stick into a single-line\nstring. So let’s take a look at the JSON-ish UI notation.\n{south:{north:{flow:[$myTextField], align:right}, south:$submitButton}} And this can be further shorthened using the single-character layout constraint aliases to:\n{s:{n:{flow:[$myTextField], align:right}, s:$submitButton}} Notice that this JSON is not quite valid JSON. The property keys aren’t quoted, and neither are some of the values. This is OK, as the JSON parser for UIFragment is using non-strict mode, so as to eliminate all extra syntax that would only make our notation more difficult to write.\nUsing JSON, the entire Java source for the above example becomes:\nForm f = new Form(\u0026quot;Test Form\u0026quot;, new BorderLayout()); f.add( BorderLayout.CENTER, UIFragment.parseJSON(\u0026quot;{s:{n:{flow:[$myTextField], align:right}, s:$submitButton}}\u0026quot;) .set(\u0026quot;myTextField\u0026quot;, new TextField()) .set(\u0026quot;submitButton\u0026quot;, new Button(\u0026quot;Submit\u0026quot;)) .getView() ); f.show(); While the total lines of code hasn’t changed, the portion related to constructing the UI is certainly shorter, and it is now easy to understand what the structure will be.\nSyntax The syntax is built around containers. Rather that have a container tag, I opted to use a separate tag for each layout type. This makes the syntax both easier to read and easier to write. Instead of \u0026lt;container layout=\u0026quot;flow\u0026quot;\u0026gt; we simply have \u0026lt;flow\u0026gt;.\nThe supported layouts are shown in the following table.\nTable 1. Container notation Layout XML JSON TableLayout \u0026lt;table\u0026gt;\u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;…​\u0026lt;/td\u0026gt;…​\u0026lt;/tr\u0026gt;…​\u0026lt;/table\u0026gt; {table:[[],…​]} BorderLayout \u0026lt;border\u0026gt;…​\u0026lt;/border\u0026gt; {c:[], n:[], e:[], w:[], s:[], o:[]} FlowLayout \u0026lt;flow\u0026gt;…​\u0026lt;/flow\u0026gt; {flow:[], align:center, valign:top} BoxLayout X \u0026lt;x\u0026gt;…​\u0026lt;/x\u0026gt; {x:[]} BoxLayout Y \u0026lt;y\u0026gt;…​\u0026lt;/y\u0026gt; {y:[]} GridLayout \u0026lt;grid\u0026gt;…​\u0026lt;/grid\u0026gt; {grid:[], rows:3, cols:2} LayeredLayout \u0026lt;layered\u0026gt;…​\u0026lt;/layered\u0026gt; {layered:[]} Placeholders Rather than creating tags for every Component type, I chose to leave it simple. Only Containers can be expressed using the XML/JSON notation. Components should be represented using placeholders, and a corresponding call to set(String,Component) must be made on the UIFragment to bind a Component to the placeholder.\nE.g.\nUIFragment.parseJSON(\u0026quot;{s:$myButton}\u0026quot;) .set(\u0026quot;myButton\u0026quot;, new Button(\u0026quot;Hello\u0026quot;)) The above example creates a Container with a button placed in its south position. The $myButton placeholder will be replaced by the button that we passed to set(). Notice that the placeholder is prefixed with a $.\nThe XML equivalent of the above is:\nUIFragment.parseXML(\u0026quot;\u0026lt;border\u0026gt;\u0026lt;$myButton constraint='south'/\u0026gt;\u0026lt;/border\u0026gt;\u0026quot;) .set(\u0026quot;myButton\u0026quot;, new Button(\u0026quot;Hello\u0026quot;)) Attributes There are a small number of attributes which can be added to elements of a UIFragment. These include:\nuiid – The UIID to set on the element.\nid – An ID that can be used to obtain a direct reference to the Container via the UIFragment.findById(String) method. This is useful if you need to provide further customizations on the Container in Java that aren’t possible using XML or JSON.\nclass – This works like the HTML class attribute works. It assigns tags to the container that can be used by ComponentSelector to select the resulting component. Multiple tags are separated by spaces.\nThere are also some attributes that are only applicable to certain container types. E.g. \u0026lt;flow\u0026gt; supports align and valign attributes which accept \u0026ldquo;left\u0026rdquo;, \u0026ldquo;right\u0026rdquo;, \u0026ldquo;center\u0026rdquo;, and \u0026ldquo;top\u0026rdquo;, \u0026ldquo;bottom\u0026rdquo;, \u0026ldquo;center\u0026rdquo; respectively for values.\n\u0026lt;grid\u0026gt; and \u0026lt;table\u0026gt; both support rows and cols attributes which specify the number of rows and columns in their layouts respectively. On \u0026lt;table\u0026gt; these are optional attributes. If they are omitted it will use the actual data in the table to figure out the correct number of rows and columns.\nLabels Labels are a special case which are supported in UIFragments without having to use a placeholder. The XML notation supports a \u0026lt;label\u0026gt; tag, and the JSON notation will treat a string literal as a Label.\nExamples FlowLayout The following are all equivalent\nJSON notation using short array syntax for flow layout.\nContainer cnt = UIFragment.parseJSON(\u0026quot;['Name', $name, $button]\u0026quot;) .set(\u0026quot;name\u0026quot;, new TextField()) .set(\u0026quot;button\u0026quot;, new Button(\u0026quot;Submit\u0026quot;)) .getView(); JSON notation using verbose Object syntax for flow layout.\nContainer cnt = UIFragment.parseJSON(\u0026quot;{flow:['Name', $name, $button]}\u0026quot;) .set(\u0026quot;name\u0026quot;, new TextField()) .set(\u0026quot;button\u0026quot;, new Button(\u0026quot;Submit\u0026quot;)) .getView(); XML notation\nContainer cnt = UIFragment.parseXML(\u0026quot;\u0026lt;flow\u0026gt;\u0026lt;label\u0026gt;Name\u0026lt;/label\u0026gt;\u0026lt;$name/\u0026gt;\u0026lt;$button/\u0026gt;\u0026lt;/flow\u0026gt;\u0026quot;) .set(\u0026quot;name\u0026quot;, new TextField()) .set(\u0026quot;button\u0026quot;, new Button(\u0026quot;Submit\u0026quot;)) .getView(); Pure Java Imperative Code\nContainer cnt = new Container(new FlowLayout()); cnt.add(new Label(\u0026quot;Name\u0026quot;)); cnt.add(new TextField()); cnt.add(new Button(\u0026quot;Submit\u0026quot;)); And the resulting UI:\nBorderLayout JSON notation using single-char constraints.\nContainer cnt = UIFragment.parseJSON(\u0026quot;{n:'Name', c:$name, s:$button}\u0026quot;) .set(\u0026quot;name\u0026quot;, new TextField()) .set(\u0026quot;button\u0026quot;, new Button(\u0026quot;Submit\u0026quot;)) .getView(); JSON notation using verbose constraints.\nContainer cnt = UIFragment.parseJSON(\u0026quot;{north:'Name', center:$name, south:$button}\u0026quot;) .set(\u0026quot;name\u0026quot;, new TextField()) .set(\u0026quot;button\u0026quot;, new Button(\u0026quot;Submit\u0026quot;)) .getView(); XML notation\nContainer cnt = UIFragment.parseXML(\u0026quot;\u0026lt;border\u0026gt;\u0026lt;label constraint='north'\u0026gt;Name\u0026lt;/label\u0026gt;\u0026quot; + \u0026quot;\u0026lt;$name constraint='center'/\u0026gt;\u0026lt;$button constraint='south'/\u0026gt;\u0026lt;/bortder\u0026quot;) .set(\u0026quot;name\u0026quot;, new TextField()) .set(\u0026quot;button\u0026quot;, new Button(\u0026quot;Submit\u0026quot;)) .getView(); Pure Java Imperative Code\nContainer cnt = new Container(new BorderLayout()); cnt.add(BorderLayout.NORTH, new Label(\u0026quot;Name\u0026quot;)); cnt.add(BorderLayout.CENTER, new TextField()); cnt.add(BorderLayout.SOUTH, new Button(\u0026quot;Submit\u0026quot;)); And the result is:\nBox Layout Y JSON notation\nContainer cnt = UIFragment.parseJSON(\u0026quot;{y:['Name', $name, $button]}\u0026quot;) .set(\u0026quot;name\u0026quot;, new TextField()) .set(\u0026quot;button\u0026quot;, new Button(\u0026quot;Submit\u0026quot;)) .getView(); XML notation\nContainer cnt = UIFragment.parseXML(\u0026quot;\u0026lt;y\u0026gt;\u0026lt;label\u0026gt;Name\u0026lt;/label\u0026gt;\u0026lt;$name/\u0026gt;\u0026lt;$button/\u0026gt;\u0026lt;/y\u0026gt;\u0026quot;) .set(\u0026quot;name\u0026quot;, new TextField()) .set(\u0026quot;button\u0026quot;, new Button(\u0026quot;Submit\u0026quot;)) .getView(); Pure Java Imperative Code\nContainer cnt = new Container(BoxLayout.y()); cnt.add(new Label(\u0026quot;Name\u0026quot;)); cnt.add(new TextField()); cnt.add(new Button(\u0026quot;Submit\u0026quot;)); And the result:\nBox Layout X JSON notation\nContainer cnt = UIFragment.parseJSON(\u0026quot;{x:['Name', $name, $button]}\u0026quot;) .set(\u0026quot;name\u0026quot;, new TextField()) .set(\u0026quot;button\u0026quot;, new Button(\u0026quot;Submit\u0026quot;)) .getView(); XML notation\nContainer cnt = UIFragment.parseXML(\u0026quot;\u0026lt;x\u0026gt;\u0026lt;label\u0026gt;Name\u0026lt;/label\u0026gt;\u0026lt;$name/\u0026gt;\u0026lt;$button/\u0026gt;\u0026lt;/x\u0026gt;\u0026quot;) .set(\u0026quot;name\u0026quot;, new TextField()) .set(\u0026quot;button\u0026quot;, new Button(\u0026quot;Submit\u0026quot;)) .getView(); Pure Java Imperative Code\nContainer cnt = new Container(BoxLayout.x()); cnt.add(new Label(\u0026quot;Name\u0026quot;)); cnt.add(new TextField()); cnt.add(new Button(\u0026quot;Submit\u0026quot;)); And the result:\nGridLayout JSON notation\nContainer cnt = UIFragment.parseJSON(\u0026quot;{grid:[$settings, $info, $account, $logout], cols:2}\u0026quot;) .set(\u0026quot;settings\u0026quot;, new Button(FontImage.MATERIAL_SETTINGS)) .set(\u0026quot;info\u0026quot;, new Button(FontImage.MATERIAL_INFO)) .set(\u0026quot;account\u0026quot;, new Button(FontImage.MATERIAL_ACCOUNT_CIRCLE)) .set(\u0026quot;logout\u0026quot;, new Button(FontImage.MATERIAL_EXIT_TO_APP)) .getView(); XML notation\nContainer cnt = UIFragment.parseXML(\u0026quot;\u0026lt;grid cols='2'\u0026gt;\u0026lt;$settings/\u0026gt;\u0026lt;$info/\u0026gt;\u0026lt;$account/\u0026gt;\u0026lt;$logout/\u0026gt;\u0026lt;/grid\u0026gt;\u0026quot;) .set(\u0026quot;settings\u0026quot;, new Button(FontImage.MATERIAL_SETTINGS)) .set(\u0026quot;info\u0026quot;, new Button(FontImage.MATERIAL_INFO)) .set(\u0026quot;account\u0026quot;, new Button(FontImage.MATERIAL_ACCOUNT_CIRCLE)) .set(\u0026quot;logout\u0026quot;, new Button(FontImage.MATERIAL_EXIT_TO_APP)) .getView(); The result is:\nTableLayout JSON notation\nContainer cnt = UIFragment.parseJSON(\u0026quot;{table:[['Name', $name], ['Age', $age], ['Active', $active]]}\u0026quot;) .set(\u0026quot;name\u0026quot;, new TextField()) .set(\u0026quot;age\u0026quot;, new TextField()) .set(\u0026quot;active\u0026quot;, new CheckBox()) .getView(); XML notation\nContainer cnt = UIFragment.parseXML(\u0026quot;\u0026lt;table\u0026gt;\u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;\u0026lt;label\u0026gt;Name\u0026lt;/label\u0026gt;\u0026lt;/td\u0026gt;\u0026lt;td\u0026gt;\u0026lt;$name/\u0026gt;\u0026lt;/td\u0026gt;\u0026lt;/tr\u0026gt;\u0026quot;+ \u0026quot;\u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;\u0026lt;label\u0026gt;Age\u0026lt;/label\u0026gt;\u0026lt;/td\u0026gt;\u0026lt;td\u0026gt;\u0026lt;$age/\u0026gt;\u0026lt;/td\u0026gt;\u0026lt;/tr\u0026gt;\u0026quot;+ \u0026quot;\u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;\u0026lt;label\u0026gt;Active\u0026lt;/label\u0026gt;\u0026lt;/td\u0026gt;\u0026lt;td\u0026gt;\u0026lt;$active/\u0026gt;\u0026lt;/td\u0026gt;\u0026lt;/tr\u0026gt;\u0026lt;/table\u0026gt;\u0026quot;) .set(\u0026quot;name\u0026quot;, new TextField()) .set(\u0026quot;age\u0026quot;, new TextField()) .set(\u0026quot;active\u0026quot;, new CheckBox()) .getView(); The result is:\nReusing a Fragment Suppose you have a UIFragment that defines a single row of a list. When this list grows to hundreds or thousands of rows, it may become expensive to re-parse the JSON or XML for each row fragment. Luckily, you don’t need to do that. You can create the fragment once, and then use it to generate a different view for each row.\nConsider this example using the Contacts API.\nContact[] contacts = Display.getInstance().getAllContacts(true, true, true, true, true, true); UIFragment fragment = UIFragment.parseJSON(\u0026quot;{w:$icon, c:{n:$name, s:[$phone, '/', $email]}}\u0026quot;); Container cnt = new Container(BoxLayout.y()); for (Contact contact : contacts) { Component row = fragment.set(\u0026quot;icon\u0026quot;, (contact.getPhoto() == null) ? new Button(FontImage.MATERIAL_ADD_A_PHOTO) : new Button(contact.getPhoto().scaledHeight(20))) .set(\u0026quot;name\u0026quot;, new Label(contact.getDisplayName())) .set(\u0026quot;phone\u0026quot;, new Label(contact.getPrimaryPhoneNumber())) .set(\u0026quot;email\u0026quot;, new Label(contact.getPrimaryEmail())) .getView(); $(row).selectAllStyles().setBorder(Border.createUnderlineBorder(1)) .setBgColor(0xffffff) .setBgTransparency(0xff); cnt.add(row); } f.add(BorderLayout.CENTER, cnt); In this example, we parse the JSON only once, when UIFragment.parseJSON() is called. Then we iterate through each contact, setting the placeholders for each row. This works because once getView() has been called, the next subsequent call to set() will result in the fragment’s `view’ getting reset. This works similar to the way a prepared database query works in JDBC. The query is compiled (prepared) once, and changing the placeholders results in a different effective query.\nAnd the result:\nAccessing Components in the Fragment The JSON and XML notations offer only a limited amount of customization options for elements. The uiid attribute allows you to set the UIID for a component, but that’s about it. If you want to customize it further, you’ll need to obtain a reference to the actual component, and customize it directly using its Java API. There are two ways to obtain references to the components in a fragment.\nAdd the id attribute to the component, then use the findById() method of the fragment to access it.\nAdd the class attribute to the component to add \u0026ldquo;tags\u0026rdquo; that can be selected by the ComponentSelector class.\nExample using findById()\nUIFragment fragment = UIFragment.parseJSON(\u0026quot;{c:{flow:'Hello World', id:'MyContainer'}}\u0026quot;); Container myContainer = (Container)fragment.findById(\u0026quot;MyContainer\u0026quot;); $(myContainer).setPaddingMillimeters(10); Container cnt = fragment.getView(); In the above example we set the ‘id’ attribute on the nested FlowLayout Container, so that we can fetch it via findById(). Then we set the padding on that container using the Java API. The result:\nExample using class Attribute and ComponentSelector\nContainer view = UIFragment.parseJSON(\u0026quot;{c:{flow:'Hello World', class:'tag1 tag2'}, s:{flow:'South', class:'tag2'}\u0026quot;) .getView(); $(\u0026quot;.tag1\u0026quot;, view).selectAllStyles().setBgColor(0xff0000).setBgTransparency(0xff); $(\u0026quot;.tag2\u0026quot;, view).selectAllStyles().setBorder(Border.createLineBorder(1)); This example demonstrates the use of the class attribute for setting tags that can be used by ComponentSelector for selecting nested components in the fragment. We have two nested containers. One in the center with tags \u0026ldquo;tag1\u0026rdquo; and \u0026ldquo;tag2\u0026rdquo;; and a second component in the south with tag \u0026ldquo;tag2\u0026rdquo; only.\nWe’re able to select on \u0026ldquo;tag1\u0026rdquo; to set the background color of the first component to red. Then we selet on \u0026ldquo;tag2\u0026rdquo; (which selects both of the components), to set the border of both components to use a line border.\nThe result:\nSummary UIFragment provides simple way to user interfaces using a declarative syntax. It supports both an XML and a JSON syntax. The JSON notation is almost always more succinct and easier to read than the XML equivalent, and both provide advantages over directly defining the UI in Java code. You can embed placeholders inside your fragment’s JSON/XML and have them replaced by custom components when the fragment is compiled. Additionally, you can access nested components within fragments for further customization by tagging them either with an \u0026ldquo;id\u0026rdquo; or a \u0026ldquo;class\u0026rdquo; attribute. Finally you can reuse the same fragment to generate entire sets of components by setting placeholders with different values.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/introduction-to-uifragment/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/introduction-to-uifragment/uidesign.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI recently became frustrated by the amount of work I had to put into recreating a Component hierarchy programmatically. For a test case, I needed to create a Form with a text field in the bottom, and a button just above it on the right.\u003c/p\u003e\n\u003cp\u003eI ended up with code that looked like:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eForm f = new Form(\u0026quot;Test Form\u0026quot;, new BorderLayout());\n\nContainer south = new Container(new BorderLayout());\nsouth.add(BorderLayout.SOUTH, new TextField());\nsouth.add(BorderLayout.NORTH, FlowLayout.encloseRight(new Button(\u0026quot;Submit\u0026quot;)));\n\nf.add(BorderLayout.SOUTH, south);\n\nf.show();\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThe result looks something like:\u003c/p\u003e","title":"Introduction to UIFragment"},{"content":"\nThe new video capture constraints API allows you to specify \u0026ldquo;constraints\u0026rdquo; when capturing videos. Constraints include:\nVideo Quality (High or Low)\nMaximum duration\nMaximum file size\nVideo Resolution (i.e. width and height).\nSupport for these constraints vary by platform and device, but the API allows you to check if your constraints are supported at runtime. Essentially, you set your \u0026ldquo;preferred\u0026rdquo; constraints, and the API will give you its best attempt at meeting those constraints. This is similar to setting a visual Component’s preferred width and height. The layout manager takes these preferred dimensions under advisement, but ultimately sets the size on its own.\nExample 1: Capturing a Low-Quality 5-Second Clip Suppose we want to allow the user to capture a short (5 second) clip, in a low resolution, appropriate for sharing on a social media platform. We create our VideoCaptureConstraints object as follows:\nVideoCaptureConstraints cnst = new VideoCaptureConstraint() .preferredQuality(VideoCaptureConstraints.QUALITY_LOW) .preferredMaxLength(5); This constraint can then be passed to Capture.captureVideo() to obtain the captured file.\nString videoPath = Capture.captureVideo(cnst); Not all platforms support all constraints So how do we know if our constraints will be obeyed? If the platform doesn’t support the max length, constraint, we may want to do something different. We can find out if a constraint is supported by simply asking out constraint object.\nE.g.\nif (cnst.isMaxLengthSupported()) { // The max length constraint that we specified is supported on this platform. } else{ // The max length constraint is NOT supported. // Check the effective max length constraint value to see if it may be partially // supported int effectiveMaxLength = cnst.getMaxLength(); if (effectiveMaxLength == 0) { // Max length is not supported at all... the user will be able // to capture a video without duration restrictions } else { // Max length was set to some different value than we set in our // preferredMaxLength, but the platform is at least trying to accommodate us. } } You can probe a constraint to see whether the entire constraint is supported (i.e will be obeyed), or whether any particular aspect of it will be supported using the following methods:\nisSupported() – True if all preferred constraints are supported.\nisQualitySupported() – True if the preferred quality setting is supported.\nisMaxLengthSupported() – True if the max length setting is supported.\nisMaxFileSizeSupported() – True if the max file size setting is supported.\nisSizeSupported() – True if the specified preferred width and height constraints are supported.\nExample 2: Specifying Explicit Width and Height Suppose we want to capture a video with resolution 320×240. We would begin with this constraint:\nVideoCaptureConstraints cnst = new VideoCaptureConstraints() .preferredWidth(320) .preferredHeight(240); Explicit width and height constraints currently aren’t well supported across platforms. Android doesn’t support them at all. iOS supports only 3 specific sizes. Javascript supports it when running on a desktop browser or on Android – but not on iOS. Etc..\nSo let’s find out if this constraint will be obeyed.\nif (cnst.isSizeSupported()) { // Yay! This platform supports our constraint, so the captured video will // be exactly 320x240. } else { // Not supported... let's see if the platform will at least try to accommodate us int effectiveWidth = cnst.getWidth(); int effectiveHeight = cnst.getHeight(); int quality = cnst.getQuality(); if (effectiveWidth == 0 \u0026amp;\u0026amp; effectiveHeight == 0) { // This platform has no control over width and height // In many cases it will try to at least set the quality approximate if (quality != 0) { // The platform set the quality for us to try to comply. // Since 320x240 is pretty small, the quality would probably // be set to QUALITY_LOW } } else { // The platform couldn't capture at 320x240, but it has provided an // alternate size that is as close to that as possible. } } Constraint Support By Platform Platform Size Quality Max Length Max File Size Javascript (iOS) Yes Yes Yes No iOS Limited Yes Yes No Android No* Yes Yes Yes Simulator/JavaSE No No No No UWP No* Yes Yes No Javascript (Desktop) Yes Yes Yes No Javascript (Android) Yes Yes Yes No * If size is specified, the platform will attempt to translate to the appropriate quality constraint. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nGareth Murfin — July 10, 2019 at 3:34 pm (permalink) Gareth Murfin says:\nIt would be awesome if you could use this same class and ust specify an array of pngs or something to also be able to export a video.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/video-capture-constraints/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/video-capture-constraints/new-features-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe new video capture constraints API allows you to specify \u0026ldquo;constraints\u0026rdquo; when capturing videos. Constraints include:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003eVideo Quality (High or Low)\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eMaximum duration\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eMaximum file size\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eVideo Resolution (i.e. width and height).\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eSupport for these constraints vary by platform and device, but the API allows you to check if your constraints are supported at runtime. Essentially, you set your \u0026ldquo;preferred\u0026rdquo; constraints, and the API will give you its best attempt at meeting those constraints. This is similar to setting a visual Component’s preferred width and height. The layout manager takes these preferred dimensions under advisement, but ultimately sets the size on its own.\u003c/p\u003e","title":"Video Capture Constraints"},{"content":"\nA while back someone asked on stackoverflow how to adapt a Codename One app to tablets. I provided quite a few references in the answer and following discussion but I think a better approach is to explain what we did with the recent Codename One Build app because that’s what I’ve been doing in all recent apps I worked on.\nI call this approach the \u0026ldquo;phone first\u0026rdquo; approach for universal app development. It starts by forgetting about the tablet and focusing on building a good looking phone app. In this app I usually subclass Form for all the classes which instantly creates an app that’s very suitable for phones.\nWhen this is done I give some thought to how I would like the app to work as a tablet app. In general I want the app to have a permanent side menu and one Form where the content is replaced.\nTo accomplish this I change all the existing subclasses of Form so they will derive from my private class BaseForm which is basically something like this:\npublic class BaseForm extends Container { private String title; private static Form tabletForm; public BaseForm(String title, Layout l) { super(l); this.title = title; if(!(l instanceof BorderLayout)) { setScrollableY(true); } } // rest of code } Since there is only one form in the tablet I can keep it as a static global, that’s obvious.\nBut why is the title a variable?\nWhere are the rest of the methods we expect in Form?\nSimple, we create every method thats missing and make it work in such a way that makes sense for our applications tablet design. E.g. this is show() which is one of the bigger methods here:\npublic void show() { if(isTablet()) { if(tabletForm == null) { __**(1)** tabletForm = new Form(title, new BorderLayout()); __**(2)** getUnselectedStyle().setBgTransparency(255); __**(3)** UIUtil.createSideMenu(tabletForm); tabletForm.add(CENTER, this); tabletForm.show(); } else { replaceTabletForm(true); __**(4)** } } else { if(getParent() != null) { __**(5)** getComponentForm().show(); } else { Form f = new Form(title, new BorderLayout()); UIUtil.createSideMenu(f); f.add(CENTER, this); __**(6)** f.show(); } } } private void replaceTabletForm(boolean dir) { getUnselectedStyle().setBgTransparency(255); Container c = tabletForm.getContentPane(); c.replaceAndWait(c.getComponentAt(0), this, CommonTransitions.createCover(CommonTransitions.SLIDE_HORIZONTAL, dir, 300)); tabletForm.setTitle(title); __**(7)** } __1 If this is the first form shown we create a new Form for the case of a tablet __2 The BaseForm is in the center of a border layout which means it will take the available space, we can use more creative layouts e.g. with 3 panes __3 By default Container is transparent but this looks bad in replace animation so for tablets we make the containers opaque __4 If this isn’t the first form we just use the replace method below __5 For a phone we wrap a BaseForm in a Form so they are effectively identical, we can reuse the Form instances __6 This code is almost identical to the code in the tablet mode but happens multiple times __7 Since we reuse the same form in the tablet mode we need to update the title value Once we do this there would be compilation errors for various methods of Form that we relied on. These are mostly easy to fix as they just mean implementing the logic for every Form method you need e.g.:\npublic void showBack() { if(isTablet()) { replaceTabletForm(false); } else { getComponentForm().showBack(); } } Generalization via API I tried to generalize this process through a standardized API multiple times in the past and failed. It’s easy to solve the simple use cases but converting a \u0026ldquo;best practice\u0026rdquo; into an API is more challenging.\nIf you have thoughts or ideas on how this approach can be adapted to create a more versatile API I’m open to suggestions.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-adapting-to-tablets/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-adapting-to-tablets/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA while back someone asked on stackoverflow \u003ca href=\"https://stackoverflow.com/questions/54269508/how-to-structure-the-cn1-code-for-a-tablet-form-layout\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehow to adapt a Codename One app to tablets\u003c/a\u003e. I provided quite a few references in the answer and following discussion but I think a better approach is to explain what we did with the recent Codename One Build app because that’s what I’ve been doing in all recent apps I worked on.\u003c/p\u003e\n\u003cp\u003eI call this approach the \u0026ldquo;phone first\u0026rdquo; approach for universal app development. It starts by forgetting about the tablet and focusing on building a good looking phone app. In this app I usually subclass \u003ccode\u003eForm\u003c/code\u003e for all the classes which instantly creates an app that’s very suitable for phones.\u003c/p\u003e","title":"TIP: Adapting to Tablets"},{"content":"\nWe are thrilled to announce the release of Codename One 6.0 – Chat. Codename One is an open source \u0026ldquo;Write Once Run Anywhere\u0026rdquo; mobile platform for Java and Kotlin developers!\nWith this release we introduced Codename One Build which is one of the biggest overhauls to the Codename One workflow since its inception. We also refined and updated many underlying technologies e.g. the xcode 10.1 migration, WKWebView support, push replies, badges on Android and much more.\nYou can check out the details below for the full review but first if you are new to Codename One here’s a short primer. Codename One is the only platform that:\nHas Write Once Run Anywhere with no special hardware requirements and 100% code reuse\nCompiles Java or Kotlin into native code for iOS, UWP (Universal Windows Platform), Android \u0026amp; even JavaScript\nIs Open Source \u0026amp; Free for commercial use with an enterprise grade commercial support\nIs Easy to use with 100% portable Drag \u0026amp; Drop GUI builder\nHas Full access to underlying native OS capabilities using the native OS programming language (e.g. Objective-C) without compromising portability\nHas full control over every pixel on the screen! Just override paint and draw or use a glass pane to draw anywhere…​\nLets you use native widgets (views) and mix them with Codename One components within the same hierarchy (heavyweight/lightweight mixing)\nSupports seamless Continuous Integration out of the box\nTo learn more about Codename One check out the about page you can download it for free right now.\nVersion 6.0 is nicknamed Chat because of the WhatsApp Clone application that was developed with it for the online course in the Codename One Academy.\nHighlights of this Release The top 5 features of this release are covered in this short video, check out further details below…​\nCodename One Build — we can now monitor builds from Android and iOS. The app is also available for every device through web PWA. It works with push notification and is built with Codename One! __ Currently the iOS version is still in beta due to the tedious appstore approval process xcode 10.1 Migration — builds on the Codename One cloud implicitly use xcode 10.1. We migrated from xcode 9.2 to satisfy Apples requirements, this has been seamless for the most part\nVM Changes — we now support java.util.Objects and some additional methods from Class\nNew Switch API — Switch replaces the old OnOffSwitch API which is pretty old by now\nReply Push Notifications — the final piece of RFE 2208 Rich Push Notifications is now implemented. You can now prompt a user for a reply via a push message\nSupport for Badges on Android — we can now mark an Android icon with a numeric badge\nMaterial Design Infinite Progress — InfiniteProgress now has a material design mode that includes the custom circle animation we see in material design\nWKWebView Support — Apple includes two implementations of a \u0026ldquo;WebView\u0026rdquo;. We now support both\nCSS Improvements — underline border is now supported natively. Round rectangle is also supported natively and lets you activate the angle only on specific corners as per this RFE\nPicker Improvements — Picker now lets you define start/end date\nFontImage rotateAnimation — FontImage lets you animate an icon so it rotates infinitely effectively making every component into an InfiniteProgress\nAdded Ownership to Component Hierarchy — ownership allows us to create a relationship between components other than Component → Container\nAdded Animation Safe Revalidate — revalidte() is a powerful tool but if it’s invoked when an animation is in progress it might produce unpredictable behavior. This method solves that problem\nButton Lists — List is discouraged but we still want lists that use a model to represent buttons, radio buttons and checkboxes button lists can fit in that niche\nXML Mapping in Properties — this is still an experimental feature but XML parsing/generating is now supported for PropertyBusinessObject\nPWA Install Prompt — a new API lets us install PWA’s directly\nNew Full Screen API — the Desktop and JavaScript targets allow running the app in full screen mode by leveraging this new API\nFacebook SDK Updated — we updated the Facebook SDK to use the latest version\nThere are many other features both big and small. Check out our blog and the github project history.\nOnwards to 7.0 – Video We took a lot of time for 6.0 but I’m not sure if that’s enough. We might take longer to deliver 7.0. Currently the timeline is unchanged but we’ll have to see.\nWe will have a Netflix clone tutorial in the Codename One Academy. Hence the moniker of the next release.\nWe Need your Help If you think we are doing a good job and appreciate our help please help us by:\nSpreading the word\nEdit our docs\nEdit our sources and submit bug fixes\nOr just sign up for enterprise accounts which literally keep the lights on here…​ If your company can afford it please take the time and upgrade to enterprise, this will allow us to work on the things that are important for your company!\nThanks for reading this far and if you have any thoughts/suggestions of any kind please let us know!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-6-0-chat-live/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-6-0-chat-live/codenameone-6-release-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are thrilled to announce the release of \u003ca href=\"https://www.codenameone.com/\"\u003eCodename One\u003c/a\u003e 6.0 – Chat. Codename One is an open source \u0026ldquo;Write Once Run Anywhere\u0026rdquo; mobile platform for Java and Kotlin developers!\u003cbr\u003e\nWith this release we introduced \u003ca href=\"https://cloud.codenameone.com/buildapp/index.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCodename One Build\u003c/a\u003e which is one of the biggest overhauls to the Codename One workflow since its inception. We also refined and updated many underlying technologies e.g. the xcode 10.1 migration, \u003ccode\u003eWKWebView\u003c/code\u003e support, push replies, badges on Android and much more.\u003c/p\u003e","title":"Codename One 6.0 \"Chat\" is now Live"},{"content":"\nWe are in code freeze…​ As part of the release process I’m gathering the changes we implemented over the past few months. Quite a few didn’t get a blog post during this time. So here is a list of the important things we didn’t document.\nVM Changes We did two big things for ParparVM (our iOS VM) which allowed us to expose this functionality in other platforms as well. First is support for most of the small methods in Class which can be helpful when we write some generic code. Specifically the methods: isEnum(), isSynthetic(), isInterface(), isAnonymousClass(), isPrimitive() and isAnnotation().\nWe can’t guarantee that these will work perfectly for all cases as there are some complexities. E.g. our process for supporting Java 8 might trigger true for isAnonymousClass() due to a lambda. But this is a start.\nAnother important piece is java.util.Objects. Technically we implemented this class via com.codename1.compat.java.util.Objects but if you use the java.util.Objects it will work just fine. The processor will translate the calls to the Codename One equivalents.\nObjects includes some common useful utility methods. Hopefully we’ll add a few more classes like that as needed.\nXML Properties We supported JSON in properties from day one. XML is a bit harded but not by much. We added highly experimental support for XML into properties which can be useful when working with XML data from the server or storage.\n__ This feature is experimental and the API might change/break PropertyIndex includes several new API’s to enable that. First we have:\npublic Element asElement(); This returns the PropertyBusinessObject as an XML Element object which is the parsed form of XML in Codename One. You can use XMLWriter to convert this to a String or use XML processing code to work with the Element.\nThe toXML() method in PropertyIndex takes the next step of converting that XML Element to a String and returning it:\npublic String toXML(); A property in the object can appear as the text element e.g. \u0026lt;tag\u0026gt;Text Element\u0026lt;/tag\u0026gt;. You can explicitly define which by using these methods in PropertyIndex:\npublic void setXmlTextElement(PropertyBase p, boolean t); public boolean isXmlTextElement(PropertyBase p); Finally, we can parse XML by using:\npublic void fromXml(Element e); This will walk the parsed XML and convert it to the object we’re using.\nFull Screen The Desktop and JavaScript ports support running in full screen mode. This is useful for games and media applications. It’s also useful for PoS and multiple other purposes.\nHistorically, we had a build hint that allowed you to set full screen mode for the desktop port. That isn’t ideal as full screen might be something you wish to toggle dynamically within the app. It might require user permission too as is the case for JavaScript.\nWe now have a new full screen API. The following code assumes you have an import of CN specifically import static com.codename1.ui.CN.*;:\nif(isFullScreenSupported() \u0026amp;\u0026amp; !isInFullScreenMode()) { requestFullScreen(); } You can also use exitFullScreen() to perform the inverse operation.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/vm-enhancments-full-screen-xml/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/vm-enhancments-full-screen-xml/new-features-4.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are in code freeze…​ As part of the release process I’m gathering the changes we implemented over the past few months. Quite a few didn’t get a blog post during this time. So here is a list of the important things we didn’t document.\u003c/p\u003e\n\u003ch3 id=\"vm-changes\"\u003eVM Changes\u003c/h3\u003e\n\u003cp\u003eWe did two big things for ParparVM (our iOS VM) which allowed us to expose this functionality in other platforms as well. First is support for most of the small methods in \u003ccode\u003eClass\u003c/code\u003e which can be helpful when we write some generic code. Specifically the methods: \u003ccode\u003eisEnum()\u003c/code\u003e, \u003ccode\u003eisSynthetic()\u003c/code\u003e, \u003ccode\u003eisInterface()\u003c/code\u003e, \u003ccode\u003eisAnonymousClass()\u003c/code\u003e, \u003ccode\u003eisPrimitive()\u003c/code\u003e and \u003ccode\u003eisAnnotation()\u003c/code\u003e.\u003c/p\u003e","title":"VM Enhancements, Full Screen and XML"},{"content":"\nWe’re entering code freeze later tonight which means no further commits will be made. After the code freeze only reviewed commits can be cherry picked. Only critical bugs will be fixed at that point.\nWe will push out a new plugin update and tools tomorrow morning. They will be labeled 6.0 and serve as release candidates. If there are issues we’ll push out further updates during the week.\nOnce the release is made we’ll skip the next Friday release as is our practice with the first Friday after a release.\nWe closed 96 issues as part of this release so far. Some things proved problematic and were postponed to version 7.0 hopefully we’ll catch up to most of them by then.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codefreeze-for-chat/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codefreeze-for-chat/codenameone-6-release-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’re entering code freeze later tonight which means no further commits will be made. After the code freeze only reviewed commits can be cherry picked. Only critical bugs will be fixed at that point.\u003cbr\u003e\nWe will push out a new plugin update and tools tomorrow morning. They will be labeled 6.0 and serve as release candidates. If there are issues we’ll push out further updates during the week.\u003c/p\u003e","title":"Codefreeze for Chat (Codename One 6.0)"},{"content":"\nCodename One 6.0 AKA Chat will launch on February 27th. We’re pushing this release a week back to finish the open issues. We will enter code freeze on the 20th exactly one week from today.\nAfter the code freeze only reviewed commits can be cherry picked. Only critical bugs will be fixed at that point.\nChat We named the releases of Codename One based on the signature app we built on top of that given release. 5.0 was named social and 4.0 was named Taxi representing the Facebook/Uber clones respectively. Version 6.0 is named Chat as we built a WhatsApp Clone during the release cycle.\nFor Version 7.0 we plan to build a Netflix clone. The planned name for version 7.0 is \u0026ldquo;Video\u0026rdquo;.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/preparing-for-chat/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/preparing-for-chat/codenameone-6-release-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One 6.0 AKA Chat will launch on February 27th. We’re pushing this release a week back to finish the open issues. We will enter code freeze on the 20th exactly one week from today.\u003cbr\u003e\nAfter the code freeze only reviewed commits can be cherry picked. Only critical bugs will be fixed at that point.\u003c/p\u003e\n\u003ch3 id=\"chat\"\u003eChat\u003c/h3\u003e\n\u003cp\u003eWe named the releases of Codename One based on the signature app we built on top of that given release. 5.0 was named social and 4.0 was named Taxi representing the Facebook/Uber clones respectively. Version 6.0 is named Chat as we built a \u003ca href=\"https://codenameone.teachable.com/p/build-real-world-full-stack-mobile-apps-in-java\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eWhatsApp Clone\u003c/a\u003e during the release cycle.\u003c/p\u003e","title":"Preparing for Codename One 6.0 – Chat"},{"content":"\nThe recent migration to xcode 10.1 broke builds for apps using the file chooser API. In order to use that API we need to make changes to the provisioning profile to include iCloud support. With the new version you must have a container associated with iCloud for this to work.\nTo fix this follow these steps:\nLogin to https://developer.apple.com/account/ios/identifier/bundle\nUnder App IDs select your app\nClick Edit\nCheck iCloud and select Include CloudKit support (requires Xcode 6)\nFigure 1. iCloud Settings\nCreate a new iCloud container and give it a unique name/package\nGo back to the icloud settings edit mode and select the new container in the list of containers as such\nFigure 2. Select the Container\nNext regenerate and download the provisioning profiles, replace the ones in your app with the new provisioning profiles Notice that this will only work with the default xcode 10.1 mode. It seems that the application loader now requires this as Apple no longer accepts binaries with xcode 9.2 that use the older approach (without containers). Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nEric Kimotho — January 15, 2021 at 3:51 pm (permalink) Thank you for this. Apple website was updated and menus rearranged. Below are the steps I followed.\n1 Login to developer account\n2 Select Certificates, Identifiers \u0026amp; Profiles\n3 Select iCloud containers from drop down in the right (where default value shown is App IDs)\n4 Click + icon to add new identifier/container – by default iCloud containers will be selected\n5 Click Continue\n6 Enter description eg Name of the CN1 app,\n7 Enter identifier eg CN1 app package name and click continue, note iCloud prefix will be added by default\n8 Click Register\n9 You are taken back to identifiers listing created iCloud containers\n10 Select App IDs from drop down in the right\n11 Select app you need to enable iCloud (Note Apps are appearing here after sending successful iOS build, note in this case filechooser lib should first be uninstalled from project (using this link \u0026lt;/blog/tip-uninstall-cn1lib/\u0026gt;) for build to be successful)\n12 Scroll down and check iCloud then select include CloudKit support (requires Xcode 6)\n13 Click Edit button, a dialog with iCloud containers will show\n14 Select iCloud container to use and click continue\n15 Click save button at top right corner\n16 A warning dialog that provisioning will be revalidated and need to be regenerated will show, click continue\n17 Back to IDE reinstall filechooser lib\n18 Under project’s iosCerts folder, delete both provisioning profiles and rerun certificate wizard to regenerate provisioning profiles which will now have iCloud enabled\n19 Send iOS build, should be successful now\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/file-chooser-xcode-10/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/file-chooser-xcode-10/xcode-migration.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe recent migration to \u003ca href=\"/blog/xcode-10-1-migration-phase-2.html\"\u003excode 10.1\u003c/a\u003e broke builds for apps using the \u003ca href=\"/blog/native-file-open-dialogs.html\"\u003efile chooser\u003c/a\u003e API. In order to use that API we need to make changes to the provisioning profile to include iCloud support. With the new version you must have a container associated with iCloud for this to work.\u003c/p\u003e\n\u003cp\u003eTo fix this follow these steps:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eLogin to \u003ca href=\"https://developer.apple.com/account/ios/identifier/bundle\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttps://developer.apple.com/account/ios/identifier/bundle\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eUnder App IDs select your app\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eClick Edit\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eCheck iCloud and select Include CloudKit support (requires Xcode 6)\u003c/p\u003e","title":"File Chooser on Xcode 10.1"},{"content":"\nThe WhatsApp clone app is finally up in the online course. With that finally out of the way we can turn our attention to Codename One 6.0 which is due dangerously soon. We might even slightly postpone the release so we can finish crucial RFE’s/issues.\nGetting the WhatsApp clone out has been an ordeal, not so much because of complexity (the app is much simpler than Uber or Facebook)…​ It was due to the amount of concurrent things I had to deal with during this time.\nThere are still plenty of issues for version 6.0 and a lot of them just won’t make it in time so this is the point where we need to step it up for the 6.0 release. Right now I’m considering pushing it back one week to February 26th instead of the 19th. This should give us a bit more time to get more of these issues/features in. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nroland tshabalala — February 26, 2019 at 4:58 pm (permalink) roland tshabalala says:\nDoes this clone include features that allows you to modify text into things like bold, italics, underlines, bullets and different colors etc? Also does it include Voip, sending voice notes?\nShai Almog — February 27, 2019 at 3:26 am (permalink) Shai Almog says:\nNo to both. This clone is much simpler than previous clones as a lot of the functionality was already discussed in the Facebook Clone. It also includes a rich text view which you can use for rich input.\nSending voip notes is something I partially implemented there but didn’t actually do, it should be relatively trivial. VoIP would require native integration, I looked at some of the available options in the field and chose to pass on this for now. There are so many options and the setup hassle would have taken up too much time.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/whatsapp-clone-ga/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/whatsapp-clone-ga/build-real-world-full-stack-mobile-apps-in-java.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe WhatsApp clone app is finally up in the \u003ca href=\"https://codenameone.teachable.com/p/build-real-world-full-stack-mobile-apps-in-java\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eonline course\u003c/a\u003e. With that \u003cstrong\u003efinally\u003c/strong\u003e out of the way we can turn our attention to Codename One 6.0 which is due dangerously soon. We might even slightly postpone the release so we can finish crucial RFE’s/issues.\u003c/p\u003e\n\u003cp\u003eGetting the WhatsApp clone out has been an ordeal, not so much because of complexity (the app is much simpler than Uber or Facebook)…​ It was due to the amount of concurrent things I had to deal with during this time.\u003c/p\u003e","title":"WhatsApp Clone GA"},{"content":"\nLast week Steve committed the final piece of the rich push notification support RFE. This commit introduces support for replies in push messages. This came too late for the whatsapp clone but if you want to build an app of this type you would need this feature.\nThe app main class should implement PushActionProvider. This defines a method that returns a set of categories. E.g.\npublic PushActionCategory[] getPushActionCategories() { return new PushActionCategory[]{ new PushActionCategory(\u0026quot;fo\u0026quot;, new PushAction[]{ new PushAction(\u0026quot;yes\u0026quot;, \u0026quot;Yes\u0026quot;), new PushAction(\u0026quot;no\u0026quot;, \u0026quot;No\u0026quot;), new PushAction(\u0026quot;maybe\u0026quot;, \u0026quot;Maybe\u0026quot;, null, \u0026quot;Enter reason\u0026quot;, \u0026quot;Reply\u0026quot;) }) }; } Then, when sending a push notification, you can specify the \u0026ldquo;category\u0026rdquo; of the message. If the category corresponds with a defined category in your getPushActionCategories() method, then the user will be presented with a set of buttons corresponding to the PushActions in that category.\nIn the above example, we would send a push type 99 and a body of\n\u0026lt;push type=\u0026quot;0\u0026quot; body=\u0026quot;Hello\u0026quot; category=\u0026quot;fo\u0026quot;/\u0026gt; This would trigger the \u0026ldquo;fo\u0026rdquo; category that we defined, which has 3 actions: Yes, No, and Maybe. And the \u0026ldquo;Maybe\u0026rdquo; action will provide a text input because of the extra parameters provided:\nnew PushAction(\u0026quot;maybe\u0026quot;, \u0026quot;Maybe\u0026quot;, null, \u0026quot;Enter reason\u0026quot;, \u0026quot;Reply\u0026quot;) The last 2 parameters are the \u0026ldquo;hint\u0026rdquo; text and the reply button label. On android, the notification will look like this.\nFigure 1. Push Reply\nIf you click on \u0026ldquo;Maybe\u0026rdquo; (with Android API level 27 or higher which is the default), then you’ll get a text field to enter a reply directly.\nYou can retrieve both which action was pressed, and what the user text input was using the PushContent class.\nAn example push callback method to retrieve this data:\npublic void push(String value) { PushContent data = PushContent.get(); if (data != null) { Log.p(\u0026quot;Image URL: \u0026quot;+data.getImageUrl()); Log.p(\u0026quot;Category: \u0026quot;+data.getCategory()); Log.p(\u0026quot;Action: \u0026quot;+data.getActionId()); Log.p(\u0026quot;Text Response: \u0026quot;+data.getTextResponse()); } else { Log.p(\u0026quot;PushContent is null\u0026quot;); } Log.p(\u0026quot;Push \u0026quot;+value); Display.getInstance().callSerially(()-\u0026gt;{ Dialog.show(\u0026quot;Push received\u0026quot;, value, \u0026quot;OK\u0026quot;, null); }); } Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nCh Hjelm — May 21, 2019 at 11:12 am (permalink) This is a great feature! Is it possible to use the rich push features with local notifications (described here? E.g. is it possible to call the PushContent.get() from within the callback localNotificationReceived(String notificationId)?\nShai Almog — May 22, 2019 at 9:33 am (permalink) Shai Almog says:\nNo. Unfortunately they are completely separate features that have no connection between them at this time.\nCh Hjelm — May 22, 2019 at 4:45 pm (permalink) Ch Hjelm says:\nThat’s a pity, i thought local and ‘remote’ push notifications shared the same mechanics, so I hoped there was a synergy. I use local notifications for on-device popups when the app is not active, and the ‘rich’ features would be perfect to enhance that. Is it possible that the ‘rich’ features might become available for local notifications some day?\nShai Almog — May 23, 2019 at 5:05 am (permalink) Shai Almog says:\nUnless an enterprise user explicitly asks for this I don’t see this happening. This was a very hard to implement RFE that took forever. We’re already backlogged with enterprise RFE’s so even if this was requested by an enterprise user it would probably take a lot of time to resolve as it’s a big task.\nRochana Sawatzky — July 9, 2020 at 2:04 pm (permalink) Rochana Sawatzky says:\nI’ve managed to get Push working on both Android and iOS, however my Android notifications come as silent notifications. Is there a setting where I can change them to be regular notifications?\nShai Almog — July 10, 2020 at 4:12 am (permalink) Shai Almog says:\nIt seems to be an issue with Android 10: https://support.google.com/pixelphone/thread/14478025?hl=en\nWe’re still not sure if this is something that we can handle/hide or if it’s something that Google must fix.\nRochana Sawatzky — July 11, 2020 at 4:39 am (permalink) Rochana Sawatzky says:\nGood to know, thank you!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/rich-push-notification-improved/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/rich-push-notification-improved/new-features-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eLast week Steve committed the final piece of the \u003ca href=\"https://github.com/codenameone/CodenameOne/issues/2208\" target=\"_blank\" rel=\"noopener noreferrer\"\u003erich push notification support RFE\u003c/a\u003e. This commit introduces support for replies in push messages. This came too late for the \u003ca href=\"/blog/whatsapp-clone/\"\u003ewhatsapp clone\u003c/a\u003e but if you want to build an app of this type you would need this feature.\u003c/p\u003e\n\u003cp\u003eThe app main class should implement \u003ccode\u003ePushActionProvider\u003c/code\u003e. This defines a method that returns a set of categories. E.g.\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003epublic PushActionCategory[] getPushActionCategories() {\n    return new PushActionCategory[]{\n        new PushActionCategory(\u0026quot;fo\u0026quot;, new PushAction[]{\n            new PushAction(\u0026quot;yes\u0026quot;, \u0026quot;Yes\u0026quot;),\n            new PushAction(\u0026quot;no\u0026quot;, \u0026quot;No\u0026quot;),\n            new PushAction(\u0026quot;maybe\u0026quot;, \u0026quot;Maybe\u0026quot;, null, \u0026quot;Enter reason\u0026quot;, \u0026quot;Reply\u0026quot;)\n        })\n\n    };\n}\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThen, when sending a push notification, you can specify the \u0026ldquo;category\u0026rdquo; of the message. If the category corresponds with a defined category in your \u003ccode\u003egetPushActionCategories()\u003c/code\u003e method, then the user will be presented with a set of buttons corresponding to the PushActions in that category.\u003c/p\u003e","title":"Rich Push Notifications Improved"},{"content":"\nWe supported native widgets within the native interface feature since the first public beta. However, this requires native coding and isn’t always trivial. Normally you don’t really need to do that.\nE.g. for text fields we implicitly convert the field to a native field as necessary.\nHowever, if you wish to use the password manager of the device this won’t work. To solve this Steve introduced a new cn1lib: cn1-native-controls. This library wraps some native widgets and lets us use some features that might be tricky without them. Good use cases for this include the password managers which need a native text widget constantly in that sport. Another use case would be iOS’s SMS interception text field that can automatically intercept the next incoming SMS and set it to a special native text field.\nThere are currently two widgets in this library:\nNSelect — which acts like a combo box\nNTextField — which is practically a drop-in replacement for TextField\nYou can use the NTextField like this:\nhi.add(\u0026quot;Text fields\u0026quot;); hi.add(\u0026quot;Username:\u0026quot;); NTextField tf1 = new NTextField(TextField.USERNAME); System.out.println(\u0026quot;Setting font to main light 15mm\u0026quot;); tf1.getAllStyles().setFont(Font.createTrueTypeFont(Font.NATIVE_MAIN_LIGHT, 15f)); System.out.println(\u0026quot;Finished setting font\u0026quot;); tf1.getAllStyles().setFgColor(0x003300); tf1.getAllStyles().setBgTransparency(255); tf1.getAllStyles().setBgColor(0xcccccc); tf1.getAllStyles().setAlignment(CENTER); hi.add(tf1); hi.add(\u0026quot;Password:\u0026quot;); NTextField tf2 = new NTextField(TextField.PASSWORD); hi.add(tf2); hi.add(\u0026quot;Email:\u0026quot;); NTextField emailField = new NTextField(TextField.EMAILADDR); hi.add(emailField); tf1.addActionListener(e-\u0026gt;{ //tf2.setText(tf1.getText()); }); tf1.addChangeListener(e-\u0026gt;{ result.setText(tf1.getText()); hi.revalidateWithAnimationSafety(); }); tf2.addActionListener(e-\u0026gt;{ Log.p(\u0026quot;Action listener fired on password field\u0026quot;); result.setText(tf2.getText()); hi.revalidateWithAnimationSafety(); }); tf2.addDoneListener(e-\u0026gt;{ Log.p(\u0026quot;Done was clicked!!!\u0026quot;); }); Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nCh Hjelm — February 1, 2019 at 12:30 pm (permalink) Ch Hjelm says:\nHi, I tried to use this (I use a local copy of CN1 source, but updated yesterday, I used NTextField in my code, run \u0026ldquo;refresh cn1lib files\u0026rdquo;), but I get this error message:\n` error: cannot find symbol\npublic class NTextFieldNativeImpl implements com.codename1.nui.NTextFieldNative{\nsymbol: class NTextFieldNative\nlocation: package com.codename1.nui`\nWhen I look in the cn1 GitHub repository, I don’t see any ‘nui’ package…\nshannah78 — February 1, 2019 at 1:01 pm (permalink) shannah78 says:\nWhen you first install the lib, you may need to do a clean and build once before it will pick up the native classes.\nCh Hjelm — February 1, 2019 at 7:06 pm (permalink) Ch Hjelm says:\nThanks Steve, I’ve done a clean build, but it doesn’t help. The library is in /lib as it should be, but when I run the \u0026ldquo;refresh cn1lib files\u0026rdquo; I get the below errors.\nCompiling 2 source files to /Users/user1/NetBeansProjects/myapp/native/internal_tmp /Users/user1/NetBeansProjects/myapp/lib/impl/native/javase/com/codename1/nui/NSelectNativeImpl.java:38: error: cannot find symbol public class NSelectNativeImpl implements com.codename1.nui.NSelectNative{ symbol: class NSelectNative location: package com.codename1.nui /Users/user1/NetBeansProjects/myapp/lib/impl/native/javase/com/codename1/nui/NTextFieldNativeImpl.java:3: error: cannot find symbol public class NTextFieldNativeImpl implements com.codename1.nui.NTextFieldNative{ symbol: class NTextFieldNative location: package com.codename1.nui /Users/user1/NetBeansProjects/myapp/lib/impl/native/javase/com/codename1/nui/NSelectNativeImpl.java:61: error: cannot find symbol NSelect.fireSelectionChanged(index); symbol: variable NSelect 3 errors /Users/user1/NetBeansProjects/myapp/build.xml:531: Compile failed; see the compiler error output for details.\nI tried adding it to my Kitchensink example and there it works. Can my build files somehow be corrupted (and any tips on how to fix it – I’m no expert)?\nCh Hjelm — February 2, 2019 at 9:57 am (permalink) Ch Hjelm says:\nI tried a number of things, update the cn1 binaries, recompile my local copy of CN1 sources with Java 8, but nothing helped, I’m stuck with the above errors. Any help or suggestions for what I can investigate would be much appreciated 🙂\nShai Almog — February 3, 2019 at 4:26 am (permalink) Shai Almog says:\nWhat’s the version of the build.xml file? It’s on the top of the file.\nCan you post a screenshot of your build classpath from the netbeans properties?\nCh Hjelm — February 3, 2019 at 10:55 am (permalink) Ch Hjelm says:\nI compared my class paths with the KitchenSink example, and realized I had deleted the lib/impl/, override/ and native/internal_tmp folders. I added them manually, and now it works. That reminded me of somewhere in the CN1 manual there’s a screenshot of the class path list in Netbeans saying don’t change this if you don’t know what you’re doing – I now realize why 🙂 Thanks a lot for pointing me in the right direction.\nCh Hjelm — February 8, 2019 at 12:03 pm (permalink) Ch Hjelm says:\nI would like to use the NTextField in the login screen, and when that screen is shown, automatically enter edit mode for the email field. With a normal TextField I can use Form.setEditOnShow(emailField), but it doesn’t accept the NTextField. Is there some way to achieve the same effect when using the NTextField?\nShai Almog — February 9, 2019 at 6:00 am (permalink) Shai Almog says:\nNo you can’t use it like that. However, you can add an onShow listener and start editing at that point which should be equivalent.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/native-controls/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/native-controls/new-features-4.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe supported native widgets within the \u003ca href=\"/how-do-i---access-native-device-functionality-invoke-native-interfaces.html\"\u003enative interface\u003c/a\u003e feature since the first public beta. However, this requires native coding and isn’t always trivial. Normally you don’t really need to do that.\u003c/p\u003e\n\u003cp\u003eE.g. for text fields we implicitly convert the field to a native field as necessary.\u003c/p\u003e\n\u003cp\u003eHowever, if you wish to use the password manager of the device this won’t work. To solve this Steve introduced a new cn1lib: \u003ca href=\"https://github.com/shannah/cn1-native-controls\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ecn1-native-controls\u003c/a\u003e. This library wraps some native widgets and lets us use some features that might be tricky without them. Good use cases for this include the password managers which need a native text widget constantly in that sport. Another use case would be iOS’s SMS interception text field that can automatically intercept the next incoming SMS and set it to a special native text field.\u003c/p\u003e","title":"Native Controls"},{"content":"\nI’ve been pretty busy this new year with a lot of unpredictable detours. As such I completely missed the deadline of releasing the whatsapp clone application I promissed for the end of year. I’m now in the process of uploading modules into the online course for the WhatsApp clone.\nUnlike previous clones I plan to make this far simpler as a lot of the work was already covered in the Facebook Clone module. This mostly focuses on features that weren’t covered there and fixes some things e.g. SMS activation is handled in the server side.\nThere is still a lot of work to do for Codename One 6 which is slated for February so I hope I’ll be able to push out the WhatsAppClone ASAP.\nReminder xcode 10.1 Goes Live As a reminder, xcode 10.1 will be the default with builds starting tomorrow. If you experience sudden regressions please check out the previous blog post!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/whatsapp-clone/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/whatsapp-clone/build-real-world-full-stack-mobile-apps-in-java.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been pretty busy this new year with a lot of unpredictable detours. As such I completely missed the deadline of releasing the whatsapp clone application I promissed for the end of year. I’m now in the process of uploading modules into the \u003ca href=\"https://codenameone.teachable.com/p/build-real-world-full-stack-mobile-apps-in-java\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eonline course\u003c/a\u003e for the WhatsApp clone.\u003c/p\u003e\n\u003cp\u003eUnlike previous clones I plan to make this far simpler as a lot of the work was already covered in the Facebook Clone module. This mostly focuses on features that weren’t covered there and fixes some things e.g. SMS activation is handled in the server side.\u003c/p\u003e","title":"WhatsApp Clone"},{"content":"\nAs I mentioned recently, we’re migrating to xcode 10.1. This weekend we entered phase 2 of the migration which allows you to test your builds with xcode 10.1. To do this just set the build hint: ios.xcode_version=10.1.\nIf you run into issues with xcode 10.1 builds let us know ASAP. This is very urgent as phased 3 will kick in this coming Friday. In phase 3 we will flip 10.1 as the default which means that builds sent on Friday will implicitly target xcode 10.1.\nIf this produces an unforseen regression you can explicitly force xcode 9.2 for compatibility by using the build hint: ios.xcode_version=9.2.\nThis means you can use the capabilities of the latest xcode/iOS SDK within your native code starting with this update.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/xcode-10-1-migration-phase-2/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/xcode-10-1-migration-phase-2/xcode-migration.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAs I \u003ca href=\"/blog/xcode-10-1-migration.html\"\u003ementioned recently\u003c/a\u003e, we’re migrating to xcode 10.1. This weekend we entered phase 2 of the migration which allows you to test your builds with xcode 10.1. To do this just set the build hint: \u003ccode\u003eios.xcode_version=10.1\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eIf you run into issues with xcode 10.1 builds let us know ASAP. This is very urgent as phased 3 will kick in this coming Friday. In phase 3 we will flip 10.1 as the default which means that builds sent on Friday will implicitly target xcode 10.1.\u003c/p\u003e","title":"Xcode 10.1 Migration Phase 2"},{"content":"\nOver the past month Apple started sending out warnings that they will no longer accept apps built with older SDK’s starting this March. To preempt that we will update our servers to use xcode 10.1 over the next couple of weeks. This change should be seamless for the most part but some odd behaviors or bugs usually rise as a result of such migrations.\nTo test if a sudden regression is caused by this migration you can explicitly force xcode 9.2 for compatibility by using the build hint: ios.xcode_version=9.2.\nWe also considered updating the Android target SDK from 27 to 28 but since that would be a requirement only around August it might make better sense to postpone it to the 7.0 release cycle. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — January 10, 2019 at 11:29 am (permalink) Francesco Galgani says:\nWill do you still use Gradle 4.6? This information can be useful when testing native interfaces.\nShai Almog — January 10, 2019 at 11:52 am (permalink) Shai Almog says:\nRight now we won’t touch the Android side. When we do the migration to 28 we might need newer version of gradle though. We’ll post about it before that migration takes place as we’ll have specific version numbers and setting information.\nFrancesco Galgani — January 10, 2019 at 11:53 am (permalink) Francesco Galgani says:\nOk, thank you\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/xcode-10-1-migration/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/xcode-10-1-migration/xcode-migration.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOver the past month Apple started sending out warnings that they will no longer accept apps built with older SDK’s starting this March. To preempt that we will update our servers to use xcode 10.1 over the next couple of weeks. This change should be seamless for the most part but some odd behaviors or bugs usually rise as a result of such migrations.\u003c/p\u003e\n\u003cp\u003eTo test if a sudden regression is caused by this migration you can explicitly force xcode 9.2 for compatibility by using the build hint: \u003ccode\u003eios.xcode_version=9.2\u003c/code\u003e.\u003c/p\u003e","title":"Xcode 10.1 Migration"},{"content":"\nA somewhat hidden feature of Codename One Settings is the ability to define global settings. Global settings are useful when you have multiple projects and would like to use common defaults. E.g. we have standard certificate definitions for iOS/Android that allow us to just send a device build on a new project without configuring anything.\n__ For iOS this can only work for debug builds and won’t allow features such as push etc. It requires some work…​ Figure 1. The global settings toggle button\nA good use for this is in the Android settings where you can define one certificate for use with all your apps. For iOS you can define the same certificate for all applications as they don’t change between apps. However, you would need a different provisioning profile so for distribution you will need to re-run the wizard and generate only the provisioning.\nThere is a trick for iOS where you can create a \u0026ldquo;generic\u0026rdquo; provisioning profile to the * package/identifier. This can be done via the web UI on apples developer site here: https://developer.apple.com/account/ios/profile/\nYou can generate an \u0026ldquo;AllApps\u0026rdquo; provisioning profile and save it to your disk, then point the debug provisioning to that. Once this is defined, new projects will build on iOS without a single change. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — January 8, 2019 at 10:25 pm (permalink) I was unaware of the \u0026ldquo;AllApps\u0026rdquo; tips, thank you, it can be useful to don’t waste time with signing when we want only to try simple test cases in new projects. I’ve just tried this tip, I noted that to make it working it’s also necessary to set the correct \u0026ldquo;TeamID\u0026rdquo; (the string like 12ABCDEFG8) in the first part of the \u0026ldquo;AppID\u0026rdquo; inside the iOS signing settings of each project (because the default one is not correct). Is there any way to change how the String \u0026ldquo;AppID\u0026rdquo; is generated by Codename One for new projects? I tried to set the TeamID in the iOS signing of global settings, but new projects still have a wrong new AppID, that starts with \u0026ldquo;Q5GHSKAL2F\u0026rdquo;. I noted that \u0026ldquo;Q5GHSKAL2F\u0026rdquo; is used in your demo projects and it’s hard coded in your \u0026ldquo;CodenameOneWizardIterator\u0026rdquo; class of the Netbeans plugin.\nShai Almog — January 9, 2019 at 3:22 am (permalink) Shai Almog says:\nYes the team ID would also be essential, back when we created this feature team ID wasn’t supported so I’m not sure how well it will work in a global configuration. The app id is hardcoded into the wizard, I’ll need to give this some thought.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-global-settings/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-global-settings/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA somewhat hidden feature of Codename One Settings is the ability to define global settings. Global settings are useful when you have multiple projects and would like to use common defaults. E.g. we have standard certificate definitions for iOS/Android that allow us to just send a device build on a new project without configuring anything.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eFor iOS this can only work for debug builds and won’t allow features such as push etc. It requires some work…​\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e\u003cimg alt=\"The global settings toggle button\" loading=\"lazy\" src=\"/blog/tip-global-settings/global-settings.png\"\u003e\u003c/p\u003e","title":"TIP: Global Settings"},{"content":"\nHappy holidays, Merry Christmas, happy new year to all. All of us here at Codename One hope you have a lovely vacation if you are taking one. Since half of our readership is from countries that celebrate these holidays it seems like a good time to take a short blogging vacation as well.\nDuring this time we won’t blog and won’t make releases unless there are crucial issues. We’re still here for support but some things will be pushed into January. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDiamond — December 18, 2018 at 3:43 pm (permalink) Diamond says:\nHappy Holidays to you too 🙂\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/see-you-2019/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/see-you-2019/happy-holidays.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eHappy holidays, Merry Christmas, happy new year to all. All of us here at Codename One hope you have a lovely vacation if you are taking one. Since half of our readership is from countries that celebrate these holidays it seems like a good time to take a short blogging vacation as well.\u003c/p\u003e\n\u003ch2 id=\"during-this-time-we-wont-blog-and-wont-make-releases-unless-there-are-crucial-issues-were-still-here-for-support-but-some-things-will-be-pushed-into-january\"\u003eDuring this time we won’t blog and won’t make releases unless there are crucial issues. We’re still here for support but some things will be pushed into January.\u003c/h2\u003e\n\u003ch2 id=\"archived-comments\"\u003eArchived Comments\u003c/h2\u003e\n\u003cp\u003e\u003cem\u003eThis post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\u003c/em\u003e\u003c/p\u003e","title":"See You in 2019"},{"content":"\nOne of my pet peeves is the \u0026ldquo;Are you sure?\u0026rdquo; dialog. I’ve used it a lot myself because it’s the \u0026ldquo;easy way out\u0026rdquo;, but when possible I try to avoid it. This is especially important in mobile where constant prompts really slow down the workflow.\nThe trick that lets us avoid the \u0026ldquo;Are you sure?\u0026rdquo; dialog is the undo option. Once you can undo an operation you can move fast and let users reconsider later. With file deletion this is a bit harder. Most OS’s provide a trash can abstraction. This doesn’t exist in mobile devices where apps are effectively segregated from one another. However, implementing our own trash can is pretty trivial.\nThese are methods I use in one of our util classes, they aren’t public API’s because they are too high level for the API. But they might be useful for you. First we need copy and move operations. Notice, I didn’t use file system rename since different file systems might be isolated on the device and might not allow a rename:\npublic static void copyFile(String sourceFile, String destFile) throws IOException { try (InputStream source = openFileInputStream(sourceFile); OutputStream dest = openFileOutputStream(destFile)) { Util.copy(source, dest); } } public static void moveFile(String sourceFile, String destFile) throws IOException { copyFile(sourceFile, destFile); delete(sourceFile); } The next stage is a trash abstraction. We add a Trash directory which we create dynamically. We then move the file to a dummy name in the trash to delete it. Empty trash might be something you can expose to the user or just invoke on startup/exit.\npublic static String moveToTrash(String file) { try { String trash = getAppHomePath() + \u0026quot;Trash/\u0026quot;; mkdir(trash); String trashName = trash + System.currentTimeMillis(); moveFile(file, trashName); return trashName; } catch(IOException err) { Log.e(err); return null; } } public static void emptyTrash() { try { String trash = getAppHomePath() + \u0026quot;Trash/\u0026quot;; mkdir(trash); String[] arr = listFiles(trash); for(String f : arr) { delete(trash + f); } } catch(IOException err) { Log.e(err); } } Last but not least we have the undoable delete. The autoFlash option allows us to automatically delete the file after 10 seconds if it wasn’t restored. This is accomplished by launching a thread to delete the file later. We also send a callback in the case of an undelete so a user can update the UI.\npublic static void undoableDelete(String file, boolean autoFlush, Runnable onUndelete) { String trashFile = moveToTrash(file); ToastBar.showMessage(\u0026quot;Deleted \u0026quot; + file.substring(file.lastIndexOf('/') + 1) + \u0026quot;nTouch to undo\u0026quot;, FontImage.MATERIAL_UNDO, e -\u0026gt; { try { moveFile(trashFile, file); onUndelete.run(); } catch(IOException err) { Log.e(err); ToastBar.showErrorMessage(\u0026quot;An error occurred on file restore\u0026quot;); } }); if(autoFlush) { startThread(() -\u0026gt; { Util.sleep(10000); if(existsInFileSystem(trashFile)) { delete(trashFile); } }, \u0026quot;Delete Trash\u0026quot;); } } I used a toastbar to show the undo message, you might want to provide more ways to undo a delete depending on the case. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — January 6, 2019 at 9:10 am (permalink) Francesco Galgani says:\nThank you for these useful methods. Can you please confirm that all of them are to be used with FIleSystemStorage and not with Storage?\nShai Almog — January 6, 2019 at 11:53 am (permalink) Shai Almog says:\nThis was specifically designed for file system storage but can easily be adapted to support Storage. E.g. moveToTrash can check if the file is in storage by checking if startsWith(\u0026ldquo;file://\u0026rdquo;) that would only change the opening of the file code. The Trash directory would still be in the file system storage.\ncopyFile and deleteFile can be similarly adapted to detect a storage file and use the storage API instead of the FileSystemStorage API.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-undo-delete/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-undo-delete/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of my pet peeves is the \u0026ldquo;Are you sure?\u0026rdquo; dialog. I’ve used it a lot myself because it’s the \u0026ldquo;easy way out\u0026rdquo;, but when possible I try to avoid it. This is especially important in mobile where constant prompts really slow down the workflow.\u003c/p\u003e\n\u003cp\u003eThe trick that lets us avoid the \u0026ldquo;Are you sure?\u0026rdquo; dialog is the undo option. Once you can undo an operation you can move fast and let users reconsider later. With file deletion this is a bit harder. Most OS’s provide a trash can abstraction. This doesn’t exist in mobile devices where apps are effectively segregated from one another. However, implementing our own trash can is pretty trivial.\u003c/p\u003e","title":"TIP: Undo Delete"},{"content":"\nI wrote in the past about the problems in the List class, so I won’t rehash them here. However, the ideas behind list are still valuable. One such idea is the list model which allows us to separate the state from the view. Unfortunately the renderer architecture makes this hard to implement for most developers and limits the flexibility of the API.\nTo leverage this idea with the easier to use layout/container hierarchy we introduced ButtonList and its subclasses: CheckBoxList, RadioButtonList \u0026amp; SwitchList.\nWe also added a new MultipleSelectionListModel which extends the ListModel with multi-selection capabilities. This allows us to use a set of buttons as we would use a list and also generate them from data more easily.\nIn the code below we show two lists that use the same model. Changes to the checkboxes reflect instantly in the switch and vice versa:\nForm hi = new Form(\u0026quot;Button Lists\u0026quot;, new BorderLayout()); SwitchList switchList = new SwitchList(new DefaultListModel(\u0026quot;Red\u0026quot;, \u0026quot;Green\u0026quot;, \u0026quot;Blue\u0026quot;, \u0026quot;Indigo\u0026quot;)); switchList.addActionListener(e-\u0026gt;{ Log.p(\u0026quot;Selected indices: \u0026quot;+Arrays.toString(switchList.getMultiListModel().getSelectedIndices())); }); __**(1)** switchList.setScrollableY(true); Button clearSelections = new Button(\u0026quot;Clear\u0026quot;); clearSelections.addActionListener(e -\u0026gt; switchList.getMultiListModel().setSelectedIndices()); Button addOption = new Button(\u0026quot;Add Option\u0026quot;); addOption.addActionListener(e -\u0026gt; { __**(2)** callSerially(()-\u0026gt;{ TextField val = new TextField(); Command res = Dialog.show(\u0026quot;Enter label\u0026quot;, val, new Command(\u0026quot;OK\u0026quot;)); switchList.getMultiListModel().addItem(val.getText()); }); }); RadioButtonList layoutSelector = new RadioButtonList(new DefaultListModel(\u0026quot;Flow\u0026quot;, \u0026quot;X\u0026quot;, \u0026quot;Y\u0026quot;, \u0026quot;2-Col Table\u0026quot;, \u0026quot;3-Col Table\u0026quot;, \u0026quot;2 Col Grid\u0026quot;, \u0026quot;3 Col Grid\u0026quot;)); layoutSelector.addActionListener(e-\u0026gt;{ __**(3)** boolean yScroll = true; switch (layoutSelector.getModel().getSelectedIndex()) { case 0: switchList.setLayout(new FlowLayout()); break; case 1: switchList.setLayout(BoxLayout.x()); yScroll = false; break; case 2: switchList.setLayout(BoxLayout.y()); break; case 3: switchList.setLayout(new TableLayout(switchList.getComponentCount()/2+1, 2)); break; case 4: switchList.setLayout(new TableLayout(switchList.getComponentCount()/3+1, 3)); break; case 5: switchList.setLayout(new GridLayout(2)); break; case 6: switchList.setLayout(new GridLayout(3)); } switchList.setScrollableX(!yScroll); switchList.setScrollableY(yScroll); switchList.animateLayout(300); }); CheckBoxList checkBoxList = new CheckBoxList(switchList.getMultiListModel()); __**(4)** checkBoxList.addActionListener(e-\u0026gt; System.out.println(\u0026quot;CheckBox actionEvent. \u0026quot;+Arrays.toString(checkBoxList.getMultiListModel().getSelectedIndices()))); hi.add(BorderLayout.NORTH, layoutSelector); hi.add(BorderLayout.CENTER, BoxLayout.encloseY(checkBoxList, switchList)); hi.add(BorderLayout.SOUTH, GridLayout.encloseIn(2, addOption, clearSelections)); hi.show(); __1 Instead of binding multiple listeners we can bind a listener to the list itself and get the selections __2 It’s easy to add options like clear selection and add option thanks to the structure of the list model __3 This list uses a layout as it’s in-effect just a Container __4 The CheckBoxList uses the same model as the SwitchList Figure 1. Demo of the button list classes Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — December 8, 2018 at 11:14 am (permalink) Great! However, in this example, there is an issue: the \u0026ldquo;Add Option\u0026rdquo; works fine with iOS skin, but it doesn’t work as expected on Android skin (because it’s necessary to change the layout to see the new added Button). I done tests with \u0026ldquo;iPhoneX.skin\u0026rdquo; and \u0026ldquo;GooglePixel2.skin\u0026rdquo;\nFrancesco Galgani — December 8, 2018 at 11:14 am (permalink) Francesco Galgani says:\nWhy do you use the callSerially in the ActionListener of the addOption button?\nFrancesco Galgani — December 8, 2018 at 11:14 am (permalink) Francesco Galgani says:\nTo create the DefaultListModel, you used a list of Strings as args. Is it possible to bind the DefaultListModel with a list of BooleanProperty as args? It could be an interesting enhancement to seamlessly map the user selections in a ButtonList with a PropertyBusinessObject.\nShai Almog — December 8, 2018 at 1:46 pm (permalink) Shai Almog says:\nThe strings map to the labels matching the entries, the models map to the selection which is an integer or set of integers. A boolean would be a problem as you can’t get the labels from the boolean values. However, it would probably be easy to map this to boolean property objects as the model selection logic can be a great place to do that.\nI use the callSerially because of the Dialog.show that follows. It allows the event queue to flush before we block it.\nThere is an issue which wasn’t noticeable to me because of the different animations for the dialog showing. We need a hi.revalidate() in the end of the callSerially invocation.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/button-lists/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/button-lists/new-features-4.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI wrote in the past about the \u003ca href=\"/blog/avoiding-lists.html\"\u003eproblems in the List class\u003c/a\u003e, so I won’t rehash them here. However, the ideas behind list are still valuable. One such idea is the list model which allows us to separate the state from the view. Unfortunately the renderer architecture makes this hard to implement for most developers and limits the flexibility of the API.\u003c/p\u003e\n\u003cp\u003eTo leverage this idea with the easier to use layout/container hierarchy we introduced \u003ccode\u003eButtonList\u003c/code\u003e and its subclasses: \u003ccode\u003eCheckBoxList\u003c/code\u003e, \u003ccode\u003eRadioButtonList\u003c/code\u003e \u0026amp; \u003ccode\u003eSwitchList\u003c/code\u003e.\u003c/p\u003e","title":"Button Lists"},{"content":"\nWe talked about our support for Progressive Web Apps before. We added quite a few enhancements since that support was introduced and it’s a pretty powerful feature. Personally I consider it a killer feature, even if Google decides to ban your account you can still distribute your app.\nOne of the cool features is the seamlessness. Most of the functionality \u0026ldquo;just works\u0026rdquo;. However, there are some cases where we need explicit hints due to the different behavior of desktop/mobile and web.\nOne such case is installation. PWA’s support an icon on the device home screen, but you need to explicitly ask the browser to install that icon. That’s unique to PWA’s and requires a new API to support that behavior. That’s why we introduced onCanInstallOnHomescreen, canInstallOnHomescreen() and promptInstallOnHomescreen() to help with that process. You can use them as:\nonCanInstallOnHomescreen(()-\u0026gt;{ if (canInstallOnHomescreen()) { if (promptInstallOnHomescreen()) { // User accepted installation } else { // user rejected installation } } }); __ This code expects import static com.codename1.ui.CN.*; The code would prompt the user to install on the home screen in OS’s where this is appropriate. Notice that this will prompt the user once to install on the home screen so you don’t need additional guards against duplicate prompts.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/install-home-screen/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/install-home-screen/html5-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe talked about our support for \u003ca href=\"/blog/progressive-web-apps.html\"\u003eProgressive Web Apps before\u003c/a\u003e. We added quite a few enhancements since that support was introduced and it’s a pretty powerful feature. Personally I consider it a killer feature, even if Google decides to \u003ca href=\"https://www.reddit.com/r/androiddev/comments/9mpyyi/google_play_developer_account_terminated_due_to/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eban your account\u003c/a\u003e you can still distribute your app.\u003c/p\u003e\n\u003cp\u003eOne of the cool features is the seamlessness. Most of the functionality \u0026ldquo;just works\u0026rdquo;. However, there are some cases where we need explicit hints due to the different behavior of desktop/mobile and web.\u003c/p\u003e","title":"Install on Home Screen"},{"content":"\nOne of the things I like most about our subscription base is its solid nature. We still have a lot of subscribers in the $9 per month plan which we discontinued several years ago (it was so long ago I can’t find the relevant blog post anymore). That’s wonderful, it means people like our product and are with us for the long run.\nHowever, flexibility is important too. The fact that subscriptions can be canceled easily is important. Canceling subscriptions is easy although we don’t have any control over that.\nWhen you sign up for a subscription you effectively define a PayPal recurring payment process associated with your account. When we get a payment we keep the account at that level.\nTo cancel the subscription you need to login to paypal and cancel the recurring payment there. If this isn’t obvious to you we can do that (although we can’t change anything about the subscription, only cancel it). Just use the chat and give us the account email and paypal email addresses (assuming they differ).\nProblematic Upgrades We chose this approach for simplicity and security. This way we have no valuable credit card or billing information on our servers. This reduces their appeal to would be hackers. It also lets us focus on our business instead of billing etc.\nOne of the problems with this system is that we don’t have control over payment. We can’t fix mistakes and some things aren’t as seamless as they should be. One such thing is upgrades. If you upgrade your account or resubscribe on billing failure you can end up with two payments on the same account. These things are hard to detect due to some complex assumptions made in the system. So it’s crucial you cancel old payments when upgrading.\nIf you run into billing issues be sure to contact our support, using the chat button. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbaron — December 1, 2018 at 10:27 am (permalink) baron says:\ni hope to create subscribe with specific thing e.g:\n– i want just create app for android but the jar file is more 50MB\nin this case i can select ok for Android Builds features in my subscribe and dispose another things i don’t need it .\n-on anther hand the price is increase whenever increase select many of features.\nShai Almog — December 2, 2018 at 7:16 am (permalink) Shai Almog says:\nThe price is fixed additional features don’t change that. You can’t create apps with jars larger than 50mb see this https://help.codenameone.co…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-canceling-subscriptions/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-canceling-subscriptions/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the things I like most about our subscription base is its solid nature. We still have a lot of subscribers in the $9 per month plan which we discontinued several years ago (it was so long ago I can’t find the relevant blog post anymore). That’s wonderful, it means people like our product and are with us for the long run.\u003c/p\u003e\n\u003cp\u003eHowever, flexibility is important too. The fact that subscriptions can be canceled easily is important. Canceling subscriptions is easy although we don’t have any control over that.\u003cbr\u003e\nWhen you sign up for a subscription you effectively define a PayPal recurring payment process associated with your account. When we get a payment we keep the account at that level.\u003c/p\u003e","title":"TIP: Canceling Subscriptions"},{"content":"\nBox layout Y is one of the most used layouts in Codename One. It’s a wonderful, easy to use layout that makes vertical scrollable layout trivial. I love its simplicity, but sometimes that simplicity goes too far. A good example of that is the a common layout where we have a button at the bottom of the screen.\nHistorically we solved this by nesting box into a border layout:\nForm f = new Form(\u0026quot;Border Layout\u0026quot;, new BorderLayout()); __**(1)** Container box = new Container(BoxLayout.y()); box.setScrollableY(true); __**(2)** Button b = new Button(\u0026quot;Add New Button\u0026quot;); b.addActionListener(e -\u0026gt; { MultiButton mb = new MultiButton(\u0026quot;Added Button\u0026quot;); box.addComponent(0, mb); mb.setWidth(f.getWidth()); mb.setY(f.getHeight()); box.animateLayout(150); }); f.add(SOUTH, b); f.add(CENTER, box); f.show(); __1 Border layout implicitly disables the default scrolling of the Form __2 Because of that we need to scroll the box layout When launched the UI looks like this:\nFigure 1. Newly launched UI\nFigure 2. After adding a couple of elements it looks like this\nFigure 3. After adding a lot of elements it looks like this\nNow this might be what you want. The add button is always clearly visible and easily accessible. However, in some cases this doesn’t work.\nLets say you want this exact behavior like we see in the first two images. But once we reach the edge of the form you want the button to act as if this was a regular box layout. Effectively the button would either align to the bottom of the form or the edge of the layout.\nTo accomplish this we are adding a new yLast mode in the BoxLayout which can be created using BoxLayout.yLast() or new BoxLayout(BoxLayout.Y_AXIS_BOTTOM_LAST). E.g the code below will produce the exact same result for the first two images:\nForm f = new Form(\u0026quot;Border Layout\u0026quot;, BoxLayout.yLast()); __**(1)** Button b = new Button(\u0026quot;Add New Button\u0026quot;); b.addActionListener(e -\u0026gt; { MultiButton mb = new MultiButton(\u0026quot;Added Button\u0026quot;); f.addComponent(0, mb); mb.setWidth(f.getWidth()); mb.setY(f.getHeight()); f.getContentPane().animateLayout(150); }); f.add(b); f.show(); __1 Box layout doesn’t disable the default scrollability of form When it’s completely filled the button is pushed down out of the view area:\nFigure 4. The button scrolls down when there is no more space\nI like this approach as it reduces clutter for the UI and leaves more space available. It doesn’t fit for all cases but it’s a valuable addition to the API. These changes will be available with the update we’ll release this Friday. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — November 29, 2018 at 7:08 am (permalink) Why did you use f.addComponent(0, mb);?\nShai Almog — November 29, 2018 at 7:35 am (permalink) This adds the component to the first index in the component list. When I call add(Component) or addComponent(Component) it adds the component at the last offset which in this case will replace the existing \u0026ldquo;last component\u0026rdquo;. Here I added it to the top so a new entry will always appear first.\nFrancesco Galgani — November 29, 2018 at 7:46 am (permalink) So in your example all the MultiButtons are disposed in inverted order of insertion, right? And if we want that every new MultiButton is added as penultimate?\nShai Almog — November 29, 2018 at 8:24 am (permalink) No buttons are disposed but the new button is added to the top of the list instead of the bottom. That way the last button is always the add button.\nFrancesco Galgani — November 29, 2018 at 11:21 am (permalink) Francesco Galgani says:\nThank you for the quick reply. I’m sorry, my mistake: \u0026ldquo;disposed\u0026rdquo; is a false friend in my language, I wrote a thing thinking another. I understood your first reply. My question, in your example, is how to place the new added multibuttons to the bottom of list instead to the top. I mean if it’s possible something like: addComponent(n-2), where n is the number of added components to the container (plus the one we are going to add), n-1 is the Button always in the bottom, n-2 is the place to add a new multibutton. I guess that it’s not possible in this way.\nShai Almog — November 29, 2018 at 11:45 am (permalink) Shai Almog says:\nIt’s possible to call it that way. I just wanted to keep the code a bit simpler without a \u0026ldquo;weird\u0026rdquo; – offset calculation. I think it would be \u0026ldquo;cmpCount -1\u0026rdquo; but it might be \u0026ldquo;cmpCount -2\u0026rdquo; I don’t recall.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/bottom-align/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/bottom-align/new-features-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eBox layout Y is one of the most used layouts in Codename One. It’s a wonderful, easy to use layout that makes vertical scrollable layout trivial. I love its simplicity, but sometimes that simplicity goes too far. A good example of that is the a common layout where we have a button at the bottom of the screen.\u003c/p\u003e\n\u003cp\u003eHistorically we solved this by nesting box into a border layout:\u003c/p\u003e","title":"Bottom Align"},{"content":"\nA few years back we had Codename One LIVE!\nIt allowed developers to preview designs built with the old GUI builder on devices. Today we’re introducing the equivalent functionality for the new GUI builder and the Codename One Build app. Cloud Connect allows you to instantly see changes from the GUI builder in the app.\nYou can activate Cloud Connect using the new Cloud Connect button in the latest version of the GUI builder. Once it’s activated launch Codename One Build and open the side menu, you should see a new Cloud Connect option in the side menu.\n__ You might need to kill and relaunch the app the first time around to make that menu appear Check out the new How Do I video that covers the whole process.\nThis is a remarkably useful feature as it allows us to instantly see the nuanced impact of choices we make within the GUI builder. Small alignment or boundary choices within the tool can have a significant impact when you’re running on the device. Fonts and styles can look very different on the physical device than they do within the GUI builder.\nBut even more importantly, scrolling behavior and editing is impacted by design choices. E.g. in the video I made the login form scrollable. This isn’t something I thought I needed initially, but as I played with the UI on smaller devices it became apparent that this form must be scrollable. Using cloud connect saved me from the frustration of \u0026ldquo;compile → deploy → repeat\u0026rdquo;. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\ncodelessfuture — November 20, 2018 at 11:00 am (permalink) codelessfuture says:\nHave you had some copy \u0026amp; paste problem?\nShai Almog — November 20, 2018 at 11:02 am (permalink) Shai Almog says:\nWhat do you mean?\nShai Almog — November 20, 2018 at 11:07 am (permalink) Shai Almog says:\nOK, I see it now. It must have picked a command-c when I was in a different desktop… Will fix this soon.\nBoniface N. Githinji — November 20, 2018 at 11:38 am (permalink) Boniface N. Githinji says:\n@codenameone:disqus Good job. Without this feature, developing apps on CN1 caused quite the headache especially when one need to see how that 2mm padding looks on the real device. Definitely gonna try it out.\nOn other news, I am internally grateful to you and your team. I have now built 10+ apps on this great platform and I can attest that there’s nothing as good. Here’s my latest – https://play.google.com/sto… a carpooling app used in Kenya.\nhttps://uploads.disquscdn.c…\nhttps://uploads.disquscdn.c… https://uploads.disquscdn.c… https://uploads.disquscdn.c… https://uploads.disquscdn.c…\nShai Almog — November 21, 2018 at 7:08 am (permalink) Shai Almog says:\nLooks great!\nChen Fishbein — November 22, 2018 at 7:19 am (permalink) Chen Fishbein says:\nNice job!!!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/introducing-cloud-connect/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/introducing-cloud-connect/codename-one-build.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA few years back we had Codename One LIVE!\u003cbr\u003e\nIt allowed developers to preview designs built with the old GUI builder on devices. Today we’re introducing the equivalent functionality for the new GUI builder and the Codename One Build app. Cloud Connect allows you to instantly see changes from the GUI builder in the app.\u003c/p\u003e\n\u003cp\u003eYou can activate Cloud Connect using the new Cloud Connect button in the latest version of the GUI builder. Once it’s activated launch Codename One Build and open the side menu, you should see a new Cloud Connect option in the side menu.\u003c/p\u003e","title":"Introducing Cloud Connect"},{"content":"\nI’ve been pretty busy over the past few weeks and didn’t get a chance to write a \u0026ldquo;what’s new\u0026rdquo; post. This caused a huge backlog of new features which I’ll try to cut down in this post.\nUI Validation This is a feature that’s coming in the Friday update. Component inspector has a new \u0026ldquo;Validate\u0026rdquo; button that checks the UI for common mistakes. Right now it only checks for nested scrollables on the Y axis but ideally we should include additional checks.\nThis could be a pretty useful tool to diagnose common programming errors in the UI.\nMaterial Commands Command has a new factory method:\npublic static Command createMaterial(String name, char icon, ActionListener ev); Using this API you can create a Command object with the given material icon.\nFixing Revalidate This is a big one: revalidateWithAnimationSafety().\nCodename One was inspired by Swing which didn’t have animations. We added them but our model for animations was too simplistic when we launched. We later refined it with the animation manager which was a huge overhaul.\nHere’s the problem. Let’s say you have an animation running and you invoke component.remove() during the animation. It’s very likely remove() will disrupt the animation. So we serialized all calls to methods that mutate the UI. This means that if an animation is in progress it will wait for it to complete before doing the operation.\nWhile this broke some edge case behaviors this was relatively compatible and worked reasonably well.\nThe problem is we didn’t change revalidate(). We left it \u0026ldquo;as is\u0026rdquo; and didn’t think it was a problem. It’s a complex method which impacts a lot of core functionality so leaving it in place was probably a good call.\nHowever, for most cases you might want to use the new revalidateWithAnimationSafety() which makes sure animations aren’t disrupted by revalidate().\nComponent Ownership Component.setOwner(), Component.isOwnedBy() and Component.containsOrOwns(x,y) allow components to denote an ownership hierarchy. This allows you to more easily track relationships hierarchical relationships between components that don’t happen to descendents of each other – e.g. for popup dialogs that are actually contained in a layered pane but are logically owned by components in the content pane. This is used by Dialog and InteractionDialog to better test for pointer events that occur outside their bounds. Now Dialog.setDisposeWhenPointerOutOfBounds() regards an event to be in bounds if it occurs on a component that is owned by the Dialog (or by a component in the dialog). The Picker, AutocompleteTextField and ComboBox popup dialogs have been updated to track their owner so that they behave appropriately. If you develop your own popups that are placed in the layered pane, it is up to you to set their owner appropriately using Component.setOwner() so that dialogs can deal with their pointer events properly.\nThere is no special house-keeping for the owner hierarchy. E.g. If you remove an owner from the form, it doesn’t do anything like remove its owned components also. It is up to you (the developer) to manage these relationships.\nBadges on Android We added limited support for badges in the Android port. Now Push type 101 is supported on Android as well. Also LocalNotification.setBadgeNumber(int) is supported. Notable omissions are push type 100 and Display.setBadgeNumber(int) which are still not supported. Android, while supporting badges on API 22 and above still can only set it in conjunction with a notification, so APIs that just set the badge number still can’t be implemented.\nrotateRadian Rotate works with absolute coordinates which in retrospect might have been a poor choice. We can’t change that as due to backward compatibility. So we added a new method rotateRadian() that rotate graphics context about the context’s current origin, taking into account translation.\nZoom Enhancements on ImageViewer Carlos Verdier submitted a a pull request that adds a method to zoom to a specific location panning the image. As part of that change zoom is now animated by default.\nYou can disable zoom animations on ImageViewer using setAnimateZoom(false).\nFontImage Rotation Multiple icon fonts include rotating glyphs to indicate progress. While it’s trivial to rotate a FontImage we wanted to make it even simpler. As a result we added the method FontImage rotateAnimation() to FontImage. It returns a new FontImage instance using the same font/icon as the current font image. This new image is an animation that rotates to the right constantly.\nYou can use that in any Label subclass and it will animate the rotation constantly.\nEfficient getRGB Image.getRGB() isn’t very efficient as it might trigger the creation of a new array when it’s invoked. Dave Dyer submitted a new pull request that adds a new getRGB variant. This variant accepts an existing int[] array and fills it up instead of returning the array.\nThis reduces RAM allocation and is ultimately more efficient as a result.\nPicker Rage Limits One of the biggest RFE’s for the old Picker was the ability to determine ranges. Now that we have a lightweight picker implementation this is possible in a cross platform way:\npublic void setHourRange(int min, int max); public void setStartDate(Date start); public void setEndDate(Date end); This lets you limit the range of hours or dates in a lightweight Picker so a user won’t be able to pick outside of that range.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/validate-owner-badges-imageviewer-picker-range/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/validate-owner-badges-imageviewer-picker-range/new-features-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been pretty busy over the past few weeks and didn’t get a chance to write a \u0026ldquo;what’s new\u0026rdquo; post. This caused a huge backlog of new features which I’ll try to cut down in this post.\u003c/p\u003e\n\u003ch3 id=\"ui-validation\"\u003eUI Validation\u003c/h3\u003e\n\u003cp\u003eThis is a feature that’s coming in the Friday update. Component inspector has a new \u0026ldquo;Validate\u0026rdquo; button that checks the UI for common mistakes. Right now it only checks for nested scrollables on the Y axis but ideally we should include additional checks.\u003c/p\u003e","title":"Validate, Owner, Badges, ImageViewer and Picker Range"},{"content":"\nApple introduced push notification at a time when iOS apps didn’t support multi-tasking. It was used as an intrusive notification system that allowed an app to communicate it had something important to tell you. Back then push messages would trigger a dialog box as it predated the pull down notification tray pioneered by Android.\nThe purpose of push on iOS is visual notification. You can send non-visual meta-data but that’s almost an afterthought in iOS.\nOn Android push was designed as an overarching general purpose communication protocol. It’s far more powerful and Google wanted developers to use it as the actual communication protocol. In fact the visual notification of push in Android is almost an afterthought and is handled by background code within the activity.\nDevelopers coming from the Android ecosystem tend to think of push as a communication protocol and want to use that. That’s a bad idea for iOS and not a great idea for Android either.\nWe suggest using a proper communication protocol e.g. WebSockets. You should use push only for marketing related notifications and application notices in the background. That is far more portable, powerful and doesn’t suffer from the limitations of push (e.g. permissions).\nE.g. in Codename One Build we use networking as such:\nMost logic is handled through WebServices – these are use easy to build/maintain and debug\nEvents such as a new build are sent thorough a WebSocket connection – that removes the need for polling and is very fast\nWhen a build is completed we send a push notification and a WebSocket event – if the app is running the WebSocket event will work. If it isn’t you will get push notification notice. If you disable push notifications everything would still work\nThis is the best approach for networking infrastructure and we recommend most apps follow this approach. Here are a few problems in push:\nPush needs to go thru the Apple/Google servers which are unreliable complex and incompatible\nPush doesn’t work everywhere e.g. kindle or all ports e.g. JavaScript push doesn’t work for all browsers\nPush can be disabled by the user which means you literally can’t rely on it working even on supported platforms\nYou need your own servers to handle the push sending and batching anyway so you won’t be able to go \u0026ldquo;serverless\u0026rdquo; with push\nPush enforces size limits on messages\nPush doesn’t \u0026ldquo;really\u0026rdquo; work when an app is in the background in iOS. In iOS a push notification that includes a visual payload will show that e.g. an icon, badge, message, sound etc. even in a background app. However, the non-visual payload won’t be delivered to your app if it isn’t running\nAll things considered push makes sense only for visual notifications and marketing as an addition to your communication protocol not as a replacement.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-dont-use-push-as-communication-protocol/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-dont-use-push-as-communication-protocol/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eApple introduced push notification at a time when iOS apps didn’t support multi-tasking. It was used as an intrusive notification system that allowed an app to communicate it had something important to tell you. Back then push messages would trigger a dialog box as it predated the pull down notification tray pioneered by Android.\u003c/p\u003e\n\u003cp\u003eThe purpose of push on iOS is visual notification. You can send non-visual meta-data but that’s almost an afterthought in iOS.\u003c/p\u003e","title":"TIP: Don't Use Push as a Communication Protocol"},{"content":"\nA while back Steve wrote about auto-renewing subscriptions and I recently got a chance to implement such a subscription in an app. However, it seems that all the changes in the world of in-app purchase created a situation where API’s work in some cases and don’t work for all of them.\n__ After publishing this post we walked back on this, you now need to use subscribe for subscriptions again! In the blog post, Steve used the purchase(sku) API to subscribe. This worked correctly as subscriptions are determined by the respective app store. As I implemented this code I chose to use the subscribe(sku) method which seems to make more sense. Unfortunately it doesn’t work and would be deprecated with the update this Friday.\nIt seems to work and even works on Android/iOS however, it doesn’t work with the receipt API which is an important part of the IAP workflow.\nDespite a lot of the work we did for IAP it’s still one of the more painful API’s we need to work with. Dealing with the server side API is a nightmare. I hope we’ll come up with a better implementation for that moving forward.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/subscription-pitfall/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/subscription-pitfall/in-app-purchase.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA while back \u003ca href=\"/blog/autorenewing-subscriptions-in-ios-and-android.html\"\u003eSteve wrote about auto-renewing subscriptions\u003c/a\u003e and I recently got a chance to implement such a subscription in an app. However, it seems that all the changes in the world of in-app purchase created a situation where API’s work in some cases and don’t work for all of them.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eAfter publishing this post we walked back on this, you now need to use subscribe for subscriptions again!\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eIn the blog post, Steve used the \u003ccode\u003epurchase(sku)\u003c/code\u003e API to subscribe. This worked correctly as subscriptions are determined by the respective app store. As I implemented this code I chose to use the \u003ccode\u003esubscribe(sku)\u003c/code\u003e method which seems to make more sense. Unfortunately it doesn’t work and would be deprecated with the update this Friday.\u003c/p\u003e","title":"Subscription Pitfall"},{"content":"\nCrisp powers the chat button in the bottom right portion of our site. It also handles emails and a host of other great features. One feature we didn’t take advantage of is the mobile app support. To solve that we just issued a new Crisp cn1lib which we integrated into the new versions of our Android and iOS apps.\nYou can install it yourself using the extension manager and use it with the instructions here.\nThere is some implementation detail related to the library which I think would be interesting to developers building similar solutions.\nWhy HTML/JS and Not Native? When I started the work of porting the library I looked at the Crisp native SDKs for iOS/Android. I even got some code working but as I looked through the actual SDK source code it became apparent that Crisps native SDKs for iOS and Android don’t leverage native functionality. This is perfectly OK as HTML/JS can deliver a fine experience for this type of app.\nHowever, its silly to wrap the native libraries when I can use HTML directly and get greater portability. As a result of that I threw away the code I wrote for the original integration and used the HTML approach. This highlights the importants of reviewing the implementation before we start implementing a cn1lib. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nBoniface N. Githinji — October 26, 2018 at 3:37 pm (permalink) Boniface N. Githinji says:\nGreat job Shai. I’d love to re-style the FAB button – change the bg color. Any pointers on how I could do this? I tried ‘Crisp.getInstance().chatFab().getAllStyles().setBgColor(0x24d07a);’ but this didn’t work. FAB still had the red color.\nThank you.\nBoniface N. Githinji — October 26, 2018 at 3:44 pm (permalink) Boniface N. Githinji says:\nGot it to work by overriding the ‘FloatingActionButton’ UUID. Changed BgColor to 24d07a.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/crisp-cn1lib/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/crisp-cn1lib/new-features-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCrisp powers the chat button in the bottom right portion of our site. It also handles emails and a host of other great features. One feature we didn’t take advantage of is the mobile app support. To solve that we just issued a new \u003ca href=\"https://github.com/codenameone/CrispCodenameOneSDK\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCrisp cn1lib\u003c/a\u003e which we integrated into the new versions of our \u003ca href=\"/blog/build-app-beta/\"\u003eAndroid\u003c/a\u003e and \u003ca href=\"/blog/build-app-on-ios/\"\u003eiOS\u003c/a\u003e apps.\u003c/p\u003e\n\u003cp\u003eYou can install it yourself using the extension manager and use it with the instructions \u003ca href=\"https://github.com/codenameone/CrispCodenameOneSDK\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere\u003c/a\u003e.\u003c/p\u003e","title":"Crisp cn1lib"},{"content":"\nWe launched the Codename One Build App beta on Android last week and now we have a public beta for iOS as well. You can sign up to join the public beta through this link. Notice that you will need testflight on your device to join the public beta test.\nAs is the case with the Android version please let us know if there are issues you experience in the issue tracker. The app mostly \u0026ldquo;just worked\u0026rdquo; on iOS but getting through the approval and submission process is always a pain. As part of that work we also improved the tablet UI which makes the app very usable on the iPad.\nWe’re refining the app further and hopefully we’ll bring it to production grade soon.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/build-app-on-ios/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/build-app-on-ios/codename-one-build.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe \u003ca href=\"/blog/build-app-beta.html\"\u003elaunched the Codename One Build App beta on Android last week\u003c/a\u003e and now we have a public beta for iOS as well. You can sign up to join the public beta through \u003ca href=\"https://testflight.apple.com/join/Y3RxSm81\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ethis link\u003c/a\u003e. Notice that you will need testflight on your device to join the public beta test.\u003c/p\u003e\n\u003cp\u003eAs is the case with the Android version please let us know if there are issues you experience in the \u003ca href=\"http://github.com/codenameone/CodenameOne/issues/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eissue tracker\u003c/a\u003e. The app mostly \u0026ldquo;just worked\u0026rdquo; on iOS but getting through the approval and submission process is always a pain. As part of that work we also improved the tablet UI which makes the app very usable on the iPad.\u003c/p\u003e","title":"Build App on iOS"},{"content":"\nProguard is one of the most disliked aspects of Android programming. Developers attack it left and right because there are so many nuances to it. That’s a huge mistake, proguard is one of the most important tools in our development toolchain. It makes our apps slightly more secure, much smaller and even slightly faster. Codename One apps use proguard by default for Android. This is a huge benefit in our case because the limits related to obfuscation are very similar to the limits related to portability.\nHowever, one of the side effects of obfuscation is jumbled stack traces. Normally this isn’t a \u0026ldquo;big deal\u0026rdquo; since line numbers are still correct. But when we have multiple releases it might be harder to track some of these line numbers through tags and history.\nThat’s where the mapping file you get when sending an Android build becomes useful.\nFigure 1. Mapping file in Build Results\nYou can use proguard to de-obfuscate mappings manually using the retrace command but that’s not necessarily helpful.\nGoogle Play includes a section for crashes and ANR’s (Application Not Responding) reported by users. These include stack traces but they might come from a wide range of versions and might be confusing to track.\nFigure 2. The Crashes \u0026amp; ANR’s Section\nThe problem is that you can get crashes that are very unreadable due to obfuscation. That’s where the mapping.txt file becomes useful. After you upload the APK file and submit it the next step is the Deobfuscation files section. Here you can upload the mapping file matching your version, this will create slightly more readable stack traces for you.\nNotice that the mapping.txt file differs between builds even if you didn’t change anything so make sure to use the file matching the APK you uploaded.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-obfuscation-mapping-file/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-obfuscation-mapping-file/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eProguard is one of the most disliked aspects of Android programming. Developers attack it left and right because there are so many nuances to it. That’s a huge mistake, proguard is one of the most important tools in our development toolchain. It makes our apps slightly more secure, much smaller and even slightly faster. Codename One apps use proguard by default for Android. This is a huge benefit in our case because the limits related to obfuscation are very similar to the limits related to portability.\u003c/p\u003e","title":"TIP: Obfuscation Mapping File"},{"content":"\nSome of our older components were developed years ago. As Android and iOS slowly converged their UI paradigms we got stuck supporting odd/outdated functionality as designs shifted. Three great examples are pull to refresh, OnOffSwitch and the InfiniteProgress features.\nOnOffSwitch contained labels both in iOS \u0026amp; Android. On Android it was literally a button that was moved back and forth. Today both OS’s use a simple switch graphic. When we developed the original component we didn’t have the same level of graphic drawing capability that we have today, that made the design of the iOS version even harder.\nPull to refresh was a feature twitter introduced. It became a hit among developers and slowly made its way into OS’s each of which implemented it differently. The original approach was very iOS centric and relied on the way drag works on that platform. Newer approaches such as the one in material design use an overlay approach. This also brings us to the InfiniteProgress class which is technically a trivial class, however in material design it has a very distinct special effect that’s hard to replicate in the current design.\nSwitch People have been complaining about the OnOffSwitch for a while. Recently ramsestom contributed some Android code to improve this behavior and we decided to take the plunge.\nFixing the old class would have been hard. It was designed to support two very different component types and includes a lot of kludges necessary for the limited graphics capabilities of Codename One 1.0. So we needed a clean break with the new Switch class.\nFigure 1. The New Switch Class in Action\nThe new class is trivial and works as a drop-in replacement for OnOffSwitch. The great thing about it is the newfound ability to customize everything through the theme/css. You can learn more about that in the class JavaDoc.\nInfiniteProgress Despite its huge legacy there was no need to rewrite InfiniteProgress since the class is much simpler. However, since the new material design progress behavior might not be to everyones liking its off by default. We’ll switch this on for Android when we feel it’s stable enough.\nYou can activate the experimental mode either through code using:\nInfiniteProgress.setDefaultMaterialDesignMode(true); Or by setting the theme constant infiniteProgressMaterialModeBool to true. Both of these will impact the pull to refresh and progress animation.\nNotice that the implementation of pull to refresh would be completely different when this is invoked so it’s very possible that quite a few things would break or misbehave. Proceed with caution and let us know!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/switch-progress-pull/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/switch-progress-pull/pixel-perfect.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSome of our older components were developed years ago. As Android and iOS slowly converged their UI paradigms we got stuck supporting odd/outdated functionality as designs shifted. Three great examples are pull to refresh, \u003ccode\u003eOnOffSwitch\u003c/code\u003e and the \u003ccode\u003eInfiniteProgress\u003c/code\u003e features.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eOnOffSwitch\u003c/code\u003e contained labels both in iOS \u0026amp; Android. On Android it was literally a button that was moved back and forth. Today both OS’s use a simple switch graphic. When we developed the original component we didn’t have the same level of graphic drawing capability that we have today, that made the design of the iOS version even harder.\u003c/p\u003e","title":"Switch, Progress and Pull to Refresh"},{"content":"\nOne of the big \u0026ldquo;behind the scenes\u0026rdquo; motivations for our big build cloud migration was new server API’s. We now have a completely new backend and this made it easier to build a completely new Codename One App christened as \u0026ldquo;Codename One Build\u0026rdquo;.\nThis app is currently in public beta on Android which you can opt-into here. Once we feel good with the Android version we’ll push out versions for iOS and maybe UWP if there’s demand for that.\nTo keep things simple we are currently focusing on the bare minimum so we can build on top of that. Furthermore, it’s at version 0.13 so it’s far from production grade. But it works really well and should be instantly useful for all of us. It includes several interesting features:\nPush notifications on builds\nEssentially eliminates the need of using the website for build tracking\nAbility to subscribe using In-App-Purchase – this is highly experimental so if you run into a problem let us know!\n__ We made the app beta to get it out as soon as possible but for all intents and purposes this is Alpha level software We have big plans for this app and have some pretty interesting ideas for it as we move forward. Right now we want to focus on the core functionality so it runs as smoothly as possible. As it matures we might use this app as the basis for a new web UI as well.\nWe plan to push frequent updates to this app and refine it as we go. So we need your help with issues which you can file in the usual place.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/build-app-beta/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/build-app-beta/codename-one-build.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the big \u0026ldquo;behind the scenes\u0026rdquo; motivations for our big \u003ca href=\"/blog/new-build-cloud/\"\u003ebuild cloud migration\u003c/a\u003e was new server API’s. We now have a completely new backend and this made it easier to build a completely new Codename One App christened as \u0026ldquo;Codename One Build\u0026rdquo;.\u003c/p\u003e\n\u003cp\u003eThis app is currently in public beta on Android which you can opt-into \u003ca href=\"https://play.google.com/apps/testing/com.codename1.build.app\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere\u003c/a\u003e. Once we feel good with the Android version we’ll push out versions for iOS and maybe UWP if there’s demand for that.\u003c/p\u003e","title":"Build App Beta"},{"content":"\nA while back we announced the migration to the new build cloud. The migration worked very smoothly and mostly seamlessly but there was one caveat: client libraries must be up to date. This is a confusing point so hopefully this long overdue post will clarify it.\nThe core of the problem is CodeNameOneBuildClient.jar. It’s a relatively simple jar with a few ant tasks that performs a lot of \u0026ldquo;under the hood\u0026rdquo; services such as sending the build to the cloud. It’s shipped within the IDE plugin and old versions of the IDE plugins would replace it automatically. We now update it via the update framework which is better but might cause a few issues.\nGenerally the issues can be expressed either via a build that doesn’t appear. You might get an error that a build is already in the queue and once we remove app engine entirely you’ll get a connection error.\nTo fix this you need to do the following:\nUpdate your plugin to the latest version, make sure that other team members don’t use an old plugin either\nRun Update Project Libs which you can do by right clicking the project and selecting: Codename One → Codename One Settings → Basic → Update Project Libs\n__ You need to Update Project Libs for every project if you have more than one Notice that new projects should be fine.\nIf this Didn’t Work The problem is that these two steps might fail. Here are things you need to look at:\nMake sure the Versions.properties and the jars in the projects aren’t under source control. They should be excluded from it as we update them dynamically\nIn your home directory there is a directory named .codenameone make sure it doesn’t contain an UpdateStatus.lock file. If it does you can delete it assuming it’s been there for a while\nWhen in doubt you can delete Versions.properties and Update Project Libs again. This should work but if that doesn’t do it you can go with the \u0026ldquo;nuclear option\u0026rdquo; and delete the .codenameone directory and Versions.properties. After that do an Update Project Libs.\nIf this still doesn’t work let us know via the chat. Ideally try to run the update framework from command line to figure out what went wrong. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAndrew — May 7, 2020 at 5:08 am (permalink) Andrew says:\nHi there,\nI hope this finds you well. I am hoping for some pointers regarding the above \u0026ldquo;Tips\u0026rdquo;. My home directory has \u0026ldquo;UpdateStatus.properties\u0026rdquo; and \u0026ldquo;UpdateCodenameOne.jar\u0026rdquo; are these ok as is? Also, How would I go about making sure the Versions.properties aren’t under source control? Finally… how would I go about making sure the Versions.properties aren’t under source control? I am using OSX with Netbeans\nThank you for your time, Codename One is a great tool!\nBe Safe!\nShai Almog — May 8, 2020 at 4:53 am (permalink) Shai Almog says:\nIf the version file contains CodenameOneJar=124 or newer then you’re good to go\nAre you using source control such as git?\nIf so they should be under .gitignore\nIf you aren’t using source control then they aren’t under source control\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-fix-issue-missing-builds/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-fix-issue-missing-builds/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA while back we announced the migration to the \u003ca href=\"/blog/new-build-cloud/\"\u003enew build cloud\u003c/a\u003e. The migration worked very smoothly and mostly seamlessly but there was one caveat: client libraries must be up to date. This is a confusing point so hopefully this long overdue post will clarify it.\u003c/p\u003e\n\u003cp\u003eThe core of the problem is \u003ccode\u003eCodeNameOneBuildClient.jar\u003c/code\u003e. It’s a relatively simple jar with a few ant tasks that performs a lot of \u0026ldquo;under the hood\u0026rdquo; services such as sending the build to the cloud. It’s shipped within the IDE plugin and old versions of the IDE plugins would replace it automatically. We now update it via the \u003ca href=\"/blog/new-update-framework/\"\u003eupdate framework\u003c/a\u003e which is better but might cause a few issues.\u003c/p\u003e","title":"TIP: Fix Issue with Missing Builds"},{"content":"\nWe are thrilled to announce the release of Codename One 5.0 – Social. Codename One is an open source \u0026ldquo;Write Once Run Anywhere\u0026rdquo; mobile platform for Java and Kotlin developers!\nWe postponed the release of this version since it’s so packed with big changes. We made CSS a first class citizen in Codename One and made CSS updates live (no recompile necessary). We moved from screenshots in iOS launches to storyboards. Added support for newer JDK’s. Migrated to Android API level 27. Moved our entire build server infrastructure. Redid push notification and so much more…​\nThere is SO MUCH more, check out the details below.\nHowever if you are new to Codename One here’s a short primer. Codename One is the only platform that…​\nHas Write Once Run Anywhere with no special hardware requirements and 100% code reuse\nCompiles Java or Kotlin into native code for iOS, UWP (Universal Windows Platform), Android \u0026amp; even JavaScript\nIs Open Source \u0026amp; Free for commercial use with an enterprise grade commercial support\nIs Easy to use with 100% portable Drag \u0026amp; Drop GUI builder\nHas Full access to underlying native OS capabilities using the native OS programming language (e.g. Objective-C) without compromising portability\nHas full control over every pixel on the screen! Just override paint and draw or use a glass pane to draw anywhere…​\nLets you use native widgets (views) and mix them with Codename One components within the same hierarchy (heavyweight/lightweight mixing)\nSupports seamless Continuous Integration out of the box\nTo learn more about Codename One check out the about page you can download it for free right now.\nVersion 5.0 is nicknamed Social because of the Facebook Clone application that was developed with it for the online course in the Codename One Academy.\nFigure 1. Facebook Native App vs. our Clone\nHighlights of this Release The top 5 features of this release are covered in this short video, check out further details below…​\nLive CSS Update — CSS is now deeply and seamlessly integrated into Codename One. When you change the content of a CSS file and save the Codename One simulator automatically updates on the fly\nRich Push Notifications — Push notification was overhauled, we moved the last of the functionality from GCM to FCM. We now support rich push notifications that can include images and complex functionality\nLaunch Screen Storyboards — Historically iOS used screenshots of apps to fake fast application launches. Codename One automated that process in the past, it’s now discoraged by newer iOS features such as side-by-side multi-tasking. As such we now use storyboard launch files. This allows side-by-side multi-tasking and as a bonus speeds up compilation while reducing the app size further\nNew JDK/OpenJDK Support — We now support JDK’s 8 to 11 this includes OpenJDK\nNew Cloud Servers — We migrated the last remaining Codename One servers off of Google App Engine. This allowed us to introduce great new features such as the ability to increase your free build quota\nRemoved Old IDE Preferences UI — The old right click IDE preferences UI was causing a lot of confusion due to lack of maintenance. It’s now gone and replaced completely by Codename One Settings\nAndroid API Level 27 — We moved to Android’s API Level 27 by default. Since Google requires API level 26 or higher at this time. We’ll probably update API levels faster due to this policy\nLightweight Picker — The Picker component was rewritten as a lightweight component instead of a native one. This allows far more customization and cross platform consistency for one of our most problematic widgets\nLow Level Camera API — Camera Kit allows developers to access the native camera view to grab photos/videos and overlay graphics on top of the camera\nPluggable Spatial SQLite — Spatial support for SQLite lets developers write complex location based applications. This functionality lets developers replace the existing native SQLite implementation with an arbitrary implementation which is very useful for enterprise grade features such as deep encryption, replication etc.\nImproved Map Layout — The map API now includes a native high performance component layout built in\nLandscape UIID’s — Components can adapt their UIID to landscape, this enables features such as smaller title font/padding in landscape mode\nMultiple Smaller Improvements :\nDateUtil API for timezone related date functions\nSidemenu right side option and new tab ordering API\nAbility to map a list of property business objects to a table\nSendgrid cn1lib\nRest API overhaul for error handling, properties etc.\nOn-device webserver\nAuto-reconnect for websockets\nThere are many other features both big and small. Check out our blog and the github project history.\nOnwards to 6.0 – Chat We took a lot of time for 5.0 and I’d like to take a similar duration for 6.0. I think this made 5.0 a better release.\nWe will have a whatsapp clone tutorial in the Codename One Academy. Hence the moniker of the next release.\nCheck out our survey results to see the future apps we’ll release into the academy. Even if you never plan to signup to the academy this should be interesting as it gives you a good notion of what can be built with Codename One.\nWe Need your Help If you think we are doing a good job and appreciate our help please help us by:\nSpreading the word\nEdit our docs\nEdit our sources and submit bug fixes\nOr just sign up for enterprise accounts which literally keep the lights on here…​ If your company can afford it please take the time and upgrade to enterprise, this will allow us to work on the things that are important for your company!\nThanks for reading this far and if you have any thoughts/suggestions of any kind please let us know! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\ndavidwaf — September 19, 2018 at 9:10 pm (permalink) Awesome work!! ..as always. Push notifications: there was a mention they will be eventually available even for basic accounts?\nShai Almog — September 20, 2018 at 6:50 am (permalink) Shai Almog says:\nThanks!\nOur general thought is to enable a small amount monthly push messages for free/basic users (e.g. 100) so they can test push functionality when building the app. The idea is to upgrade to pro only if they find push useful.\nAnother idea is to increase the quota based on referrals so even the free tier would be able to get enough push messages for a small app.\nLukman Javalove Idealist Jaji — September 20, 2018 at 1:04 pm (permalink) Lukman Javalove Idealist Jaji says:\nI was gon ask the same question… Is there a timeline as to when this 100 units will be available?\nShai Almog — September 25, 2018 at 8:20 am (permalink) Shai Almog says:\nNo. This depends on two things:\n– Is it worth our while\n– Do we have the resources to do the required work (which is extensive)\nCurrently both are no. So far we don’t see any noticeable impact from the referral program. So investing more time in this probably won’t drive traction. We have a lot on our plates for the end of the year and Q1 2019 so I don’t see this happening soon.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-5-0-social-live/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-5-0-social-live/codenameone-5-release-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are thrilled to announce the release of \u003ca href=\"https://www.codenameone.com/\"\u003eCodename One\u003c/a\u003e 5.0 – Social. Codename One is an open source \u0026ldquo;Write Once Run Anywhere\u0026rdquo; mobile platform for Java and Kotlin developers!\u003cbr\u003e\nWe postponed the release of this version since it’s so packed with big changes. We made CSS a first class citizen in Codename One and made CSS updates live (no recompile necessary). We moved from screenshots in iOS launches to storyboards. Added support for newer JDK’s. Migrated to Android API level 27. Moved our entire build server infrastructure. Redid push notification and so much more…​\u003c/p\u003e","title":"Codename One 5.0 \"Social\" is now Live"},{"content":"\nCodename One 5.0 (Social) will launch next week, to keep the code stable we are entering a week long code freeze. Please update your plugin installs frequently and report bugs immediately so we will have a stable release!\nWe’ve added a lot of new features to 5.0 but a few of the big things are pretty disruptive:\nOpenJDK Support with JDK 9, 10 \u0026amp; 11 support\nXIB Build Mode\nNew cloud servers\nBecause all of these changes have many subtle implications we are relying on feedback from you on what’s working and what isn’t. If you run into any issue please file the issue ASAP so we can move quickly and update the release if necessary.\nDuring this week of code freeze we’ll try to update the documentation and prepare everything for the release.\nUpcoming Milestones We will branch to the 5.0 branch in our repository and every change to the branch will be cherry picked individually.\nHere are the coming releases after 5.0:\n6.0 (Chat) – Scheduled for February 19 2019\n7.0 (Video) – Scheduled for June 12 2019\nYou can track these milestones and the related tasks in our github project here.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codefreeze-5-social/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codefreeze-5-social/codenameone-5-release-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One 5.0 (Social) will launch next week, to keep the code stable we are entering a week long code freeze. Please update your plugin installs frequently and report bugs immediately so we will have a stable release!\u003c/p\u003e\n\u003cp\u003eWe’ve added a lot of new features to 5.0 but a few of the big things are pretty disruptive:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"/blog/uber-book-is-out-jdk-11.html\"\u003eOpenJDK Support with JDK 9, 10 \u0026amp; 11 support\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"/blog/no-more-ios-screenshots.html\"\u003eXIB Build Mode\u003c/a\u003e\u003c/p\u003e","title":"Codefreeze for Codename One 5.0 – Social"},{"content":"\nWebSockets changed the way I do networking code. I combine them with WebServices to get the best of both worlds. But they still suffer in terms of reliability. With WebServices we have retries and a mostly transactional model. There is no permanent connection that should be re-established.\nWith WebSockets a disconnect can be painful, up until recently I used a rather elaborate strategy of error detection and timers. With the latest update to the WebSocket cn1lib we now have a better solution: autoReconnect(int).\nIt’s exactly as it sounds, once you create a websocket you can invoke autoReconnect(5000) on it to retry the connection ever 5 seconds in case of a disconnect.\nIf you have an existing WebSocket app you should probably add this call.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-auto-reconnect-web-socket/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-auto-reconnect-web-socket/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWebSockets changed the way I do networking code. I combine them with WebServices to get the best of both worlds. But they still suffer in terms of reliability. With WebServices we have retries and a mostly transactional model. There is no permanent connection that should be re-established.\u003c/p\u003e\n\u003cp\u003eWith WebSockets a disconnect can be painful, up until recently I used a rather elaborate strategy of error detection and timers. With the latest update to the \u003ca href=\"https://github.com/shannah/cn1-websockets/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eWebSocket cn1lib\u003c/a\u003e we now have a better solution: \u003ccode\u003eautoReconnect(int)\u003c/code\u003e.\u003c/p\u003e","title":"TIP: Auto Reconnect Web Socket"},{"content":"\nCodename One 5.0 AKA Social will launch on September 19th. We pushed this release back to include support for crucial features such as JDK 11/OpenJDK support. With these features in place and a slew of other features we are gearing towards 5.0 GA. Tomorrow (Friday) we will push out plugin version 4.5 for all IDE’. This new version is effectively release candidate 1 for the 5.0 version.\nNormally we don’t bother with a release candidate this close to an actual release as the plugins don’t change much. However, we made some extensive changes to the plugins recently and we’d like to make sure we didn’t break too many things before the release.\nWe will enter the release code freeze for social on September 12th after which only reviewed commits can be cherry picked. Only critical bugs will be fixed at that point.\nCurrently version 6.0 (AKA Chat) is scheduled for release in February 19th 2019.\nSocial We named the releases of Codename One based on the signature app we built on top of that given release. 4.0 was named Taxi as it was used to develop an Uber clone. Version 5.0 is named social as we built a Facebook Clone during the release cycle.\nFor Version 6.0 we will build a whatsapp clone hence the \u0026ldquo;Chat\u0026rdquo; moniker.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/preparing-for-social/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/preparing-for-social/codenameone-5-release-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One 5.0 AKA Social will launch on September 19th. We pushed this release back to include support for crucial features such as JDK 11/OpenJDK support. With these features in place and a slew of other features we are gearing towards 5.0 GA. Tomorrow (Friday) we will push out plugin version 4.5 for all IDE’. This new version is effectively release candidate 1 for the 5.0 version.\u003c/p\u003e\n\u003cp\u003eNormally we don’t bother with a release candidate this close to an actual release as the plugins don’t change much. However, we made some extensive changes to the plugins recently and we’d like to make sure we didn’t break too many things before the release.\u003c/p\u003e","title":"Preparing for Codename One 5.0 – Social"},{"content":"\nA while back we introduced Codename One Settings which superceded the old approach built in the IDE itself. This allowed us to consolidate code and move faster. That’s how we were able to implement more wizards for things like CSS support etc.\nUp until now we just left the old UI in place. People are still used to it. But it has a lot of bugs and causes confusion as developers launch the old UI instead of the new one. So with version 5.0 we’ll remove the old preferences UI and leave Codename One Settings.\nWe’ll also remove the deprecated build targets from the menu and try to streamline the first usage of Codename One a bit. Most of these changes shouldn’t be noticeable for most developers. However, from experience I’m sure there are quite a few developers out there that didn’t move to Codename One Settings.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/removing-old-preferences/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/removing-old-preferences/generic-java-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA while back we introduced Codename One Settings which superceded the old approach built in the IDE itself. This allowed us to consolidate code and move faster. That’s how we were able to implement more wizards for things like CSS support etc.\u003c/p\u003e\n\u003cp\u003eUp until now we just left the old UI in place. People are still used to it. But it has a lot of bugs and causes confusion as developers launch the old UI instead of the new one. So with version 5.0 we’ll remove the old preferences UI and leave Codename One Settings.\u003c/p\u003e","title":"Removing the Old Preferences"},{"content":"\nThe most secure password in the world is the one that doesn’t exist. You remove the user from the equation with a completely random key. To be fair this has some drawbacks and a password still exists somewhere (in your phone/email) but generally this works rather well…​\nThe trick is simple, if we want to authenticate a user we can email him a single use URL e.g. mycoolapp://act-32548b09-d328-4330-8243-d7d30c322e40. As you can see that’s pretty hard to guess or brute force. Once clicked the URL becomes invalid so even if it’s exposed somehow it would still be irrelevant. To do this we need two parts:\nThe server logic\nClient URL handling\nBoth are pretty easy.\nThe Server One caveat is that the mycoolapp will work on the device but you can’t click it in an email or in a browser. So we will need an https URL from your server.\nThe server would look something like this, notice that this is Spring Boot Controller code but you should be able to use any server out there:\npublic boolean sendSigninEmail(String e) { List\u0026lt;UserObj\u0026gt; ul = users.findByEmailIgnoreCase(e); if(ul.isEmpty()) { return false; } UserObj u = ul.get(0); u.setHashedActivationToken(UUID.randomUUID().toString()); __**(1)** users.save(u); __**(2)** email.sendEmail(e, \u0026quot;Signin to the Codename One App\u0026quot;, \u0026quot;This is a one time link to activate the Codename One App. Click this link on your mobile device: nnhttps://ourserverurl.com/app/activateURL?token=act-\u0026quot; + u.getHashedActivationToken()); __**(3)** return true; } public User activateViaToken(String t) throws ServerAppAPIException { List\u0026lt;UserObj\u0026gt; ul = users.findByHashedActivationToken(t); __**(4)** if(ul.isEmpty()) { throw new ServerAppAPIException(ServerErrorCodes.NOT_FOUND); } UserObj u = ul.get(0); String val = u.getAppToken(); __**(5)** u.setHashedActivationToken(null); __**(6)** users.save(u); User r = u.getUser(); r.setAppToken(u.getAppToken()); return r; } __1 We use UUID to generate the long activation string __2 We save it in the database overwriting an older URL if it exists __3 We can send an email or SMS with the HTTPS URL to activate the app __4 Next we activate the user account with the received token. We find the right account entry __5 An access token is a secure password generated by the server that’s completely random and only visible to the app __6 The activation token used in the URL is removed now making the URL a single use tool All of that is mostly simple but there is still one missing piece. Our app will expect a mycoolapp URL and an HTTPS URL won’t launch it. The solution is a 302 redirect:\n@RequestMapping(value=\u0026quot;/activateURL\u0026quot;, method=RequestMethod.GET) public void activateURL(@RequestParam String token, HttpServletResponse httpServletResponse) { httpServletResponse.setHeader(\u0026quot;Location\u0026quot;, \u0026quot;mycoolapp://\u0026quot; + token); httpServletResponse.setStatus(302); } This sends the device to the mycoolapp URL automatically and launches your app with the token!\nClient Side On the client we need to intercept the mycoolapp URL and parse it. First we need to add two new build hints:\nandroid.xintent_filter=\u0026lt;intent-filter\u0026gt; \u0026lt;action android_name=\u0026quot;android.intent.action.VIEW\u0026quot; /\u0026gt; \u0026lt;category android_name=\u0026quot;android.intent.category.DEFAULT\u0026quot; /\u0026gt; \u0026lt;category android_name=\u0026quot;android.intent.category.BROWSABLE\u0026quot; /\u0026gt; \u0026lt;data android_scheme=\u0026quot;mycoolapp\u0026quot; /\u0026gt; \u0026lt;/intent-filter\u0026gt; ios.plistInject=\u0026lt;key\u0026gt;CFBundleURLTypes\u0026lt;/key\u0026gt; \u0026lt;array\u0026gt; \u0026lt;dict\u0026gt; \u0026lt;key\u0026gt;CFBundleURLName\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;com.mycompany.myapp.package.name\u0026lt;/string\u0026gt; \u0026lt;/dict\u0026gt; \u0026lt;dict\u0026gt; \u0026lt;key\u0026gt;CFBundleURLSchemes\u0026lt;/key\u0026gt; \u0026lt;array\u0026gt; \u0026lt;string\u0026gt;mycoolapp\u0026lt;/string\u0026gt; \u0026lt;/array\u0026gt; \u0026lt;/dict\u0026gt; \u0026lt;/array\u0026gt; __ Don’t forget to fix mycoolapp and com.mycompany.myapp.package.name to the appropriate values in your app Next all we need to do is detect the URL in the start() method. This needs to reside before the code that checks the current Form:\nString arg = getProperty(\u0026quot;AppArg\u0026quot;, null); __**(1)** if(arg != null) { if(arg.contains(\u0026quot;//\u0026quot;)) { __**(2)** List\u0026lt;String\u0026gt; strs = StringUtil.tokenize(arg, \u0026quot;/\u0026quot;); arg = strs.get(strs.size() - 1); while(arg.startsWith(\u0026quot;/\u0026quot;)) { arg = arg.substring(1); } } if(!arg.startsWith(\u0026quot;act-\u0026quot;)) { __**(3)** showLoginForm(); callSerially(() -\u0026gt; Dialog.show(\u0026quot;Invalid Key\u0026quot;, \u0026quot;The Activation URL is invalid\u0026quot;, \u0026quot;OK\u0026quot;, null)); return; } arg = arg.substring(4); Form activating = new Form(\u0026quot;Activating\u0026quot;, new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER)); activating.add(CENTER, new InfiniteProgress()); activating.show(); sendActivationTokenToServer(arg); __**(4)** return; } __1 This is from the CN class globally imported. The app argument is the URL __2 We remove the URL portion of the argument __3 The act- prefix is there to validate the URL is correct __4 This sends the activation key to the server logic we discussed above Testing in The Simulator This will work in iOS and Android. Starting next week you could also test this on the simulator using the new Send App Argument menu option in the simulator.\nTo integrate this properly into an app you would normally have a login menu that accepts only the email/phone. Or a system in your web based UI to send an invite link to the app.\nWhatsapp uses an inverse of this trick to activate their desktop app. They show a QR code to your device and once you scan that QR code with your whatsapp phone install the desktop version is activated. That’s much better than passwords. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — September 5, 2018 at 8:36 am (permalink) Francesco Galgani says:\nThank you Shai for this article, the server redirect is a great idea to circumvent the \u0026ldquo;impossible to click\u0026rdquo; links with a custom protocol in Gmail. Some email providers allow to click any link with any custom protocol, others block any custom protocol. I circumvented this issue to send an activation link with a completely different approach, however your redirect solution is very good 😉\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-activate-via-url-send-arguments/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-activate-via-url-send-arguments/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe most secure password in the world is the one that doesn’t exist. You remove the user from the equation with a completely random key. To be fair this has some drawbacks and a password still exists somewhere (in your phone/email) but generally this works rather well…​\u003c/p\u003e\n\u003cp\u003eThe trick is simple, if we want to authenticate a user we can email him a single use URL e.g. \u003ccode\u003emycoolapp://act-32548b09-d328-4330-8243-d7d30c322e40\u003c/code\u003e. As you can see that’s pretty hard to guess or brute force. Once clicked the URL becomes invalid so even if it’s exposed somehow it would still be irrelevant. To do this we need two parts:\u003c/p\u003e","title":"TIP: Activate via URL and Send Arguments"},{"content":"\nI wrote before about Crisp and how pleased we are over the migration to their service. Recently they started offering a new service of status page. This service runs on their servers and essentially monitors whether our service is down.\nDue to the complexity of our service not all of the pieces are monitored but a few of the more important features are already mapped. Hopefully, if you experience service issues you can look in the status page and you’d know if something is going on. Notice that when it goes red we get alerts and notice that something is broken\nYou can see the status page at https://status.codenameone.com/\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/status-monitor/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/status-monitor/generic-java-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI wrote before about \u003ca href=\"/blog/moving-away-from-intercom.html\"\u003eCrisp\u003c/a\u003e and how pleased we are over the migration to their service. Recently they started offering a new service of status page. This service runs on their servers and essentially monitors whether our service is down.\u003c/p\u003e\n\u003cp\u003eDue to the complexity of our service not all of the pieces are monitored but a few of the more important features are already mapped. Hopefully, if you experience service issues you can look in the status page and you’d know if something is going on. Notice that when it goes red we get alerts and notice that something is broken\u003c/p\u003e","title":"Status Monitor"},{"content":"\nIn February I wrote about a new/improved way to build for iOS without the screenshot process. That was a bit ahead of its time as the xib build didn’t disable the screenshot process yet. This is now fixed and it’s turned on by default now. That means that if you send an iOS build it won’t go through the screenshot generation process.\nThis means that apps with native peers in the first screen such as maps, browser etc. will start working with this coming update. It also means the splash screen of the application on iOS will be relatively simple by default. You can customize it using xcode to make it more appealing. The upside is things such as multi-tasking etc. will work correctly.\nA side benefit of this is a slightly faster build. It would also make the resulting binaries even smaller than they already are. In some cases the screenshots increased the size of the binaries significantly.\nIf you want to revert to the old behavior you can do so by setting the build hint ios.generateSplashScreens=true. It now defaults to false. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — August 29, 2018 at 11:23 am (permalink) Francesco Galgani says:\nIs the multitasking enabled by default? Is the generated splash screen equals to the icon.png of the app?\nFrancesco Galgani — August 29, 2018 at 12:04 pm (permalink) Francesco Galgani says:\nWhat about the compatibility of the new builds with the various versions of iPhone?\nShai Almog — August 30, 2018 at 5:42 am (permalink) Shai Almog says:\nIt isn’t but I think it should, let me check.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/no-more-ios-screenshots/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/no-more-ios-screenshots/xcode-migration.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIn February I wrote about a new/improved way to \u003ca href=\"/blog/xcode-9-on-by-default.html\"\u003ebuild for iOS without the screenshot process\u003c/a\u003e. That was a bit ahead of its time as the xib build didn’t disable the screenshot process yet. This is now fixed and it’s turned on by default now. That means that if you send an iOS build it won’t go through the screenshot generation process.\u003c/p\u003e\n\u003cp\u003eThis means that apps with native peers in the first screen such as maps, browser etc. will start working with this coming update. It also means the splash screen of the application on iOS will be relatively simple by default. You can customize it using xcode to make it more appealing. The upside is things such as multi-tasking etc. will work correctly.\u003c/p\u003e","title":"No More iOS Screenshots"},{"content":"\nI try to write about every new feature or capability we introduce but this isn’t always possible. Tasks sometimes weigh me down and as they do so I sometimes find something that I totally neglected as it was released. Such is the case with the CN1Webserver library which we launched over 6 months ago.\nIt got lost and in fact it came out during such a busy period I completely forgot about it.\nThis cn1lib lets you create a simple web server on the device. You can then connect to this server either from the device itself (the more common use case) or remotely.\nThis sounds insane but it’s a surprisingly common trick used by developers to get around odd device limitations. I first ran into this use case around 2010. Back then a company I was consulting for needed a way to process media files before playback (to apply DRM). This was impossible in Android at the time and it’s still challenging. Their solution was genius and trivial: they implemented a webserver on the device.\nThis way they could download and decode the file locally, then playback from a local URL on the device itself. The devices media API was oblivious to the fact that DRM was used in playback.\nThere are quite a few additional cases such as the ability to embed HTML/JS code that needs server interaction in order to work. For most of us this feature is pretty niche but the fact that you can accomplish it with a simple plugin is huge.\nYou can install the cn1lib like you can any other cn1lib from the Extension Manager. You will need additional setup so it will work correctly on the devices as explained in the github project. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — August 28, 2018 at 3:30 pm (permalink) Francesco Galgani says:\nWhen I think to a server, I have in mind Apache, Tomcat, IIS… Which type of content and code can be used in that CN1 server? Only static content of html/js?\nShai Almog — August 29, 2018 at 3:27 pm (permalink) Shai Almog says:\nYou can dynamically generate files to the file system where this server will serve them. I think it should be pretty easy to create a servlet like API to serve truly dynamic content through this API though.\nCarlos — February 22, 2019 at 10:29 am (permalink) Carlos says:\nCould this server accept post operations, so binary files could be remotely submitted to the device?\nShai Almog — February 23, 2019 at 5:39 am (permalink) Shai Almog says:\nI don’t think so. A device can be hidden behind a NAT so even if you enable it this would be problematic to implement.\nCarlos — February 23, 2019 at 6:06 pm (permalink) Carlos says:\nI’m thinking I just need sending files within the local network, so the NAT wouldn’t be a problem. What I want to do is sending files from a desktop java app to a CN1 app. What would be the best way to achieve that? I was thinking websockets, but the files could be quite large, so I’m not sure that is a good choice…\nShai Almog — February 24, 2019 at 4:32 am (permalink) Shai Almog says:\nI would use the cloud as a middle tier for most cases as it makes things simpler. However, if you don’t want that I’d use a server on the desktop which ideally supports websockets. Then use the websockets to push an event to the connected client. Based on such an event I’d trigger a download from the client.\nThis would save battery life. You can also use push notification instead of websockets to further save on battery life and send the event even when the app is in the background with visual notification to the user.\nCarlos — February 24, 2019 at 7:42 pm (permalink) Carlos says:\nGreat, thank you. I’ll try these solutions and see which one fits best for my needs.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/on-device-web-server/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/on-device-web-server/new-features-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI try to write about every new feature or capability we introduce but this isn’t always possible. Tasks sometimes weigh me down and as they do so I sometimes find something that I totally neglected as it was released. Such is the case with the \u003ca href=\"https://github.com/shannah/CN1Webserver\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCN1Webserver\u003c/a\u003e library which we launched over 6 months ago.\u003c/p\u003e\n\u003cp\u003eIt got lost and in fact it came out during such a busy period I completely forgot about it.\u003c/p\u003e","title":"On Device Web Server"},{"content":"\nI’m answering questions in the Code Ranch this week about Create an Uber Clone in 7 Days. So far I’ve had some pretty great ones, if you have a question join the conversation for a chance to win a free copy. To qualify just ask in the Android forum and make sure to qualify it with \u0026ldquo;Create an Uber Clone in 7 Days:\u0026rdquo; so I will notice the question.\nSo far the book is doing well trending in the #2 to #3 spot for mobile development books in the kindle store. The print version isn’t selling as nicely, probably because of the huge price difference between the kindle and print book. Since the print book took far more effort, I might skip doing a print book if I go through this again.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/code-ranch-questions/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/code-ranch-questions/create-uber-clone-book-promo-1024.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI’m answering questions in the \u003ca href=\"https://coderanch.com/t/698065/mobile/Shai-Almog\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCode Ranch\u003c/a\u003e this week about \u003ca href=\"https://www.amazon.com/Create-Uber-Clone-Days-mobile-ebook/dp/B07FRXZRRV/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCreate an Uber Clone in 7 Days\u003c/a\u003e. So far I’ve had some pretty great ones, if you have a question join the conversation for a chance to win a free copy. To qualify just ask in the \u003ca href=\"https://coderanch.com/f/93/Android\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eAndroid forum\u003c/a\u003e and make sure to qualify it with \u0026ldquo;Create an Uber Clone in 7 Days:\u0026rdquo; so I will notice the question.\u003c/p\u003e","title":"Code Ranch Questions"},{"content":"\nFinally after all this time you can buy the Uber book today in both in Kindle and print versions!\nNotice that the kindle pricing is currently very low due to Amazon’s restrictions. Once the Amazon exclusivity expires the price of the ebook will go up.\nNotice that the book is also available on all Amazon domains so you can order from UK, DE, FR, ES, IT, NL, JP, BR, CA, MX, AU and IN.\nNotice that the print book should also be available in local stores, but you’ll probably need to ask the store to stock it. For now the book won’t launch on other digital stores due to Amazon exclusivity, I’m not sure when/if this will change.\nYou can check out the first two chapters at the book site. Please spread this far and wide, if the book is a success I’ll turn it into a series featuring other apps as well.\nJDK 11 In unrelated news, this weekend we’ll release experimental support for JDK 9, 10 and 11. This support means Codename One will work when running on these JDK’s (and OpenJDK) but it doesn’t mean that Codename One will add features from these JDK’s.\nIf you have a newer JDK on your machine we’d appreciate issues covering this support. We’re releasing it early to give us time to test it until the 5.0 release.\nIt’s an important feature as JDK 8 reaches end of life at the end of the year. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — August 16, 2018 at 8:13 am (permalink) Francesco Galgani says:\nDo you mean that we can upgrade from Oracle NetBeans IDE 8.2 (that supports Java 8) to Apache NetBeans 9.0 (that supports Java 9 and Java 10)?\nCan we even replace Netbeans8+JDK8 with Netbeans9+OpenJDK10? Do you have done some tests with this combination of software?\nIs the Codename One plugin ready for NetBeans 9.0?\nIs the current code of our Codename One apps fully compatible with Java9/10?\nShai Almog — August 16, 2018 at 12:14 pm (permalink) Shai Almog says:\nYes on all counts with the plugin that comes out tomorrow (including JDK 11). We did our testing but it was relatively limited so we hope people will let us know how well this works (or doesn’t work). We also use these newer JDK’s in our continuous integration tests.\nGareth Murfin — August 16, 2018 at 12:33 pm (permalink) Gareth Murfin says:\nGreat work on the book, that might be my xmas gift to myself :-))))\nRonald Tshabalala — August 16, 2018 at 4:18 pm (permalink) Ronald Tshabalala says:\nHey Shai, are you still going to do further examples for the course? I read a few blogs back saying you doing a messaging system?\nShai Almog — August 17, 2018 at 3:37 am (permalink) Shai Almog says:\nYes!\nI will produce 8 apps for the course out of which I delivered 2 (in addition to the 2+ already there beforehand). The next app would be a whatsapp clone which will launch in 2018. It will be followed by a netflix clone. You can see how this was decided in the survey results https://www.codenameone.com…\nFrancesco Galgani — August 17, 2018 at 10:07 pm (permalink) Francesco Galgani says:\nThank you. At the moment I’m migrating from Netbeans8.2+JDK8 to Netbeans9+OpenJDK10. I suggest you to update the info here (it’s written to use JDK8):\nhttps://www.codenameone.com…\nShai Almog — August 18, 2018 at 8:09 am (permalink) Shai Almog says:\nYes, we’ll update it once we know JDK 9+ are stable.\nTommy Mogaka — August 21, 2018 at 10:11 am (permalink) Tommy Mogaka says:\nHi Shai, Will the upcoming 2019 Java licensing change by Oracle have an effect on Codename One? Is CN1 dependent on Java for developing and deploying apps or is there an alternative Development Tool Kit that supports the cn1 plugin? Please advice! Thanks.\nShai Almog — August 22, 2018 at 4:01 am (permalink) Shai Almog says:\nOpenJDK is the alternative. Its license is free. Also as long as you keep updating the JDK to the latest LTS (currently JDK 11) this shouldn’t be a problem. This is the exact reason we’re moving to support JDK 11.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/uber-book-is-out-jdk-11/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/uber-book-is-out-jdk-11/create-uber-clone-book-promo-1024.png\"\u003e\u003c/p\u003e\n\u003cp\u003eFinally after all this time you can buy the Uber book today in both in \u003ca href=\"https://www.amazon.com/Create-Uber-Clone-Days-mobile/dp/1983258784/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eKindle and print\u003c/a\u003e versions!\u003cbr\u003e\nNotice that the kindle pricing is currently very low due to Amazon’s restrictions. Once the Amazon exclusivity expires the price of the ebook will go up.\u003c/p\u003e\n\u003cp\u003eNotice that the book is also available on all Amazon domains so you can order from \u003ca href=\"https://www.amazon.co.uk/dp/B07FRXZRRV\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eUK\u003c/a\u003e, \u003ca href=\"https://www.amazon.de/dp/B07FRXZRRV\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDE\u003c/a\u003e, \u003ca href=\"https://www.amazon.fr/dp/B07FRXZRRV\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFR\u003c/a\u003e, \u003ca href=\"https://www.amazon.es/dp/B07FRXZRRV\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eES\u003c/a\u003e, \u003ca href=\"https://www.amazon.it/dp/B07FRXZRRV\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eIT\u003c/a\u003e, \u003ca href=\"https://www.amazon.nl/dp/B07FRXZRRV\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eNL\u003c/a\u003e, \u003ca href=\"https://www.amazon.co.jp/dp/B07FRXZRRV\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eJP\u003c/a\u003e, \u003ca href=\"https://www.amazon.com.br/dp/B07FRXZRRV\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eBR\u003c/a\u003e, \u003ca href=\"https://www.amazon.ca/dp/B07FRXZRRV\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCA\u003c/a\u003e, \u003ca href=\"https://www.amazon.com.mx/dp/B07FRXZRRV\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eMX\u003c/a\u003e, \u003ca href=\"https://www.amazon.com.au/dp/B07FRXZRRV\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eAU\u003c/a\u003e and \u003ca href=\"https://www.amazon.in/dp/B07FRXZRRV\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eIN\u003c/a\u003e.\u003c/p\u003e","title":"Uber Book is Out! (And JDK 11 Support)"},{"content":"\nIf you aren’t using properties with Codename One, you probably should. Here’s a post I wrote a while back covering them, it should give you a lot of reasons for this. We are slowly integrating them into API’s such as Rest and as a result the code is simpler. A huge bonus is the type safety and flexibility that comes with this API.\nUp until now binding in properties was mostly limited to \u0026ldquo;simple\u0026rdquo; classes such as TextField. Complex structures such as Table weren’t supported. This is no longer the case.\nWith the coming update UIBinding now includes a new API to bind a list of PropertyBusinessObject to a TableModel. This effectively allows the creation of table matching list of objects without writing any code!\nStoring Object Lists as JSON Before we go into the table binding code we needed some API’s to support the following demo. One such API in PropertyIndex is:\npublic static void storeJSONList(String name, List\u0026lt;? extends PropertyBusinessObject\u0026gt; objs); public \u0026lt;X extends PropertyBusinessObject\u0026gt; List\u0026lt;X\u0026gt; loadJSONList(String name); These API’s let you store the data in the list of property objects into JSON. It also lets you load that JSON data into a newly created list. When we implemented this initially it failed for the date object. It turns out that storing Date objects into JSON isn’t standardized. Googling a bit showed that dates are often written like this in JSON: 2018-08-01T18:28:23.292.\nSo this is now the standard for date objects stored/loaded into JSON.\nSample Lets look at how this work with a sample based on the old code I wrote a while back. You can check out the full project here. First we’ll start with the properties object itself which isn’t very different:\npublic class Contact implements PropertyBusinessObject { public final IntProperty\u0026lt;Contact\u0026gt; id = new IntProperty\u0026lt;\u0026gt;(\u0026quot;id\u0026quot;); public final Property\u0026lt;String, Contact\u0026gt; name = new Property\u0026lt;\u0026gt;(\u0026quot;name\u0026quot;); public final Property\u0026lt;String, Contact\u0026gt; email = new Property\u0026lt;\u0026gt;(\u0026quot;email\u0026quot;); public final Property\u0026lt;String, Contact\u0026gt; phone = new Property\u0026lt;\u0026gt;(\u0026quot;phone\u0026quot;); public final Property\u0026lt;Date, Contact\u0026gt; dateOfBirth = new Property\u0026lt;\u0026gt;(\u0026quot;dateOfBirth\u0026quot;, Date.class); public final Property\u0026lt;String, Contact\u0026gt; gender = new Property\u0026lt;\u0026gt;(\u0026quot;gender\u0026quot;); public final IntProperty\u0026lt;Contact\u0026gt; rank = new IntProperty\u0026lt;\u0026gt;(\u0026quot;rank\u0026quot;); private final PropertyIndex idx = new PropertyIndex(this, \u0026quot;Contact\u0026quot;, id, name, email, phone, dateOfBirth, gender, rank); @Override public PropertyIndex getPropertyIndex() { return idx; } public Contact() { name.setLabel(\u0026quot;Name\u0026quot;); email.setLabel(\u0026quot;E-Mail\u0026quot;); phone.setLabel(\u0026quot;Phone\u0026quot;); dateOfBirth.setLabel(\u0026quot;Date Of Birth\u0026quot;); gender.setLabel(\u0026quot;Gender\u0026quot;); rank.setLabel(\u0026quot;Rank\u0026quot;); } } There isn’t much to say about this object it’s pretty standard. So lets initialize it in the start() method:\nprivate List\u0026lt;Contact\u0026gt; listOfContacts; public void start() { if(current != null) { current.show(); return; } if(!existsInStorage(\u0026quot;contacts.json\u0026quot;)) { listOfContacts = new ArrayList\u0026lt;\u0026gt;(); __**(1)** Contact c =new Contact(). id.set(1). dateOfBirth.set(new Date()). name.set(\u0026quot;Shai\u0026quot;). gender.set(\u0026quot;Male\u0026quot;); listOfContacts.add(c); listOfContacts.add(new Contact(). id.set(2). dateOfBirth.set(new Date()). name.set(\u0026quot;Steve\u0026quot;). gender.set(\u0026quot;Male\u0026quot;)); listOfContacts.add(new Contact(). id.set(3). dateOfBirth.set(new Date()). name.set(\u0026quot;Chen\u0026quot;). gender.set(\u0026quot;Male\u0026quot;)); PropertyIndex.storeJSONList(\u0026quot;contacts.json\u0026quot;, listOfContacts); __**(2)** } else { listOfContacts = new Contact().getPropertyIndex().loadJSONList( \u0026quot;contacts.json\u0026quot;); __**(3)** } // rest of start method ... } __1 If there are no entries I initialize the list to valid default values __2 I store the list of objects to the Storage as JSON. Notice this is a static method as we already have object instances in the list __3 Loading the JSON does require an object type for context __ Notice that this won’t work for JSON that contains more than one type of object. So I can’t store Contact and Person in a single JSON file The resulting JSON file looks like this:\n[{ \u0026quot;gender\u0026quot;: \u0026quot;Male\u0026quot;, \u0026quot;name\u0026quot;: \u0026quot;Shai\u0026quot;, \u0026quot;dateOfBirth\u0026quot;: \u0026quot;2018-08-14T18:27:43.585\u0026quot;, \u0026quot;id\u0026quot;: 1 }, { \u0026quot;gender\u0026quot;: \u0026quot;Male\u0026quot;, \u0026quot;name\u0026quot;: \u0026quot;Steve\u0026quot;, \u0026quot;dateOfBirth\u0026quot;: \u0026quot;2018-08-14T18:27:43.585\u0026quot;, \u0026quot;id\u0026quot;: 2 }, { \u0026quot;gender\u0026quot;: \u0026quot;Male\u0026quot;, \u0026quot;name\u0026quot;: \u0026quot;Chen\u0026quot;, \u0026quot;dateOfBirth\u0026quot;: \u0026quot;2018-08-14T18:27:43.585\u0026quot;, \u0026quot;id\u0026quot;: 3 }] Notice that the date is listed using the new standard format for date strings.\nNow that the data is persistent lets create a table to edit this data.\nThe Table UI The table binding code from which this post originates produces this output for the Contact object:\nFigure 1. Property Table for the Contact Object\nThis was essentially created using these three lines of code:\nContact prot = new Contact(); UiBinding.BoundTableModel tb = ui.createTableModel(listOfContacts, prot); Table t = new Table(tb); The first line uses a prototype object based on which the table structure is determined. Next we create a table model of the type BoundTableModel which includes some special capabilities I’ll cover soon. The next line creates the table…​ That’s it!\nThe full code doesn’t contain all that much more:\nForm hi = new Form(\u0026quot;Property Table\u0026quot;, BoxLayout.y()); UiBinding ui = new UiBinding(); Contact prot = new Contact(); UiBinding.BoundTableModel tb = ui.createTableModel(listOfContacts, prot); tb.setMultipleChoiceOptions(prot.gender, \u0026quot;Male\u0026quot;, \u0026quot;Female\u0026quot;, \u0026quot;Unspecified\u0026quot;); Table t = new Table(tb); hi.add(t); hi.getToolbar().addMaterialCommandToRightBar(\u0026quot;\u0026quot;, FontImage.MATERIAL_ADD, e -\u0026gt; tb.addRow(tb.getRowCount(), new Contact(). name.set(\u0026quot;Unnamed\u0026quot;))); hi.getToolbar().addMaterialCommandToRightBar(\u0026quot;\u0026quot;, FontImage.MATERIAL_REMOVE, e -\u0026gt; { if(t.getSelectedRow() \u0026gt; -1) tb.removeRow(t.getSelectedRow()); }); hi.getToolbar().addMaterialCommandToRightBar(\u0026quot;\u0026quot;, FontImage.MATERIAL_SAVE, e -\u0026gt; PropertyIndex.storeJSONList(\u0026quot;contacts.json\u0026quot;, listOfContacts)); hi.show(); You will notice I set multiple choice options for the gender. That means that when someone clicks the gender column they will see this:\nFigure 2. The gender option is a picker\nThat’s really cool but it gets better. The date column implicitly uses a date picker:\nFigure 3. The date is implicitly a picker\nNotice the commands in the source above, they include some familiar code (such as the save method). But the other commands include new methods that aren’t available in the standard TableModel class.\nThe BoundTableModel includes a few features that aren’t available in TableModel specifically:\npublic void excludeProperty(PropertyBase b); __**(1)** public void setColumnOrder(PropertyBase... columnOrder); __**(2)** public void setEditable(PropertyBase pb, boolean editable); __**(3)** public void addRow(int index, PropertyBusinessObject b); __**(4)** public void removeRow(int index); public void setMultipleChoiceOptions(PropertyBase prop, String... values); public void setValidationConstraint(PropertyBase prop, Constraint c); __**(5)** __1 Allows us to hide a column from the table __2 Allows us to determine the order of the columns, normally they are in the order they are added to the PropertyIndex __3 We can flag a specific property as non-editable __4 Add/remove a row will also update the origin list or property __5 We can bind validation logic to a specific property Abstract Table Model A lot of the power of this class is enabled via the new AbstractTableModel class. Up until now TableModel was the base interface that was implemented by DefaultTableModel. It’s a good abstraction but we needed a way to add new API’s without changing the interface.\nHad we migrated the core of Codename One to Java 8 we might have used default methods. Instead we added a new abstract class that implements all the new API’s we need from TableModel. Table now has special cases internally for AbstractTableModel.\nMost of the API’s in AbstractTableModel map directly to the functionality you see above. E.g. public Class getCellType(int row, int column) allows the Table to to generate the right cell type by default.\nFinal Word This is relatively simple, I could have gone much further. I could have used an auto generated UI to edit individual rows etc. But I wanted to keep things simple and manageable.\nAs you can see from the blog, this week I’ve been playing a lot of catch up with updates on where we are. There is a lot more coming as we ramp up to Codename One 5.0 in September.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/table-property-mapping/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/table-property-mapping/properties.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIf you aren’t using properties with Codename One, you probably should. Here’s a \u003ca href=\"/blog/properties-are-amazing.html\"\u003epost I wrote a while back covering them\u003c/a\u003e, it should give you a lot of reasons for this. We are slowly integrating them into API’s such as \u003ccode\u003eRest\u003c/code\u003e and as a result the code is simpler. A huge bonus is the type safety and flexibility that comes with this API.\u003c/p\u003e\n\u003cp\u003eUp until now binding in properties was mostly limited to \u0026ldquo;simple\u0026rdquo; classes such as \u003ccode\u003eTextField\u003c/code\u003e. Complex structures such as \u003ccode\u003eTable\u003c/code\u003e weren’t supported. This is no longer the case.\u003c/p\u003e","title":"Table Property Mapping"},{"content":"\nWhen we announced the migration to the new cloud servers one of the casualties was the cloud email API. This was a well intentioned API for sending an email from an app. Unfortunately we didn’t understand the complexities of modern mail systems well enough when we came up with this API. It turns out that this is pretty problematic. Mail servers get blacklisted and emails fail to deliver.\nThe problem is that this impacts everyone, if one bad actor sends spam with our cloud servers all of us get blacklisted…​\nThe solution is simple. We now have a new cn1lib for SendGrid. If you aren’t familiar with SendGrid it’s one of the several leading transactional e-mail providers. They offer 100 free emails per day. They provide a powerful developer REST API which we utilize in this cn1lib.\nIf you are using the cloud email feature we strongly suggest migrating your code to this cn1lib ASAP. We usually try to give more notice in advance but the app engine backend is something we need to remove in the near future.\nNote that this only applies to the send email via cloud API’s and not to the standard send email API’s which are just fine! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — August 14, 2018 at 12:39 pm (permalink) Francesco Galgani says:\nThank you. I suppose that you suggest to replace the use of Message.sendMessageViaCloudSync, while we can continue to use the Log.sendLog, right?\nShai Almog — August 15, 2018 at 3:24 am (permalink) Shai Almog says:\nYes!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/sendgrid-cn1lib/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/sendgrid-cn1lib/meeting.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen we announced the migration to the new cloud servers one of the casualties was the cloud email API. This was a well intentioned API for sending an email from an app. Unfortunately we didn’t understand the complexities of modern mail systems well enough when we came up with this API. It turns out that this is pretty problematic. Mail servers get blacklisted and emails fail to deliver.\u003c/p\u003e","title":"SendGrid cn1lib"},{"content":"\nWe added a lot of features and fixed bugs over the past couple of months and I’ve been a bit lax on blogging. I’ll try to fix that as we approach the revised 5.0 release date. One of the big changes we added over the weekend (it will be in the builds on Friday), is a huge rework of the Rest API.\nIf you are unfamiliar with the Rest API check out this older post. The Rest API had a few problems, the most pressing of these was the inconsistent error handling behavior. A failure of the Rest call didn’t always trigger error handling correctly and behaved inconsistently on reading the response of the error.\nAnother inherent problem which we ran into was processing errors differently. E.g. I have a JSON webservice but an error might return a String instead of JSON. With the existing API there was no way of handling this.\nThis mostly impacted the asynchronous calls but was a problem with the synchronous calls too. Another problem was the SuccessCallback interface used through the API. In itself it’s fine but the callback method is named: onSucess which somehow slipped through…​\nUnfortunately fixing interfaces is nearly impossible so we had to add a new interface OnComplete. Like the SuccessCallback the interface is \u0026ldquo;lambda friendly\u0026rdquo; by featuring only one method.\nA Word About Deprecation We use deprecation a lot to indicate the better API for usage. As a result we had to deprecate all the existing asynchronous calls in the Rest class and replace them with new API’s.\nWe won’t remove these deprecated API’s in the foreseeable future. The deprecation is there to show the better/newer API’s.\nBetter Properties Integration As part of this work we also squeezed in some work on property business object support. So if I want to make a JSON request to the server with a User PropertyBusinessObject I can do something like:\nUser userPropertyObject = ...; ServerResultObject result = Rest.post(url). jsonContent(). body(userPropertyObject). getAsProperties(ServerResultObject.class); Notice that the result can also be parsed from JSON into a property business object seamlessly!\nFetch API’s The existing synchronous get API’s such as getAsString() didn’t change. We left the signature as is and they should work the same way.\nHowever, the asynchronous API’s relied on the old SuccessCallback interface so we had to change the signature. If this was old Java 5 we could have just overloaded the method but this would have created a conflict for lambda calls so we decided to change the method name to a fetch prefix.\nSo the existing code:\nRest.get(url). getAsString(c -\u0026gt; callback(c)); Would become:\nRest.get(url). fetchAsString(c -\u0026gt; callback(c)); Since I used a lambda the fact that we replaced SuccessCallback with OnComplete becomes irrelevant.\nAll the versions of the methods that received FailureCallback instances are now deprecated as there were serious problems with error handling.\nError Handling The new error handling code is far more consistent and would work both for the synchronous and asynchronous calls. Notice that if you don’t define an error handler the behavior in the case of an error might be slightly inconsistent but should generally just return the error value in the standard response.\nE.g.:\nRest.get(url). jsonContent(). onErrorCodeString(r -\u0026gt; error(r)). fetchAsJsonMap(c -\u0026gt; callback(c)); There are five new onError style methods:\npublic RequestBuilder onErrorCodeBytes(ErrorCodeHandler\u0026lt;byte[]\u0026gt; err); public RequestBuilder onErrorCodeJSON(ErrorCodeHandler\u0026lt;Map\u0026gt; err); public RequestBuilder onErrorCode(ErrorCodeHandler\u0026lt;PropertyBusinessObject\u0026gt; err, Class errorClass); public RequestBuilder onErrorCodeString(ErrorCodeHandler\u0026lt;String\u0026gt; err); public RequestBuilder onError(ActionListener\u0026lt;NetworkEvent\u0026gt; error); The first four methods are invoked for an error code from the server (value that isn’t 2xx or 3xx from the HTTP response). Notice that each type parses the result and can use a different parsing system from the default parsing logic. We even support parsing errors into a PropertyBusinessObject which can be of a type different from the one used in the main result. So you can define a ServerError business object and parse error result JSON directly into a type-safe object.\nThe ErrorCodeHandler interface is a simple lambda friendly interface that returns the Result object.\nThe last method onError is invoked in case of an exception during the connection. We separate a failure such as exceptions which occur due to connectivity or physical issues from a server error code failure. Normally, I would recommend ignoring onError and focusing on a global error handler using NetworkManager as exists in the boilerplate code in a new project.\nMoving Forward Let us know what you think of these changes and how we can further improve the syntax/utility of this API. I think there is a lot we can do to take it forward.\nTwo omissions in the API that I’ve run into over the years are:\nSupport for XML — this should be easy to add but there wasn’t much demand for it. If there is we can probably add XML support too\nImage handling — we already have great Image download/caching API’s so we didn’t add them to this class. I’m not sure if this would be the right API to do image requests but it might\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/rest-api-error-handling/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/rest-api-error-handling/new-features-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe added a lot of features and fixed bugs over the past couple of months and I’ve been a bit lax on blogging. I’ll try to fix that as we approach the revised 5.0 release date. One of the big changes we added over the weekend (it will be in the builds on Friday), is a huge rework of the \u003ccode\u003eRest\u003c/code\u003e API.\u003c/p\u003e\n\u003cp\u003eIf you are unfamiliar with the \u003ccode\u003eRest\u003c/code\u003e API check out this \u003ca href=\"/blog/terse-rest-api.html\"\u003eolder post\u003c/a\u003e. The \u003ccode\u003eRest\u003c/code\u003e API had a few problems, the most pressing of these was the inconsistent error handling behavior. A failure of the \u003ccode\u003eRest\u003c/code\u003e call didn’t always trigger error handling correctly and behaved inconsistently on reading the response of the error.\u003c/p\u003e","title":"Rest API Error Handling"},{"content":"\nStarting this weekend builds sent using the old plugin or an old project will fail. You will need to update the plugin to 4.3 (or 4.0.3 in NetBeans) or newer. This is an important phase in removing App Engine from our build stack and moving to a new system.\nIf you are experiencing problems with a project do the following:\nRight Click the project\nSelect Codename One → Codename One Settings or Codename One Preferences\nClick Basic\nClick Update Project Libs in the bottom left side\nWhat’s Next? After this initial phase we plan to delete the app engine server. This will clean up our legacy system completely. It also means that if you created a Codename One account in the past and haven’t been active your account might vanish.\nIn that case you would need to create it all over again.\nWhy are we Doing This? The old system based on App Engine is unmaintainable and fundamentally broken. Unfortunately, even basic features on app engine just don’t work so we can’t even keep this running.\nUsing our own servers has been liberating and far more powerful. This is a move we should have completed years ago. Once App Engine is completely out of the way we’ll be able to deliver some services we’ve had on the drawing board for years. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nGareth Murfin — August 8, 2018 at 4:38 am (permalink) Gareth Murfin says:\nAwesome cant wait to see the new stuff.. I always assumed app engine was perfect but I dont think ive got around to really using it much.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/ending-support-for-legacy-cloud/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/ending-support-for-legacy-cloud/looking-forward.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eStarting this weekend builds sent using the old plugin or an old project will fail. You will need to update the plugin to 4.3 (or 4.0.3 in NetBeans) or newer. This is an important phase in removing App Engine from our build stack and moving to a new system.\u003c/p\u003e\n\u003cp\u003eIf you are experiencing problems with a project do the following:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eRight Click the project\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eSelect Codename One → Codename One Settings or Codename One Preferences\u003c/p\u003e","title":"Ending Support for Legacy Cloud"},{"content":"\nI used to do a lot of enterprise consulting in the day and used to lecture a lot on J2EE (as it was known back then). A lot of that knowledge isn’t as applicable even in the server side today, but the algorithms are surprisingly even applicable in mobile.\nOne of the algorithms I would explain a lot when teaching J2EE was the 2PC AKA Two Phase Commit.\nThis is builtin to enterprise servers but I won’t go into that here, there is plenty of discussion about that online. What matters to me is how this can be used in a mobile context to build an app that’s friendly for offline/online modes.\nWhat’s 2PC To understand 2PC you need to understand what’s a transaction. I hope you do but just in case you don’t here’s an oversimplified definition: A transaction contains more than one operation where we want all the operations to succeed or we want all of them to fail.\nThis is explained with a simple example of a transfer between two bank accounts: If I transfer $5 from my account to my friends account I want the deduction of $5 to be in the same transaction as adding the $5. Otherwise if there is a failure money can evaporate and vanish!\nHere’s where 2PC comes in, say my account is in one bank and my friends is in another bank in a different server (obviously this is more complicated, again over simplifying). How would that work?\nThe two phase commit splits every transaction into two phases:\nPerform the operations of the transaction but don’t commit\nPerform the actual commit\nThat way a system can send all the separate operations to all the servers (yes there can be more than two…​) and when all the servers say they can perform the commit it will notify them all to commit. There are still points of failure in this system but usually when it fails it will be more consistent.\nWorking Offline in a Mobile Device Offline synchronization is one of the hardest things to do right in mobile. Especially in cases where your network is unreliable.\nSome apps just fail and ask for a valid network connection. But there’s another way.\nAssuming you have a cached local database you can let the user keep working locally and then synchronize the data with the server once you get access. This obviously carries several risks:\nConflict – user changes might conflict with changes going on in the server while he is working offline\nSynchronization – you would need to somehow synchronize the changes to the server\nConnection Reliability – if server synchronization fails the client and server might be left in an illegal state\nThat’s where the key ideas of two phase commit become applicable.\nCommand Pattern Don’t be confused with the Codename One Command class. The GoF Command pattern represents a queue of tasks that allow us to perform the tasks in order. Assuming your server contains a set of REST calls a command would probably map to each call.\nSo if we proceed with the bank account transfer analogy I’ll have a command that says \u0026ldquo;transfer $5 from account X to account Y\u0026rdquo;. The implementation of said command could just invoke the REST API. However, when we are offline we can just log the command to run later when we are online.\nWe can create a queue of offline commands and wait for the moment we get a stable server connection so we can send the commands in queue.\nAll, Nothing or Conflict Here’s the tricky part. The server might have changed and the client might have multiple commands.\nIn an ideal world we can just perform the REST call for each command and be done with it. In practice this can make things worse. If the server changed we can get a conflict. We can also succeed with some operations and fail with others which can create an illegal state in the client.\nThe solution is to have a similar command abstraction in the server to support the offline mode. So when we go back online instead of sending the regular REST requests we’ll send a special set of commands e.g.:\n/beginTransaction – would return a transaction id. It might also accept a timestamp which could be useful for conflict detection on the server. The server can use timestamps on database entries to indicate when they were changed. Your timestamp would indicate when you last fetched the database so if an entry was changed since you fetched the database you might have a conflict.\nSend REST calls with special transaction=id parameter or HTTP header. These operations won’t commit but would return an error in case of a failure. Handling this error is the interesting part. You can do that per-command and let the user decide if this command is crucial or not. You can offer a UI to merge a command or discard it. You can offer to discard all local changes etc.\nAssuming all went well you can send a commit call.\nThis sounds a bit difficult but once you divide things correctly and make them modular enough it isn’t very hard.\nSummary You need to think in advance about offline/online in some systems. If you are building a social network it isn’t a big deal if some data is stale or offline behavior isn’t perfect. But if you are building something that needs reliability you need to understand this theory.\nSome tools try to abstract these ideas. That sometimes creates a situation of automatic merges (or failures) that don’t give the user enough control. Even if you use such a tool you need to have a decent understanding of the underlying logic. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — July 30, 2018 at 10:32 pm (permalink) Francesco Galgani says:\nIt’s very interesting. Thank you!\nAbout the knowledge, my opinion is that the most of things expires soon… but the good ideas will never expire.\nZombieLover — September 4, 2018 at 10:46 am (permalink) ZombieLover says:\nI used a local SqlLite DB and a server side DB that stores the transactions in a large txt field\nUsers can upload changes which basically sends the queries they executed on local db and a timestamp (send via rest API)\nDownloading changes then gets all the stored queries on the Server after the timestamp they last updated their local db with (which is kept in a local variable) and executes them on localDB\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-use-two-phase-commit-for-offline/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-use-two-phase-commit-for-offline/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI used to do a lot of enterprise consulting in the day and used to lecture a lot on J2EE (as it was known back then). A lot of that knowledge isn’t as applicable even in the server side today, but the algorithms are surprisingly even applicable in mobile.\u003cbr\u003e\nOne of the algorithms I would explain a lot when teaching J2EE was the 2PC AKA Two Phase Commit.\u003c/p\u003e","title":"TIP: Use the Two Phase Commit Algorithm for Offline Support"},{"content":"\nThe most common question we get about Codename One is: \u0026ldquo;Is Codename One Free\u0026rdquo;. The direct answer is \u0026ldquo;Yes\u0026rdquo; but we don’t want to mislead. You can work with the open source code, which is just as free as any other project. But it’s not for the faint of heart…​\nThe build servers have quotas so we won’t go out of business. This is perceived by developers as \u0026ldquo;not free\u0026rdquo; but since no one else offers build servers I have an issue with that perception. To battle that perception we’re increasing the build quotas.\nSort of…​\nTo keep us sustainable paying users essentially pay for the free users. Worse, it’s only the pro/enterprise accounts that cover these costs.\nSo in order to increase the quotas we need your help. We’ll give you increased quotas for friends of yours that join e.g. you bring your friends and we’ll increase your build quotas respectively.\nFor every friend we’ll add 512kb to your jar size limit and 50 build credits. This is a permanent addition that will come into effect during the quota reset (it isn’t immediate). We’ll also count that friend as if he referred one person already so he’ll have more than the default count!\nCurrently this is capped off at 15 friends which should give you plenty of room to grow.\nThese benefits are perpetual and aren’t dependent on your friends staying or paying. However, we reserve the right to revoke these credits for abuse of this system!\nHere’s the kicker, we just updated all the users in the database currently to 1 referral by default. So all active Codename One users should already have a larger build credit by default. Due to technical reasons we can’t do it to old users that didn’t use Codename One since our migration from App Engine…​\nHow Does it Work? You can invite friends by sharing a special URL which you can see in your console here under the Account tab. E.g. mine is: \u0026lt;/index/?ref=baa9d923-b26a-430b-a814-02cf55605231\u0026gt;.\n__ You might need to logout and login again to see this entry. It should be below the token The important aspect here is the ?ref=baa9d923-b26a-430b-a814-02cf55605231 part. You can attach it to any html URL in this site including this page e.g.: \u0026lt;/blog/increase-your-build-quotas/?ref=baa9d923-b26a-430b-a814-02cf55605231\u0026gt; would be valid.\nHowever \u0026lt;https://www.codenameone.com/?ref=baa9d923-b26a-430b-a814-02cf55605231\u0026gt; isn’t valid as it doesn’t contain an html file in the URL.\nTerms and Questions Does this Apply to Paid Users? Yes. If you ever cancel your account you’d revert to paid mode and still have your increased credits. If you signup for a paid program and downgrade you won’t lose any signups during the paid duration or after.\nHow does this Work? The referral URL sets a cookie in the users browser that is active for 6 months. If during those 6 months the user signs up he is counted.\nYou would need to promote Codename One to your friends/social network to get the additional credits.\nWhat if a User Clicks two URL’s? The last one is counted. This is the industry standard.\nHow can I Monitor This? Right now you will only know when the build credits are reset. However, we plan to introduce a UI that will let you see how many users you referred.\nHow do you Check for Abuse? We only count activated users. We check user behavioral patterns through an automated system that alerts us of potential abuse.\nFuture Directions We’d like to extend this to push notification as well. We have some ideas on how to provide push support for free/basic accounts but for that we would probably want to redesign our push servers.\nThat’s a bit of an undertaking and we’ll only start that off if this program proves successful.\nI hope you all take advantage of this as much as possible!\nA Word About the 1MB Jar Size\nWe’re doing this mostly to battle a perception issue. The JAR size limit should be enough for relatively demanding apps. It’s generally a good practice to stay within it.\nThe JAR size limit refers to the size of the JAR sent to the server. Not the one returned.\nNative libs are essentially free since they are fetched from gradle/cocoapods. By default a clean hello world app is around 2-3kb and the Uber/Facebook clones fall well below the 1mb limit.\nIt’s a good limit to abide by. It means your builds will be faster and the end result application will be smaller. You shouldn’t need a larger app size.\nKeep in mind that a 1mb jar app can grow up to 16 times on iOS and a bit less on Android. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nSynapsido — August 21, 2018 at 12:22 am (permalink) Synapsido says:\nI’m free user for now, I have several developer fiends invited, where can I see my total Quotas in my account…?\nShai Almog — August 21, 2018 at 8:23 am (permalink) Shai Almog says:\nOn the first of the month when your credits are reset you can see how many clicked and created an account based on the build credits you would have.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/increase-your-build-quotas/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/increase-your-build-quotas/generic-java-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe most common question we get about Codename One is: \u0026ldquo;Is Codename One Free\u0026rdquo;. The direct answer is \u0026ldquo;Yes\u0026rdquo; but we don’t want to mislead. You can work with the open source code, which is just as free as any other project. But it’s not for the faint of heart…​\u003cbr\u003e\nThe build servers have quotas so we won’t go out of business. This is perceived by developers as \u0026ldquo;not free\u0026rdquo; but since no one else offers build servers I have an issue with that perception. To battle that perception we’re increasing the build quotas.\u003c/p\u003e","title":"Increase your Build Quotas"},{"content":"\nI’ve been working on the new \u0026ldquo;Create an Uber Clone in 7 Days\u0026rdquo; book for ages. After so much work this is finally almost done!\nWe have a release date: August 16th (yes 2018!). You can already pre-order the kindle edition but you’d get it for free if you buy the print edition which for some inexplicable reason can’t be pre-ordered.\nUPDATE: Since writing this I’ve added a dedicated book site, I’d rather you share that instead of the link to this post. It’s available here: https://uber.cn1.co/\nYou can see the preorder page on amazon here. For now the digital book is an exclusive on Amazon. This provides some visibility benefits that are helpful at this stage.\nI’m pretty happy with how the book turned out, it’s a huge leap over previous things we did. A lot of that is thanks to the huge effort of the multiple people who reviewed it over the course of its production. Unfortunately I don’t have access to the names of all the reviewers so if you aren’t mentioned here please contact me via the chat ASAP and we’ll fix that.\nLate stage reviewers of the book were very helpful so far, specifically Francesco Galgani, Rémi Tournier and Steve Nganga. Steve Hannah put so much effort into his review I gave him editor credits for the book.\nIn that sense this book is a team/community effort so in that spirit I’m publishing the first two chapters and all of the appendices for free!\nI’m publishing them in the PDF format which was developed for the print book. I would very much appreciate it if you spread the word on this. I’d prefer if you don’t send out the PDFs and instead send a link to this blog post so people can download the PDF from here. I don’t like those annoying sites that demand your email for download and we don’t do it here.\nIf you like what you read, the print book will be available for purchase on August 16th. Notice that the digital/kindle book has different formatting which is very noticeable in the source code listings.\nThis PDF is based on the print version, as a result it has asymmetric padding and layout. This allows elements to \u0026ldquo;bleed\u0026rdquo; to the edge of the page and provides a pleasant browsing experience when reading the printed documentation.\nThe first two chapters and appendices can be downloaded from here.\nYou can check out this article I wrote for Hackernoon. It explains some of the nitty gritty details of asciidoctor and professional book layout. So if you are curious why it took so long to get this book out, check out the before/after shots in that article.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/uber-book-release-date/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/uber-book-release-date/create-uber-clone-book-promo-1024.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been working on the new \u0026ldquo;Create an Uber Clone in 7 Days\u0026rdquo; book for ages. After so much work this is finally almost done!\u003cbr\u003e\nWe have a release date: August 16th (yes 2018!). You can already pre-order the kindle edition but you’d get it for free if you buy the print edition which for some inexplicable reason can’t be pre-ordered.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eUPDATE:\u003c/strong\u003e Since writing this I’ve added a dedicated book site, I’d rather you share that instead of the link to this post. It’s available here: \u003ca href=\"https://uber.cn1.co/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttps://uber.cn1.co/\u003c/a\u003e\u003c/p\u003e","title":"Uber Book Release Date"},{"content":"\nSteve just implemented one of the harder RFE’s we had in a while. It isn’t finished but we can already try some of these features and you should be able to try some of these rich types of push messages.\nThe difficulty stems from the way these push messages are implemented differently in the native OS’s outside of the domain where we have full control. As part of that work our entire developer guide section related to push was rewritten here: https://github.com/codenameone/CodenameOne/wiki/Push-Notifications\nIt isn’t available yet in the developer guide as I’m still busy with the book and would need to do some work to incorporate it correctly but this is a huge leap forward for our push support.\nWe’ll have more announcements about this in the coming months.\nValidation on iOS Francesco Galgani implemented this pull request which animates validation errors in InputComponent on top of the Label.\nThis was merged and looks great but it did create a regression in validation where regular text fields fail at the moment and throw an exception. We might push a hotfix on Thursday to fix that issue.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tich-push-notification-improved-validation/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tich-push-notification-improved-validation/new-features-4.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSteve just implemented one of the \u003ca href=\"https://github.com/codenameone/CodenameOne/issues/2208\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eharder RFE’s\u003c/a\u003e we had in a while. It isn’t finished but we can already try some of these features and you should be able to try some of these rich types of push messages.\u003c/p\u003e\n\u003cp\u003eThe difficulty stems from the way these push messages are implemented differently in the native OS’s outside of the domain where we have full control. As part of that work our entire developer guide section related to push was rewritten here: \u003ca href=\"https://github.com/codenameone/CodenameOne/wiki/Push-Notifications\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttps://github.com/codenameone/CodenameOne/wiki/Push-Notifications\u003c/a\u003e\u003c/p\u003e","title":"Rich Push Notifications and Improved Validation"},{"content":"\nOver the weekend we migrated a huge amount of code to the new build servers. In this post I’ll try to cover three separate things. I’ll explain the architecture/history and process of the migration. What worked, what didn’t work and lessons learned. And finally how this will impact Codename One users moving forward.\nI’ll start with a bit of history to explain the background and motivations. We formed Codename One in January 2012. Back then Chen and I worked in full startup mode in an accelerator. Chen never worked in a startup before and was amazed by the pace of work, he quipped that we did more work in 3 months than we did in 5 years at Sun Microsystems!\nThe build cloud was built during that time but was refined over the past 6 years to suit our growing needs. We made the mistake of picking App Engine for the build cloud as we wanted to shorten the time to market while keeping the implementation scalable. The fact that Google offered free hosting credits for startups was also a big incentive.\nThe build cloud was built as a monolith, this isn’t a bad thing. In fact Martin Fowler specifically advises that people start with a monolith architecture first. The cloud server doesn’t actually do the builds, for that we need dedicated standalone servers (e.g. Macs, Windows machines etc). It essentially orchestrates all the disparate pieces so they will work together. In the past it handled a lot more but as the years went by we chopped out pieces one by one to move into a microservices architecture e.g.:\nPush Crash protection Build file submission Build server web UI And more. We tried to remove everything since app engine is just SO bad but still quite a few things remained in the cloud servers:\nUser authorization/signup/activation Build orchestration – submit, status, server assignment etc. Billing – we don’t store billing information but PayPal notified the old servers on payment Some of the transactional mail infrastructure The first two are big pieces that include a lot of code. They are also deeply tied to everything else.\nWhen we started off with App Engine we believed Google’s claims that it supports JPA. To keep our code portable we used JPA so we’d be able to migrate away. As we discovered JPA support on App Engine is a sad joke. Basic functionality didn’t work and failed painfully, ironically these failures occurred only when the business scaled so instead of smooth performance degradation we got downtime.\nAs we moved ahead we rewrote a lot of JPA code to use the App Engine entity API and memcached. Thankfully we saved a lot of the old JPA code.\nOver the past year updating the App Engine deployment became impossible as Google blocked the old plugin it used to support App Engine. The approach of migrating to a completely new project structure is poorly documented and seems like a huge risk as things might fail badly. So we had no choice.\nHow does it Work? We’ve worked a lot with Spring Boot while developing the courses and upcoming book. The speed of development and ease of use is at a different scale altogether.\nWith that in mind we decided to do a live migration to a Spring Boot server that would work as a drop in replacement to app engine. To keep scalability in place we decided to use cloudflare (as we do on the main website). It makes scaling remarkably easy.\nBecause we already extracted the build UI from app engine in the past and now host it as part of our website, we have a clear API to the backend server. With that we could change all the calls that go into the app engine server and just point the exact same calls into the new cloud server. The cloud server decides whether it should handle a call locally or ask App Engine to perform the call for it. In this way we added a new layer for existing users, but it should be 100% compatible and shouldn’t fail.\nThe reason we had to take this approach is due to the plugins, since they are installed on the end user machines some might still point at the old App Engine. We don’t want all builds to break suddenly. We’d like users to move away gently from the old App Engine deployment.\nNormally rewriting from scratch would have been easier but because we wanted as little disruption as possible we tried to setup the new Spring Boot server to be 100% compatible so we had to import code and try to convert the old mishmash of servlets with no tiers to a proper architecture that separates tiers properly. It still looks a bit messy as the original wire protocol is messy. But now that this is behind us we’ll be able to revisit this and improve a lot of the missing pieces.\nWhat went Wrong? A lot of things failed in unexpected ways.\nThe biggest problem we ran into in production was due to cloudflare. Cloudflare blocks DDoS attacks and one of the tricks it uses is blocking all traffic that doesn’t include the User-Agent header. A lot of our code uses the URL class and doesn’t add that header. So basic things worked great in the development environment but failed in production.\nWe migrated a lot of the old numeric keys as we moved from the datastore to SQL. So the new String based keys worked reasonably well but a couple of JavaScript client side functions used syntax such as: doThis(id).\nThis seemed to work but just failed silently when the key was a string. We had to add quotes to those methods to get it through. Since there are so many nuanced features in the platform we just missed testing this.\nSome OTA and install features failed in production. This relates to relatively hidden/obscure code in the app engine implementation that we completely missed. In fact we used JSP for a couple of features in the old app engine. While Spring Boot supports JSP it has some deployment limitations so we just translated that code to a standard webservice call. Not an ideal solution but since there was so little code to port it was something we could address.\nAfter working a bit Spring Boot would fail with RAM errors. Turns out we need to explicitly set the Xmx/Xms flags in Spring Boot using a conf file. We didn’t run into it in previous deployments as we didn’t do some of the heavy IO that we do here.\nWhat Worked Great So many things \u0026ldquo;just worked\u0026rdquo;!\nThe migration to SQL was mostly smooth and included only a few pitfalls/schema changes. Being able to use proper SQL instead of datastore is a huge step forward. It’s so much faster we don’t need memcached and get better performance to boot!\nThe truly amazing thing is the queries and 3rd party tools. This has boosted our ability to address issues tremendously.\nDespite the User-Agent issue cloudflare is a huge asset. It makes caching repeated queries trivial. Better yet, since we now proxy some downloads through the servers we can get faster/more reliable downloads thanks to cloudflare.\nI can’t sing the praises of Spring Boot enough, it makes this trivial. It has it’s pain points (unreadable huge stack traces) but the ease of development is amazing. We manage our own infrastructure now through IaaS. It’s easier, faster, cheaper and scales better than the previous PaaS deployment. Four out of four criteria.\nWhile we didn’t test scaling to the full extent so far CPU utilization is flat/low. This architecture would probably scale much better than app engine ever did. Google sells App Engine as a \u0026ldquo;Google Scale\u0026rdquo; solution but anyone who worked with it will know that this only applies if you can spend \u0026ldquo;Google Sums\u0026rdquo; to pay for that. App Engine tries to scale by adding computing resources instead of just slowing down.\nThat means that if you have 10k active users you’d pay for a lot of servers to handle them. Our current solution can handle 10k concurrent users easily. It would slow down but wouldn’t crash. It would still be cheap thanks to Linode.\nWe also took the opportunity to move most of our transactional emails to mailgun. So if you get an email from us you will notice it uses a different domain. One of the big problems developers had with signup in the past was due to corporate inboxes relegating us to spam. We made some bad technical choices assuming SendGrid can help us fix these issues. This probably isn’t SendGrid’s fault as much as it’s our lack of understanding in this field.\nWe decided to start a new leaf with a new domain for the emails. We didn’t move everything there and I’m not sure if we ever will as I’m concerned about deliverability. Regardless this is seems to be a good move as we have 100% deliverability so far.\nHow could this Impact You I already discussed some of these here. But there is one additional entry in the pile: IPN.\nWe handle our subscriptions via PayPal. We’d love to add other options but there are logistical issues with global deployments for all of them. We don’t want any billing data on our servers as we don’t want to deal with that complexity.\nPayPal billing can work via a solution called IPN which means paypal invokes us on every billing. That way we can update our user database based on payment received. So far so good.\nUnfortunately you can’t change an IPN address after it was set. So existing subscribers still point to the old app engine URL. We have a workaround of polling app engine for subscription level for existing subscribers. This only impacts current paying users and might cause a situation where your subscription appears to have 2 days left even if it has more.\nWe plan to migrate the project in app engine so the IPN will be the only remaining piece and it will point back to our server. To do that we’ll need to bring app engine offline and set it up with a new project. That will take time. So for now this workaround is in place.\nWe plan to disable app engine builds by the end of the month. That means you would need to update your plugins to the latest in order to build. If you don’t you would get an error. We would still not remove app engine as a few other features are harder to migrate over.\nWhat’s Next? Now that this is in place we can finally implement some cool features we’ve been craving…​ Higher build quotas for free users including features such as push notification etc.\nAll of these would be coming in the next few months…​\nI don’t want to announce dates as I’m still working on the book and we need to push out Codename One 5.0 but it’s coming and hopefully before 5.0 which is now slated for September. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nSteve Nganga — July 12, 2018 at 11:26 am (permalink) Steve Nganga says:\nGood read… just a quick one. much has been said on vertx on the backend, is this something you ever thought of using as opposed to springboot….\nLukman Javalove Idealist Jaji — July 12, 2018 at 1:18 pm (permalink) Lukman Javalove Idealist Jaji says:\nFantastic read and kudos to you and the team.\n\u0026ldquo;Higher build quotas for free users including features such as push notification etc\u0026rdquo;…\nDoes this mean we may get push features with basic subscription at least?\nShai Almog — July 13, 2018 at 5:00 am (permalink) Shai Almog says:\nI know quite a few people that use Spring Boot and don’t personally know anyone that uses vertx. It looks interesting but there are a few things that make me think vertx isn’t the right solution for us:\n– JPA – I like JPA. It exposes SQL etc. but doesn’t seem to promote JPA. I’m sure I can integrate hibernate etc. but that would already mean more work than Spring Boot.\n– It \u0026ldquo;isn’t opinionated\u0026rdquo; – I think that’s conceptually wrong. I don’t think a framework can be everything to everyone and still be good. You need to have opinions and optimize to those opinions otherwise you provide a sub par experience to everyone\n– Legacy – one of the cool things I have with Spring Boot is support for legacy code and features. I could just stick an old servlet \u0026ldquo;as is\u0026rdquo; without rewriting the very sensitive code I had there. It’s really convenient\n– Deployment – deploying a Spring Boot app in linux as a service is amazing. It generates a special JAR that works as a Linux service… The whole story \u0026ldquo;just works\u0026rdquo;.\nAgain, I’m writing this without spending one minute playing with vertx so I might be completely wrong.\nShai Almog — July 13, 2018 at 5:04 am (permalink) Shai Almog says:\nThis is still in tentative so keep that in mind. These plans can change as we refine things.\nOur goal is to offer 100 free push messages per month for everyone so you can test the push functionality for free. We will treat basic/free users in the same way when it comes to push.\nThe goal is to provide an incentive based system for promoting Codename One and increasing the quotas accordingly. I think push will still cap at some level but we haven’t decided the full details yet.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/migrating-app-engine-spring-boot/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/migrating-app-engine-spring-boot/generic-java-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOver the weekend we migrated a huge amount of code to the new build servers. In this post I’ll try to cover three separate things. I’ll explain the architecture/history and process of the migration. What worked, what didn’t work and lessons learned. And finally how this will impact Codename One users moving forward.\u003c/p\u003e\n\u003cp\u003eI’ll start with a bit of history to explain the background and motivations. We formed Codename One in January 2012. Back then Chen and I worked in full startup mode in an accelerator. Chen never worked in a startup before and was amazed by the pace of work, he quipped that we did more work in 3 months than we did in 5 years at Sun Microsystems!\u003c/p\u003e","title":"Migrating from App Engine to Spring Boot"},{"content":"\nThis is important! We will replace the entire build infrastructure of Codename One over this weekend. That means that you might see disruptions in service through the weekend but please report them to us as we might not be aware!\nWe are finally removing the last remaining pieces of the horrible mess that is Google App Engine from our backend code. This is a huge job and is sure to cause some disruption.\nIn the long term this is great news. It means our servers will be modernized. As a result they will be better equipped to adopt new features that we’ve rejected in the past due to the age of the infrastructure. The downside is this bump in the road.\nA huge part of the difficulty is switching the servers while avoiding disruption and letting you all upgrade your plugins at your own pace. We tried to create the new server in such a way that it would proxy into the old server so builds would seamlessly work even if you still use an old plugin. This should work great for simple cases but might introduce issues with edge cases. E.g. if you have two machines and only updated the plugin/libraries in one of them.\nThis might create regressions as the infrastructure is quite complicated but we hope we can resolve them quickly now that we have better control over the server process.\nA Few Things Will Change As part of this change we need to change/deprecate some niche features that haven’t been used as much:\nLog.getUniqueDeviceId() will return -1 after this update and will no longer work for new builds. You will need to switch to Log.getUniqueDeviceKey() which returns a unique string\nAnalyticsService will now default to app mode. The old web mode is now officially deprecated and will stop working in the future\nCloud email which is used via the sendMessageViaCloud API will no longer work at some point (it does work now but we will eventually retire it). If you need an equivalent API we will introduce something via a cn1lib such as SendGrid integration etc.\nOther than that this change should be almost seamless for your app logic…​\nNo New UI Right Now This change won’t change a lot in terms of features right now. In the near future this will enable us to completely rebuild the UI of the build server. We have some big plans for that and I hope we’ll be able to deliver on them now that we have better control.\nBut first I need to finish the work on the damn book. After this whole side track on the server. While we’re on the subject, thank you all who sent feedback on the first chapter it was super helpful!\nI hope to have the second chapter out and about this week, it will take a while to complete everything as I’m going top-to-bottom through the book and it will take a while to finish the appendices.\nOnce the book is done I’ll publish the first two chapters and the appendices here for free. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — July 4, 2018 at 12:39 am (permalink) Francesco Galgani says:\nIn my apps I rely on sendMessageViaCloudSync to send to myself screenshots of the apps. I also use it to allow users to send to me technical assistance requestes. So… I hope that you will remove this API to send email only after an alternative method for your supported platforms will be ready. I also use Log.getUniqueDeviceId(), however replacing it with Log.getUniqueDeviceKey() it’s not a problem.\nShai Almog — July 4, 2018 at 4:24 am (permalink) Shai Almog says:\nRight now it will continue working. It invokes app engine so until we physically turn off the servers it will still work.\nThe reason we need to remove this is conceptual. We use one email provider to send an email for all users, but one bad actor who sends spam emails can destroy the deliverability of emails from everyone. This is already the case where we got blacklisted by some spam filters like spamcop.\nThe solution includes two separate actions. First we need to separate the email account so you would send using sendgrid, AWS or mailgun. All of these have a free quota e.g. 10k emails so you’d still be able to use them for free. Here we can offer a cn1lib that will interact with one of those. But there’s a problem. The credentials for these API’s should be in the server so a server will perform the operation. Right now we don’t store any private data in the cloud and don’t have the UI to do so.\nSending credentials from the client is possible but is inherently insecure. It’s not a big deal as those would be free accounts but still I wouldn’t want to throw away one broken solution for another…\nThanks for the headsup on using this, I’ll try to give this more thought and find a long term solution before we shut down the old server.\nFrancesco Galgani — July 4, 2018 at 10:35 am (permalink) Francesco Galgani says:\nThank you Shai, I understood what you wrote, however I have some dubts. I’m trying to expose my doubts in this comment. Because your current API can send emails only to the email account of the developer who sent the app to your build servers, I have difficult to understand that \u0026ldquo;sendMessageViaCloudSync\u0026rdquo; can be used to spam (assuming that a developer cannot spam to theirself). Moreover, this API is available only to Pro accounts, so I suppose that is virtually impossible that somebody pays a Pro account to send unwanted emails to theirself. In my experience, it’s very difficult to buy an IP that it’s not already inserted in one or more spam blacklists, so it’s normal that the IPs of your servers can be in one or more blacklists. Because all these facts, I don’t see a conceptual issue in your API… of course, I can be wrong. Thank you for any further clarification.\nShai Almog — July 5, 2018 at 4:01 am (permalink) Shai Almog says:\nWe just customize the from field. We don’t actually send an email as \u0026ldquo;you\u0026rdquo; since we use our servers to do so. That means the reputation for sending is shared with every Codename One user out there as the SMTP server IP address is what counts for a lot of spam filtering solutions e.g. Spam Cop.\nOtherwise every spammer could just randomly change the from field and spam away from one server (they actually do that but it’s useless). That means that if one Codename One user sends bad emails and his users flag them as spam we all pay…\nThe solution is different servers with different IP addresses that allow us to isolate ourselves from one another and build our own email sending reputation. Thankfully all email providers have a relatively generous free monthly quota (around 10,000 emails) so the question becomes how do we expose access to these services without risking your credentials… Thinking about this further I’m afraid there is no easy answer, there will always be a bit of a risk to credentials but I have an idea on how to accomplish this in a way that’s relatively intuitive.\nPlease file an issue on this I’ll try to push out a cn1lib to address this soon.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-build-cloud/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-build-cloud/generic-java-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eThis is important!\u003c/strong\u003e We will replace the entire build infrastructure of Codename One over this weekend. That means that you might see disruptions in service through the weekend but please report them to us as we might not be aware!\u003cbr\u003e\nWe are \u003cstrong\u003efinally\u003c/strong\u003e removing the last remaining pieces of the horrible mess that is Google App Engine from our backend code. This is a huge job and is sure to cause some disruption.\u003c/p\u003e","title":"New Build Cloud"},{"content":"\nA few years ago a consultant convinced us to integrate Intercom into our website. In retrospect this was a mistake which I’ll discuss in more depth below. We are migrating away from Intercom right now…​ That means that if you have an email address or ongoing chat history with us in Intercom it might get lost!\nWorse. If you unsubscribe this might also get lost due to the migration process (sorry about that!). We’re moving to a new far better system (crisp).\nWhat’s Intercom It’s the chat widget at the bottom right portion of the website.\nIt also handles the emails we send out offering help or pointing out information about Codename One. We use it to send out email announcements etc. It’s useful because when you reply to an email or chat it all goes to one place so we know who we’re talking with (sort of, it doesn’t do a great job). E.g. if you use the chat wizard then answer through email for us it’s one interface.\nWhy does it Suck Intercom is a bad product and to make things worse it’s expensive. It does the basic things reasonably well but it’s UX and UI are very badly designed for us and our audience.\nDespite Intercom’s many shortcomings we were lazy on the issue of migration as there is always something more important to do. Thankfully Intercom decided to change their pricing model so we’d pay 5x the already inflated price which was the perfect incentive for us to discover crisp which is far cheaper and seems like a better product altogether.\nWith this you should already see the new chat widget below and should be able to interact with us there…​ You can also check out the new https://help.codenameone.com/ website that was generated as apart of the process. Hopefully we’ll strengthen it with a bigger knowledge base.\nWhere Next Unfortunately this is just the tip of the iceberg. Intercoms code is embedded deep into the backend systems. The problem is we still have some app engine servers running and it’s really hard to update them as Google effectively killed off the system we were using. So we are finally doing what we procrastinated on for 3 years and removing app engine completely from our stack!\nThis is a HUGE move, I can’t over state it. All our user logs and everything is in app engine. That might mean that if you had an old \u0026ldquo;dormant\u0026rdquo; account that you haven’t used in years it might get deleted in the migration as we won’t be able to migrate it. That’s not a big deal since such accounts would typically be free accounts and you could just re-create that account. The bigger benefit is that we would be able to implement a lot of the features we always wanted to and couldn’t because of the problems in our backend!\nYou might notice some kinks in the migration let us know in the comments or the chat if things don’t work well. Setting up the automated emails from scratch will be a nightmare but it has to be done.\nThis might delay some things such as the book release, but we are making progress there…​\nI’m sending out an email with some more details there if you are interested. It will be the first email to go out with the new crisp system so hopefully this works out nicely. If you don’t get it let us know in the chat and we’ll try to track that with you.\nCodename One 5.0 This isn’t directly related to that but with this overhaul the decision is even more important. We decided to bump Codename One 5.0 to September 2018 instead of the current July release date.\nWe think features such as JDK 9/10/11 support is crucial with the new JDK release cycles. I’d also like Codename One to work with OpenJDK which is now a more stable target. Since these things require a lot of testing over time we think this new release date is crucial. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDiamond — June 28, 2018 at 6:51 am (permalink) Diamond says:\nI use https://www.livechatinc.com. You might also want to check them out and compare features and cost with crisp.\nShai Almog — June 29, 2018 at 6:20 am (permalink) Shai Almog says:\nI wasn’t familiar with them. Looking at this it seems they price per-agent which is slightly more expensive for our use case. The problem in this field seems to be the HUGE number of companies doing roughly the same thing. I don’t understand how Intercom can raise their prices 5x when they were already FAR more expensive with fewer features…\nFrancesco Galgani — July 23, 2018 at 5:19 pm (permalink) Francesco Galgani says:\nAbout the OpenJDK support you mentioned in this article, have you read this news on the Oracle web site?\nhttps://www.java.com/en/dow…\nI suppose that OpenJDK will be the best response.\nAnd now a difficult question, because there is few information: in the next years, do you think that the applications developed with Codename One will be able to run on Google Fuchsia, the replacement of Android?\nShai Almog — July 24, 2018 at 4:11 am (permalink) Shai Almog says:\nYes that really sucks. That’s why we consider the move to OpenJDK/JDK 11 as very high priority…\nFuchsia will never happen. There are millions of Android apps, hundreds of thousands adaptations and vendor customizations. Google knows it. Fuschia is a research project not an actual attempt to replace Android (despite some misleading nonsense from the tech press/PR).\nThe only thing of interest in Fuschia is the kernel, you can replace Androids kernel and keep 90% of the compatibility for apps and vendors. Mac OS did it when they migrated from Power PC to Intel. It makes the most sense.\nHaving said that, since we run on a lot of very different architectures if something that historically never happened would happen we could target that too.\nCaterina Bassano — July 24, 2018 at 11:12 am (permalink) Caterina Bassano says:\nInteresting! I am curious: what makes Intercom a bad product and what made you choose Crisp over others?\nShai Almog — July 25, 2018 at 4:27 am (permalink) Shai Almog says:\nLets start with a couple of things I liked in Intercom which are still unavailable in Crisp:\n– Threaded discussions are/were handled better\n– Analytics on email sending is better\nThe pricing difference is amazing, AFAIK no one is remotely close to Crisps \u0026ldquo;ultimate\u0026rdquo; tier in terms of pricing. I was referring to Intercoms pricing without all its packages to make it equivalent to Crisp which would have put the price difference at x20/x30…\nThe price made us move but after working with Crisp for a while now I think it’s also a technically superior product. This is mostly because these guys are a startup and they are \u0026ldquo;hungry\u0026rdquo; unlike Intercom which is so full of investor funding it can’t function. Crisp listens to users whereas Intercom doesn’t really care unless you pay 5-6 figures. We paid mid 4 figures (annually) and they didn’t care to implement anything we asked for. They changed pricing to existing customers with 1 month of notice… Who does that?\nHere are the features that Crisp does way better:\n– User account – their insight into users is much easier to read with color coded events placed in a sensible location. It’s far more readable, I can now look at a specific user and understand what’s going on where in Intercom this was a mess.\n– Mobile – Intercom was unusable on mobile. There was no way to disable it there. Crisp can be disabled on mobile but is usable there to begin with. It doesn’t annoy. People would complain about our site a lot mostly because of Intercom.\n– Gifs – Intercom added the most annoying feature in history: gif support. Users started sending us animated gifs. That’s stupid and redundant. We aren’t targeting children… Our chat is there to help not entertain. Crisp has a \u0026ldquo;while you wait play a game\u0026rdquo; feature, but it can be turned off. They let us adapt the way the widget looks/behaves to the type of business we have. BTW I commented about the gif issue in their public blog post and a lot of users chimed in complaining about it. Intercoms solution was swift and simple: they disabled commenting on future blog posts…\n– I love their visitor view, it has given me a level of insight into our site visitors that neither Google Analytics or Intercom have given. It might be because we integrated Google Analytics badly though.\n– The tools are very hacker friendly, markup and REST API’s. Developers are responsive and proactive in their attitude.\nThe way I see it, Crisp is moving to answer customer needs. Intercom is moving to increase monetization. I don’t think anyone should use Intercom regardless of the price. It’s a company culture issue that’s probably unfixable.\nShai Almog — July 25, 2018 at 5:47 am (permalink) Shai Almog says:\nI forgot to mention one HUGE conceptual problem with Intercom… They separate leads from users and charge the same for both.\nA lead is a person who visited the site but you don’t know who he is. A user is a logged in user. If a lead enters his email address into intercom he’s still a separate lead and isn’t merged with his user account. Supposedly for security so a person can’t impersonate a user… The reality is that you end up with multiple redundant accounts and some of your user support goes into the lead while other goes into the user. That means conversations are lost and invisible. The only real purpose of this is to overcharge on leads, we literally took time every month to delete leads to keep our price manageable as leads are redundant… But we also deleted user data as a result.\nOne Intercom user who was communicating with us was complaining about something. When our agent tried to understand what he was complaining about he asked her to look in his chat history. But it was hidden in a lead and was impossible to find in intercoms UI. He didn’t believe our agent who said she can’t see the history he was talking about…\nAgain, this boils down to a company that over monetizes its users.\nFrancesco Galgani — August 22, 2018 at 4:05 pm (permalink) Francesco Galgani says:\nI have no experience of Crisp or other similar services. If you think that Crisp is a good service, my question is if it can be integrated in a Codename One app. I’m developing a complex app: it could be useful is there is something ready to be used to get feedbacks and support requests from users.\nShai Almog — August 22, 2018 at 4:21 pm (permalink) Shai Almog says:\nI agree. We plan to integrate crisp as a cn1lib. This should be trivial to accomplish but I don’t have an ETA for it right now. It’s very much on our \u0026ldquo;TODO\u0026rdquo; list.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/moving-away-from-intercom/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/moving-away-from-intercom/looking-forward.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA few years ago a consultant convinced us to integrate Intercom into our website. In retrospect this was a mistake which I’ll discuss in more depth below. We are migrating away from Intercom right now…​ That means that if you have an email address or ongoing chat history with us in Intercom it might get lost!\u003cbr\u003e\nWorse. If you unsubscribe this might also get lost due to the migration process (sorry about that!). We’re moving to a new far better system (\u003ca href=\"https://crisp.chat/en/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ecrisp\u003c/a\u003e).\u003c/p\u003e","title":"Moving Away from Intercom"},{"content":"\nLast week I pushed out an enhancement to ToastBar that changed the static showMessage methods. I made them return the Status object instead of void which would allow more control of the toast message after it’s shown. Unfortunately, I totally forgot that I can’t do that without breaking some binary compatibility.\nIn Java return types create a distinct method signature, so even though the language doesn’t allow you to do this:\nvoid myMethod() { } int myMethod() { return 1; } This is actually valid in the bytecode level. Furthermore, it’s a used by the JVM to implement Java language features like covariant return types.\nSo if you used ToastBar and compiled against older libraries you might experience issues when building. Make sure to update your client libraries before sending a build by going into Codename One Settings → Basic → Update Client Libs. Then do a clean/build before sending a new build.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/toastbar-return-value/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/toastbar-return-value/generic-java-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eLast week I pushed out an enhancement to \u003ccode\u003eToastBar\u003c/code\u003e that changed the static \u003ccode\u003eshowMessage\u003c/code\u003e methods. I made them return the \u003ccode\u003eStatus\u003c/code\u003e object instead of \u003ccode\u003evoid\u003c/code\u003e which would allow more control of the toast message after it’s shown. Unfortunately, I totally forgot that I can’t do that without breaking some binary compatibility.\u003c/p\u003e\n\u003cp\u003eIn Java return types create a distinct method signature, so even though the language doesn’t allow you to do this:\u003c/p\u003e","title":"ToastBar Return Value"},{"content":"\nI’ve been so busy with the book I completely missed a lot of things I should have blogged about and one such thing is the NativeLogsReader cn1lib which has been in the extension manager for a while now.\nThe NativeLogsReader cn1lib was created by Francesco Galgani to include native logging into the Codename One log. A lot of times we get on device failures that are really hard to track. In those cases we ask users to connect cables and try to view the native logs to search for clues. With this library you can see native output even without physical access to the device!\nThat’s really helpful when you’re tracking an issue that happens on an end user device.\nCertificate Wizard Issues We’ve had several cases of downtime with the certificate wizard lately and we are going through such a downtime right now. We are working on fixing it and hopefully it will be fixed by the time you read this…​\nHowever, I’d like to explain why these things happen. The certificate wizard connects to Apples undocumented system to support generating certificates/provisioning. It’s a system they have in place for xcode but it’s a bit flaky. We could just use something like webscraping in the worst case scenario but either way every time Apple makes a change we need to adapt.\nA while back Apple made a change, we adapted relatively quickly but introduced a few regressions which were really hard to pinpoint as they relate to behaviors such as cookie policies etc. Things that work for our localized test cases sometimes fail as we scale them to the entire community…​\nHopefully, this round of whack-a-mole will be over soon.\nBook Update and 5.0 As usual producing the book is taking way longer than planned but I’m getting there. I’m really excited about what we have so far and can’t wait to share it with you guys.\nOn a related subject we also need to update Codename One to run on newer JDK’s 9/10/11 all of which broke so many documented features in the JDK that we depend on. This is crucial as JDK 8 will EoL in 2019.\nWith those two things in mind we decided to postpone Codename One 5.0 to September instead of its current July target. This will give us time to address these issues and give me a bit of time to do some \u0026ldquo;actual work\u0026rdquo; that doesn’t revolve around the book. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChris — June 20, 2018 at 4:43 am (permalink) Chris says:\nNativeLogsReader works for debug builds or only for App Store Builds? Please advise.\nDo we have to add the following statement in every form as we don’t where the App will Crash or have some issue\nString logs = NativeLogs.getNativeLogs();\nFrancesco Galgani — June 20, 2018 at 2:13 pm (permalink) Francesco Galgani says:\nIt works for every app (it it’s a debug build or an app store build doesn’t matter).\nFor example, if all the Forms of your app are subclasses of a custom base Form, you can add a side menu command in your custom base Form to read and/or send by email the native log. In this way, you can add this functionality to all the Forms, coding it only one time.\nYaakov Gesher — June 23, 2018 at 10:10 pm (permalink) Yaakov Gesher says:\nJust add that code in the EDT error handler, and the network event handler, and anywhere you’re working off the EDT and might run into a problem.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/native-logging-certificate-wizard/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/native-logging-certificate-wizard/ios-cert-wizard-blog-post-header.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been so busy with the book I completely missed a lot of things I should have blogged about and one such thing is the \u003ca href=\"https://github.com/jsfan3/CN1Libs-NativeLogsReader\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eNativeLogsReader cn1lib\u003c/a\u003e which has been in the extension manager for a while now.\u003c/p\u003e\n\u003cp\u003eThe \u003ca href=\"https://github.com/jsfan3/CN1Libs-NativeLogsReader\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eNativeLogsReader cn1lib\u003c/a\u003e was created by \u003ca href=\"https://github.com/jsfan3\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFrancesco Galgani\u003c/a\u003e to include native logging into the Codename One log. A lot of times we get on device failures that are really hard to track. In those cases we ask users to connect cables and try to view the native logs to search for clues. With this library you can see native output even without physical access to the device!\u003c/p\u003e","title":"Native Logging and Certificate Wizard Downtime"},{"content":"\nI’ve been working on a book form of the Uber Clone module in the course. I finished the principal writing quite a while back but unlike the course a book requires more back and forth. I’ve already gone through the first review cycle and it has made the book much better as a result. There is still a lot to do as I would like the result to be sublime.\nAs part of that process I’ll publish the first few chapters of the book here which I hope would be helpful and provide feedback from you guys…​\nThe first couple of chapters are an introduction to Codename One and I think they are far better written than anything we have out there right now.\nPeople who purchased the full online course will get free access to the book within a couple of months after publication (once exclusivity expires). At that time I will embed the book into the course with the other materials.\nWhile the writing itself is quite easy the production aspect is a pain in the neck. Hopefully this book will succeed and if it does I’ll keep doing additional ones which should be easier now that I have the process mostly ironed out. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — June 16, 2018 at 6:10 am (permalink) Francesco Galgani says:\nThank you very much Shai 😉\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/uber-clone-book/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/uber-clone-book/build-real-world-full-stack-mobile-apps-in-java.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been working on a book form of the Uber Clone module in the course. I finished the principal writing quite a while back but unlike the course a book requires more back and forth. I’ve already gone through the first review cycle and it has made the book much better as a result. There is still a lot to do as I would like the result to be sublime.\u003c/p\u003e","title":"Uber Clone Book"},{"content":"\nAs I mentioned the other day, we have a lot of new features and announcements. Today I’d like to discuss the upcoming right side menu bar and new tab order functionality.\nRight SideMenu The old SideMenuBar supported the placement of the menu anywhere we want. We could place it in the left/right/top or bottom. The problem was that this support was painfully unreliable and inconsistent.\nWhen we migrated to the Toolbar API we ignored that support and only included the left side menu support. For some of us this isn’t a big deal. Just a small limitation. However, if your app is localized to an RTL language this might be a problem.\nWhat’s RTL\nRTL stands for Right to Left to indicate languages written in the opposite direction to most western languages. Typically these are old languages specifically:\nArabic\nAramaic\nAzeri\nDhivehi/Maldivian\nHebrew\nKurdish (Sorani)\nPersian/Farsi\nUrdu\nHistorically, these languages date to a time when writing was engraved with a hammer and a chisel. It was easier to hold the hammer in the right hand (the more dominant hand for 90% of the population) and thus write from the right side.\nAs ink and paper took over languages that didn’t have a writing system before picked a direction that wouldn’t smear the ink.\nThe problem of RTL languages is far more difficult as numbers or other languages are still written from left to right. This is called: bidi (bi-directional). That means a sentence starts from the right, skips to the left to show a number then goes back.\nBecause RTL languages are read from the right side users expect the entire UI to be reversed. That means all UI elements should be aligned to the right and all components should be in the exact flipped order. This is done automatically in Codename One see the i18n tutorial.\nUp until now we couldn’t do this for the side menu but now that Francesco Galgani introduced support for right side menu in his PR and followup PR this is finally possible!\nWith next weeks update you could invoke a version of the add to side menu method that lets you add an element to the right side.\nInput Cycle Codename One has its roots well before the move to touch devices. In the old devices one would navigate with 4 direction buttons and our entire focus system revolves around that. This is a powerful system as it lets us work with unique input devices such as TV’s etc.\nHowever, it has some limitations specifically with the virtual keyboard cycle. When we edit a field and press NEXT we would expect the keyboard to move to the next text field. That’s easy. But what if the next field is a Picker?\nNow you can override this behavior so the next element will work correctly, we were also able to simplify this similarly to the way that tabIndex works in HTML as this system doesn’t need the full functionality of the original focus code.\nTab Index Component now has a preferredTabIndex property which specifies the tab order of a component. There are 3 types of values that you can set here.\nA value of -1 means that the component is not tab-focusable (i.e. you will never get to this field by tabbing or hitting Next/Prev in the keyboard). This is the default value for all components except TextArea, and Picker – which are currently the only components that are tabbable.\nA value of 0 means that the component is tab-focusable, and the order will be dictated by the logical document order. (The logical document order is defined in the layout managers).\nA value greater than 0 explicitly sets the tab order. Be careful with this as if you mix explicitly set tab orders (i.e. tabIndex \u0026gt; 0) with implicitly set tab orders (i.e. tabIndex == 0) in the same form, you may get unexpected results.\nIf you want to query the form for tab order, you can use any of the new methods on Form.\nFinding Next/Prev Components. Form.getNextComponent(Component current), which gets the next component by tab order given some currently focused component.\nForm.getPreviousComponent(Component current), which gets the previous component.\nForm.getTabIterator(Component current), which gets an iterator that allows you to iterate through all of the tabbable components in the form in their tab order, starting at some currently focused component.\nMaking a Component Tab-Focusable If you are designing a new component that should be tab-focusable, you should just set the preferredTabIndex to 0.\ncmp.setPreferredTabIndex(0);\nIf you want to make the component so it won’t be tab-focusable, just do\ncmp.setPreferredTabIndex(-1);\nThere is also a convenience method setTraversable(boolean) which wraps these calls to make them more intuitive. E.g.:\ncmp.setTraversable(true) is the same as calling cmp.setPreferredTabIndex(0), and cmp.setTraversable(false) is the same as calling cmp.setPreferredTabIndex(-1).\nDefault Tab Orders\nIt is recommended that you just stick with preferredTabIndex=0 if you want your component to be tabbable, because it’s a lot of work to explicitly declare tab order for all of your fields. Then the tab order will be automatically calculated based on the logical order of the fields on the form. This default ordering is dictated by the layout manager. For indexed layout managers (e.g. BoxLayout.Y, BoxLayout.X, GridLayout, FlowLayout), the tab order is simply the component order in the container. Constraint-based layout managers like BorderLayout and TableLayout define their own orders that make logical sense. LayeredLayout defines an order based on the x,y coordinates of its children, roughly moving top-left to bottom-right.\nIf you are developing your own layout manager and want a default tab order that is different than just the component order within the container, you should override the following methods:\noverridesTabIndices(Container) – Return true to indicate that the layout manager provides its own traversal order.\ngetChildrenInTraversalOrder(Container parent) – return array of Components in the parent in the order that they should be traversed. This returned array doesn’t need to include all of the child components, only the ones that should be considered in traversal – but it may also include components that shouldn’t be included in traversal, as the ineligible components will be filtered out at a later step. In fact some of the elements of this array may be null, and those will be filtered out.\nSee BorderLayout for an example or TableLayout for another example.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/right-sidemenu-tab-order/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/right-sidemenu-tab-order/new-features-4.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAs I mentioned the other day, we have a lot of new features and announcements. Today I’d like to discuss the upcoming right side menu bar and new tab order functionality.\u003c/p\u003e\n\u003ch3 id=\"right-sidemenu\"\u003eRight SideMenu\u003c/h3\u003e\n\u003cp\u003eThe old \u003ccode\u003eSideMenuBar\u003c/code\u003e supported the placement of the menu anywhere we want. We could place it in the left/right/top or bottom. The problem was that this support was painfully unreliable and inconsistent.\u003c/p\u003e\n\u003cp\u003eWhen we migrated to the \u003ccode\u003eToolbar\u003c/code\u003e API we ignored that support and only included the left side menu support. For some of us this isn’t a big deal. Just a small limitation. However, if your app is localized to an RTL language this might be a problem.\u003c/p\u003e","title":"Right SideMenu and Tab Order"},{"content":"\nI have a lot to write about so today I’ll only focus on two of the several PR’s we handled over the last month. I’ll try to cover more over the rest of the week. Also as a friendly reminder we will migrate to API level 27 this Friday and the price of the online course including the Facebook/Uber clone apps will go up next week…​\nIf you didn’t sign up yet this is your chance.\nSet Properties ramsestom contributed a pull request which filled in a gap in the properties API: SetProperty. I don’t use Set very often as List is typically more convenient so it’s something that I just didn’t notice.\nYou can now declare SetProperty as you would a declare a ListProperty e.g.:\npublic final SetProperty\u0026lt;User, User\u0026gt; peopleYouMayKnow = new SetProperty\u0026lt;\u0026gt;(\u0026quot;peopleYouMayKnow\u0026quot;, User.class); The nice thing about this PR is that it also refactored the code in a sensible way so SetProperty \u0026amp; ListProperty have a common base class CollectionProperty so there isn’t too much code duplication.\nDensity PR ramsestom also made a more challenging change to the way densities are managed. When we originally integrated this it caused a performance regression on Android which demonstrates just how hard it is to work with such huge PR’s.\nThis PR is still conflicting and I don’t have the time to go over some of the nuances that should be fixed there. It’s not something I want to merge at the last minute either as it’s a huge change. Ideally if this could be broken down to smaller PR’s we can adopt individually it would be far easier to merge again.\nOne crucial thing to keep in mind when you submit a PR is binary compatibility. Method signatures must match completely or things will fail badly for some users. This is also true when introducing new API’s, once we accept a PR we need to maintain it for years to come.\nShort Material Icon Syntax One of the tricks I’ve been using recently is:\nimport static com.codename1.ui.FontImage.*; This lets me do things like:\nsetMaterialIcon(send, MATERIAL_SEND); That’s short and to the point. But why require a static import?\nSo I’ve added this method to Label (which is the base class of Button etc.):\nsend.setMaterialIcon(FontImage.MATERIAL_SEND); That might not seem very different but it carries one big nuance that will appear in the update this Friday. When you make changes to the theme they will be reflected in the material icon.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/set-properties-density-pr-short-material-icon/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/set-properties-density-pr-short-material-icon/new-features-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI have a lot to write about so today I’ll only focus on two of the several PR’s we handled over the last month. I’ll try to cover more over the rest of the week. Also as a friendly reminder we will migrate to API level 27 this Friday and the price of the \u003ca href=\"https://codenameone.teachable.com/p/build-real-world-full-stack-mobile-apps-in-java\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eonline course including the Facebook/Uber clone apps\u003c/a\u003e will go up next week…​\u003cbr\u003e\nIf you didn’t sign up yet this is your chance.\u003c/p\u003e","title":"Set Properties, Density PR and Short Material Icon Syntax"},{"content":"\nThis is important: We’ll update the build tools \u0026amp; build target to API level 27 with next weeks update (June 8th). We HIGHLY recommend you check your app before we flip the switch!\nI also just uploaded the final lesson in the Facebook Clone App which is now fully live in the online course.\nI’ve discussed the build target 27 migration before. We wanted to do it in May but the work on the Facebook clone pushed that back so it will have to wait. You can test this right now by setting the build hints:\nandroid.buildToolsVersion=27 android.targetSDKVersion=27 If you would like to go back to the previous level after the change you can set them to 23 although I’d strongly recommend against that. Google will require at least 26 starting in August and is already producing warnings if you try to submit updates to apps right now.\nI answered a lot of FAQ’s about this the last time I wrote about this.\nFacebook Clone is GA I was racing against the clock to get the Facebook clone out of the door and made it just now. In the past 48 hours I recorded the last 20+ lessons to finish the 46 lesson long module. I have a lot of thoughts about the results and insights about Facebook after doing this…​\nI’ll try to write an article similar to the one I wrote about Uber detailing some of my experiences here.\nI mentioned before when we launched the Uber app that the price of the course will go up by 100USD to $599 once the Facebook clone is up. Since it was late we’ll postpone this price change to June 12th so if you still didn’t signup for the course nows a good time.\nWe’ll raise the price further in the future as we add things to the courses but probably not by the same amount.\nI’ll send out a couple of reminders for this by email during the week.\nWe Updated our Privacy Policy Sorry about that. I know it’s a pain I think we all get enough emails without that one…​\nI’m personally a big fan of the ideas behind GDPR \u0026amp; I think it will ultimately help in refining better business models that don’t rely on spyware tactics. For the record, we never tracked anything or used personal data in any way. It’s not a part of our business model.\nWe use a couple of 3rd party GDPR compliant services (Intercom \u0026amp; Google Analytics), that’s pretty much it.\nAnyway it’s a minimal privacy policy because we respect your privacy and don’t need to look at details. If you think we need to explicitly state something there that isn’t mentioned let us know.\nThere is a lot of additional news I’d like to cover but I’ll try to get to those next week.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/moving-to-27-facebook-clone-done/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/moving-to-27-facebook-clone-done/android_studio.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is important: We’ll update the build tools \u0026amp; build target to API level 27 with next weeks update (June 8th). We HIGHLY recommend you check your app before we flip the switch!\u003cbr\u003e\nI also just uploaded the final lesson in the Facebook Clone App which is now fully live in the \u003ca href=\"https://codenameone.teachable.com/p/build-real-world-full-stack-mobile-apps-in-java\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eonline course\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eI’ve discussed the \u003ca href=\"/blog/android-build-target-27-migration.html\"\u003ebuild target 27 migration before\u003c/a\u003e. We wanted to do it in May but the work on the Facebook clone pushed that back so it will have to wait. You can test this right now by setting the build hints:\u003c/p\u003e","title":"Moving to API Level 27 and Facebook Clone is DONE!"},{"content":"\nOne of the worst components in Codename One is the picker component. It’s origin lies in the migration to iOS 7 where the native picker introduced a 3d effect that was hard to replicate with our old graphics layer. We had no choice. We used a native widget for that picker and regretted that decision ever since.\nIt looks bad on the simulator, it misbehaves and with every update from Apple things break. This has again proven to us the importance of the lightweight architecture of Codename One!\nSince the introduction of the picker our graphics layer was heavily revised enough to support something as elaborate as the iOS picker UI. With that Steve spent a lot of time doing a from scratch implementation of the iOS picker UI which you can try right now.\nFigure 1. New Picker on the Simulator\nThe new implementation is on right now!\nIf the platform supports native pickers it will use the native picker UI. If it doesn’t it will default to the lightweight UI.\nYou can force the lightweight mode by invoking: picker.setLightweightMode(true);.\nSince picker is native by default the UI changes in iOS/Android where we get the native Android picker interface. Right now we only replicated the iOS UI, ideally we’d do the same for the Android picker although the urgency is much lower as it’s surprisingly more robust than the iOS picker API.\nAs part of this implementation Steve introduced some API’s such as a scene-graph API which is currently marked as deprecated as it’s still under development. If there is some interest in it we might explore some of those capabilities in the future.\nDevice Detection On a different note…​ We hid most of the device detection functionality in Codename One to prevent the situation where developers write code such as:\nif(deviceX) { } else if(device Y) { } //.... This starts as a quick bandaid to a problem \u0026amp; snowballs into something that’s unmaintainable.\nHaving said that there are some valid use cases for device detection such as statistics \u0026amp; analysis. There are some edge cases that can only be solved in this way e.g. on iOS it’s often impossible to calculate the accurate device DPI without detection code.\nWith that in mind Diamond introduced this cn1lib which is available in the extension manager. It includes native device detection code that would you to detect the device. Hopefully this will be used for good.\nFacebook Clone Update I’m past the 50% of the content mark (roughly at 65-70% by my estimate) but that doesn’t leave me that much time. Currently I have 25 lessons nearly ready and 17 out of them are already published. I estimate this will take another 25 lessons to complete since I still have a lot of material that’s prepared but not segmented. For comparison the Uber clone module took 40 lessons to complete.\nTo be fair, these lessons are shorter as I get to the point faster and I improved the material presentation significantly. Either way I’ll need to pick up the pace if I hope to release this module before the end of the month. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nStefan Eder — May 23, 2018 at 10:27 am (permalink) Would it be possible now to have a UI like in the IOS calendar app where the pickers slide in between the other controls – thus not open a dialog to choose but stay on the same form?\nStefan Eder — May 23, 2018 at 11:13 am (permalink) Stefan Eder says:\nApparently even if the locale is german and the date is displayed in the german format befor editing – in the picker UI in the simulator the date format is the US date format and the buttons are english.\nShai Almog — May 24, 2018 at 4:05 am (permalink) Shai Almog says:\nCan you please file an issue on this?\nSince this is a lightweight component we’ll localize it with the rest of the localization logic. All of this should be declared in the javadoc to the class to make it easier to do.\nIt should be possible to embed this but right now it’s not a priority so we hid/deprecated those internal API’s as they are still not mature enough for use. Notice that there are small nuances with embedding e.g. if you have a text field followed by a picker you’d expect the \u0026ldquo;next\u0026rdquo; cycle to include the picker (that currently doesn’t work in the picker) but it would be hard to do with embedding.\nFrancesco Galgani — May 25, 2018 at 3:36 pm (permalink) Francesco Galgani says:\nThe Diamond’s CN1Lib to detect the device works perfectly! Thanks! 😀\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/lightweight-picker-device-detection/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/lightweight-picker-device-detection/pixel-perfect.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the worst components in Codename One is the picker component. It’s origin lies in the migration to iOS 7 where the native picker introduced a 3d effect that was hard to replicate with our old graphics layer. We had no choice. We used a native widget for that picker and regretted that decision ever since.\u003c/p\u003e\n\u003cp\u003eIt looks bad on the simulator, it misbehaves and with every update from Apple things break. This has again proven to us the importance of the lightweight architecture of Codename One!\u003c/p\u003e","title":"Lightweight Picker, Device Detection and More"},{"content":"\nUp until last Friday CSS support has been a second class citizen, with the release of Codename One 4.2 we’re making CSS a core feature. We also improved the builtin CSS support extensively!\nChanges you make to a CSS file will instantly reflect in the simulator. You don’t need to compile or do anything special. When you launch the simulator we open a CSS watcher thread that automatically recompiles \u0026amp; deploys the CSS whenever you save.\nInstallation is also much simpler. You can click the CSS entry in Codename One Settings \u0026amp; activate CSS. That’s it!\n__ Migration doesn’t migrate your theme! You would need to redo the theme in CSS __ Disabling CSS after enabling it might have some issues, if you experience that remove the entry codename1.cssTheme from codenameone_settings.properties If you have a project that uses the older CSS support the settings app is smart enough to recognize that and offer to migrate to the new CSS support.\nFigure 1. The CSS Option in Codename One Settings\n__ These changes might need an update to the build.xml file. Make sure to update it when you save the file Other Improvements in CSS Other than these great new features CSS has improved by leaps and bounds. One of the biggest benefits of the new CSS processing logic is speed. It’s much faster. The trick behind that is simplification of the process for resource file generation.\nThe CSS plugin occasionally uses the webkit browser from JavaFX to generate an image of the CSS style. E.g. if a complex gradient is used the CSS processor just fires up webkit and grabs a multi-image screenshot of this style.\nThis is powerful as it allows for complex CSS styling, but it has many pitfalls such as slower compilation, lower fidelity \u0026amp; larger resources.\nThe newer CSS version works with some of our new border types such as round border. But the bigger improvement is that it doesn’t launch the browser window unless you actually need it. This results in faster compilation times for the CSS.\nWhat’s Still Missing The biggest piece we need to do is migrate the documentation to the developer guide and update this everywhere.\nAnother big missing piece with CSS support is localization. It’s not a CSS feature but rather something we would expect to have within the generated resource file. So java properties files would be implicitly added to the resource file during CSS compile. Personally I think we can make localization much easier by detecting unlocalized strings in the simulator \u0026amp; automatically adding them to the resource bundle.\nWe need some more demos \u0026amp; tutorials that cover CSS and ideally we would want this exposed in the \u0026ldquo;new project wizard\u0026rdquo;.\nIf we could automate the conversion of res files to CSS it would be great for things like this as we could instantly make all of our demos work both ways.\nThe Big Picture The obvious question here is: are we replacing the designer tool with CSS?\nNot yet.\nThough this is something I’m personally conflicted with. The designer tool is showing its age so it makes sense to minimize its usage. I don’t think we’ll deprecate the designer soon as it’s still convenient to work with.\nPersonally I find the designer more convenient probably due to habit. However, CSS has a few big advantages, for me personally the biggest advantages is documentation. I did the Uber clone app using the designer tool and while that was pretty easy to implement, the tutorial became untenable…​\nI had to grab screenshots of every UI setting and if I wanted to revise something later I had to redo the screenshots. This was sometimes complicated as it required reverting existing changes to make the shots real. Since CSS is based on code it’s far easier to walk through the CSS changes I made like I would do with any other block of source code. That’s why the Facebook Clone uses CSS and it’s indeed far more convenient in that sense. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — May 15, 2018 at 2:56 pm (permalink) Thank you very much 🙂\n«If we could automate the conversion of res files to CSS it would be great for things like this […]». This should be great!\nDurank — May 17, 2018 at 8:55 pm (permalink) Durank says:\nI think so that codename one must create a migration css res to new css\nFrancesco Galgani — June 10, 2018 at 9:17 pm (permalink) Francesco Galgani says:\nIs this the only available documentation at the moment? https://github.com/shannah/…\nIs it complete about \u0026ldquo;Fonts\u0026rdquo;, \u0026ldquo;Images\u0026rdquo;, \u0026ldquo;Supported CSS Selectors\u0026rdquo;, \u0026ldquo;Supported Properties\u0026rdquo;?\nShai Almog — June 11, 2018 at 5:03 am (permalink) Shai Almog says:\nThe wiki there goes pretty deep but I agree we need to update that. When we go to the 5.0 code freeze we’ll try to pull these docs into the developer guide so we have a better/unified reference for this.\nDenis — August 1, 2018 at 6:24 am (permalink) Denis says:\nHi Shai,\nI can’t enable CSS in Codename One Properries (version 4.31), it says \u0026ldquo;failed to activate CSS plugin due to IO error. See the console log for details\u0026rdquo;, but console log is empty, and I even don’t know where to start troubleshooting this, can you please advise ?\nThanks,\nDenis\nShai Almog — August 2, 2018 at 5:54 am (permalink) Shai Almog says:\nHi,\nconsole might be confusing. It means the console where the settings app is running. To check the output go to your home directory then enter the \u0026ldquo;.codenameone\u0026rdquo; directory. In it execute \u0026ldquo;java -jar guibuilder_1.jar -settings path-to-project/codenameone_settings.proper…\u0026rdquo;.\nThis should launch settings. Reproduce the issue and see the logs in that console. Make sure you are running under Oracle JDK 8 when doing that.\nDenis — August 2, 2018 at 6:25 am (permalink) Denis says:\nHi,\nthere is no guibuilder_1.jar, but there is guibuilder.jar, launched as you advised and got following error while trying to enable CSS:\n[EDT] 0:0:0,1 – Codename One revisions: ab02d7476d1486e3babf14a0b26a5a5205672439\n[EDT] 0:0:0,2 – Exception: java.io.IOException – CSS Activation failed. build.xml file is missing the -pre-compile target which is where CSS compilation needs to be inserted.\njava.io.IOException: CSS Activation failed. build.xml file is missing the -pre-compile target which is where CSS compilation needs to be inserted.\nat com.codename1.apps.config.Settings.activateCSS(Settings.java:2468)\nat com.codename1.apps.config.Settings.lambda$createCSSSettings$105(Settings.java:2705)\nat com.codename1.ui.util.EventDispatcher.fireActionEvent(EventDispatcher.java:349)\nat com.codename1.ui.Button.fireActionEvent(Button.java:570)\nat com.codename1.ui.Button.released(Button.java:604)\nat com.codename1.ui.Button.pointerReleased(Button.java:708)\nat com.codename1.ui.Form.pointerReleased(Form.java:3259)\nat com.codename1.ui.Component.pointerReleased(Component.java:4288)\nat com.codename1.ui.Display.handleEvent(Display.java:2061)\nat com.codename1.ui.Display.edtLoopImpl(Display.java:1043)\nat com.codename1.ui.Display.mainEDTLoop(Display.java:961)\nat [com.codename1.ui.RunnableWr…](http://com.codename1.ui.RunnableWrapper.run)([RunnableWrapper.java](http://RunnableWrapper.java):120)\nat [com.codename1.impl.Codename…](http://com.codename1.impl.CodenameOneThread.run)([CodenameOneThread.java](http://CodenameOneThread.java):176)\nThere is indeed nothing about \u0026ldquo;pre-compile\u0026rdquo; in build.xml in projects directory, how to fix that ? is it some build-hint that I need to add to project ?\nthanks !\nDenis\nShai Almog — August 2, 2018 at 6:35 am (permalink) Shai Almog says:\nHi,\nwhen you press save in Codename One Settings it should offer to update the build.xml file for you.\nDenis — August 2, 2018 at 6:50 am (permalink) Denis says:\nit’s doesn’t, can I do that manually ?\nShai Almog — August 2, 2018 at 12:29 pm (permalink) Shai Almog says:\nMaybe try flipping a switch back and forth in basic then press the save button on the top right. It should make that offer.\nDenis — August 2, 2018 at 12:52 pm (permalink) Denis says:\nI don’t really see any switch there, I have changed version number in Basics and then pressed Save button, as I usually do before uploading to Google Play (alpha test), but that doesn’t helped\nhttps://uploads.disquscdn.c…\nShai Almog — August 2, 2018 at 6:35 pm (permalink) Shai Almog says:\nIt should work. I’m not sure what is causing it not to push the XML update. We’ll try to push out a fix to the CSS switch process for tomorrow that would hopefully workaround this issue.\nDenis — August 3, 2018 at 5:53 am (permalink) Denis says:\nthanks Shai, just for test I have created new codenameone project using \u0026ldquo;Hello World Vusial\u0026rdquo; template and \u0026ldquo;business\u0026rdquo; theme and tried to enable CSS for it, faced the same issue, I was worried if it’s problem particularly with my project, but looks like it’s general\nShai Almog — August 3, 2018 at 1:14 pm (permalink) Shai Almog says:\nDon’t use the visual template, it’s designed for the old GUI builder. That might be related to the problem you are experiencing.\nDenis — August 3, 2018 at 2:15 pm (permalink) Denis says:\nI see no way to bypass template while creating new project, please see the screenshot\nhttps://uploads.disquscdn.c…\nMy app has dynamically built UI (it’s a casual game), so it doesn’t require any template at all and I can move entire code to new project easily, if this will solve the issue …\nShai Almog — August 4, 2018 at 8:48 am (permalink) Shai Almog says:\nThat isn’t the visual template. It’s fine but I would suggest using native as the theme and bare bones as the template.\nIs this resolved after the update to 4.33? You can update via Basic -\u0026gt; Update Project Libs.\nNotice there is no newer version of the plugin. Only settings are updated.\nDenis — August 4, 2018 at 12:36 pm (permalink) Denis says:\njust tried to update Project Libs, I was not aware that they weren’t updated during plugin update, but it stuck on following error:\nException in thread \u0026ldquo;main\u0026rdquo; java.io.FileNotFoundException: C:UsersDenis.codenameoneCodenameOne_SRC.zip\nat com.codename1.apps.updater.UpdateCodenameOne.runUpdate(UpdateCodenameOne.java:228)\nat com.codename1.apps.updater.UpdateCodenameOne.main(UpdateCodenameOne.java:310)\nthere is indeed no such zip file, but there is .jar instead CodenameOne_SRC.jar\nmay be it makes sense to do a clean installation of CodenameOne ?\nI see .codenameone, .cn1Settings and .cn1 under my user folder, is there any others ?\np.s. CSS still doesn’t work, I have just checked\nShai Almog — August 5, 2018 at 4:53 am (permalink) Shai Almog says:\nOdd, it shouldn’t fail on that. It might be an eclipse specific issue. Please file an issue on that and we’ll have a look: http://github.com/codenameo…\nDenis — August 5, 2018 at 9:35 pm (permalink) Denis says:\nI have already reinstalled Eclipse (Photon) and CodenameOne (4.3), also created new project using Native theme and Bare bones template, and looks like update went good, please take a look at screenshot\nhttps://uploads.disquscdn.c…\nThe only thing that looks strange for me is that there is still this hour like icon that appeared after start of update\nhttps://uploads.disquscdn.c…\nBut unfortunately this doesn’t helped with CSS, looks like the same issue (save button also doesn’t offer to update build.xml):\n[EDT] 0:0:0,0 – Codename One revisions: a9dfcb988f51cab1b4ccc43190b9ad9034474b18\n[EDT] 0:0:0,1 – Exception: java.io.IOException – CSS Activation failed. build.xml file is missing the -pre-compile target which is where CSS compilation needs to be inserted.\njava.io.IOException: CSS Activation failed. build.xml file is missing the -pre-compile target which is where CSS compilation needs to be inserted.\nat com.codename1.apps.config.Settings.activateCSS(Settings.java:2487)\nat com.codename1.apps.config.Settings.activateCSS(Settings.java:2484)\nat com.codename1.apps.config.Settings.lambda$createCSSSettings$106(Settings.java:2729)\nat com.codename1.ui.util.EventDispatcher.fireActionEvent(EventDispatcher.java:349)\nat com.codename1.ui.Button.fireActionEvent(Button.java:570)\nat com.codename1.ui.Button.released(Button.java:604)\nat com.codename1.ui.Button.pointerReleased(Button.java:708)\nat com.codename1.ui.Form.pointerReleased(Form.java:3259)\nat com.codename1.ui.Component.pointerReleased(Component.java:4288)\nat com.codename1.ui.Display.handleEvent(Display.java:2065)\nat com.codename1.ui.Display.edtLoopImpl(Display.java:1043)\nat com.codename1.ui.Display.mainEDTLoop(Display.java:961)\nat [com.codename1.ui.RunnableWr…](http://com.codename1.ui.RunnableWrapper.run)([RunnableWrapper.java](http://RunnableWrapper.java):120)\nat [com.codename1.impl.Codename…](http://com.codename1.impl.CodenameOneThread.run)([CodenameOneThread.java](http://CodenameOneThread.java):176)\nShai Almog — August 6, 2018 at 4:16 am (permalink) Shai Almog says:\nIt’s probably a bug in the Eclipse support, we’ll need to look into it so I suggest filing an issue. That hour icon is just a shortcut to the update button in the basic section. We should probably label them…\nDenis — August 6, 2018 at 12:50 pm (permalink) Denis says:\ndone.\nhttps://github.com/codename…\nDenis — August 6, 2018 at 8:16 pm (permalink) Denis says:\nShai,\nCan you please help me with following, there is includeNativeBool theme constant in newly created project, and l like what it does, slider and dialogs looks much better, but looks like it now ignores globalToobarBool and hideLeftSideMenuBool, because now app is not in fullscreen mode\nif I disable or remove includeNativeBool constant app becomes fullscreen again (there are also codename1.arg.android.statusbar_hidden=true and codename1.arg.ios.statusbar_hidden=true build hints)\nSo my question is, is it possible to keep includeNativeBool enabled and at the same time make app fullscreen ?\nthanks,\nDenis\np.s. I also noticed that some UTF symbols are not displaying while includeNativeBool is enabled, for example \u0026ldquo;→\u0026rdquo; symbol, looks like there is a different font ?\nShai Almog — August 7, 2018 at 5:54 am (permalink) Shai Almog says:\nYour main class defines global toolbar explicitly. I would suggest leaving that.\nIf you want to show a full screen form override the method:\nprotected boolean shouldPaintStatusBar() {\nreturn false;\n}\nDon’t set a title to the form (or set it to \u0026ldquo;\u0026rdquo;) and don’t add commands.\nDenis — August 7, 2018 at 6:51 am (permalink) Denis says:\nthanks Shai, but this doesn’t worked, override shouldPaintStatusBar to return false, commented all form related commands, including setTitlle (also tried to set it to \u0026ldquo;\u0026rdquo;) toolbar is still there (in emulator, haven’t sent to real device yet), removed toolbar related theme constants and build hints, the same, any ideas ?)\nShai Almog — August 8, 2018 at 4:43 am (permalink) Shai Almog says:\nSorry I forgot to mention you also need to remove the padding from the Toolbar. It has some default padding that leaves it visible you can do that with this simple trick as Container has no padding/margin: fullScreen.getToolbar().setUIID(\u0026ldquo;Container\u0026rdquo;);\nFull sample:\nForm fullScreen = new Form(\u0026quot;\u0026quot;, new BorderLayout()) {\nhttps://uploads.disquscdn.c… @Override\nprotected boolean shouldPaintStatusBar() {\nreturn false;\n}\n};\nfullScreen.getToolbar().setUIID(\u0026ldquo;Container\u0026rdquo;);\nSpanLabel fullScreenLabel = new SpanLabel(\u0026ldquo;Takes up the whole screen!\u0026rdquo;);\nStyle s = fullScreenLabel.getAllStyles();\ns.setBgColor(0xff00);\ns.setBgTransparency(0xff);\ns.setMargin(0, 0, 0, 0);\nfullScreen.add(CENTER, fullScreenLabel);\nfullScreen.show;\nDenis — August 8, 2018 at 6:38 am (permalink) Denis says:\nthanks Shai, but ))) getToolbar() returns null, although it’s there or I confuse something ?\nhttps://uploads.disquscdn.c…\nhere is the code:\npublic MenuForm(Resources theme, Game game) {\nsuper(new TableLayout(3, 1));\nTableLayout mainTableLayout = (TableLayout) getLayout();\n// Form parameters\ngetToolbar().setUIID(\u0026ldquo;Container\u0026rdquo;);\n//setTitle(\u0026quot;\u0026quot;);\n//setScrollable(false);\n//getAllStyles().setBgImage(theme.getImage(\u0026ldquo;background.jpg\u0026rdquo;));\n//getAllStyles().setBackgroundType(Style.BACKGROUND_IMAGE_ALIGNED_CENTER);\nI also tried this:\nMenuForm menuForm = new MenuForm(theme, this);\nmenuForm.getToolbar().setUIID(\u0026ldquo;Container\u0026rdquo;);\nmenuForm.show;\nboth lead to this\njava.lang.NullPointerException\nat com.manyukhin.words.MenuForm.(MenuForm.java:58)\nat com.manyukhin.words.Game.start(Game.java:133)\nat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\nat sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)\nat sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)\nat java.lang.reflect.Method.invoke(Unknown Source)\nat com.codename1.impl.javase.Executor$1$[1.run](http://1.run)([Executor.java](http://Executor.java):140)\nat com.codename1.ui.Display.processSerialCalls(Display.java:1129)\nat com.codename1.ui.Display.mainEDTLoop(Display.java:924)\nat [com.codename1.ui.RunnableWr…](http://com.codename1.ui.RunnableWrapper.run)([RunnableWrapper.java](http://RunnableWrapper.java):120)\nat [com.codename1.impl.Codename…](http://com.codename1.impl.CodenameOneThread.run)([CodenameOneThread.java](http://CodenameOneThread.java):176)\nShai Almog — August 9, 2018 at 7:33 am (permalink) Shai Almog says:\nI suggest you don’t disable the global toolbar. If you’d keep it the code above should work fine.\nDenis — August 9, 2018 at 8:05 am (permalink) Denis says:\ndo you mean by theme constants or build hints, I removed them all\nand as you can see on screenshot in my previous message, toolbar is there\nShai Almog — August 10, 2018 at 4:56 am (permalink) Shai Almog says:\nThe default code for a new project enables the toolbar. No theme constant etc. See the toolbar code here: https://www.codenameone.com…\nDenis — August 10, 2018 at 5:59 am (permalink) Denis says:\nmany thanks Shai, I missed that global toolbar configuration in main app class, was looking at Form code )) interesting that app stays in fullscreen mode even without overridden shouldPaintStatusBar, just with toolbar margins/paddings set to zeros in theme file, but I will keep both, just letting you know\nDenis — August 10, 2018 at 7:41 am (permalink) Denis says:\nthe only thing left is the issue with some unicode symbols support when includeNativeBool is enabled, for example \u0026ldquo;→\u0026rdquo; symbol, is there a way to switch to font that used when includeNativeBool is off ?\nShai Almog — August 11, 2018 at 3:57 am (permalink) Shai Almog says:\nI would strongly suggest you don’t do that. The font that \u0026ldquo;works\u0026rdquo; is the system font as opposed to the native: font. But it looks bad and is less flexible both on the device and on the simulator.\nThe thing is that these issues might not happen on the device. The simulator uses the downloadable Roboto font or builtin helvetica both of which have limits. However, on the device their behavior and supported character range is better. You should be able to use Emojiis and everything when working on the device.\nDenis — August 11, 2018 at 6:30 am (permalink) Denis says:\nThanks Shai, I will try it on device as you suggest, as soon as I will be able to login to Dashboard, I have issues with that for some reason, talking with your support now\nDenis — August 15, 2018 at 7:39 am (permalink) Denis says:\nHi Shai, you were right, on real device character support is good, but notification bar is not covered by app, the same in emulator, but I thought that it’s just part of emulator skin\nShai Almog — August 16, 2018 at 4:50 am (permalink) Shai Almog says:\nOn which device? On Android it won’t be covered on iOS you need to style the status bar appropriately but I’m guessing here without a screenshot.\nDenis — August 16, 2018 at 10:28 am (permalink) Denis says:\nyes, Android (sorry, forgot to mention)\nhttps://uploads.disquscdn.c…\nI see that AdMobManager (admobfullscreen.cn1lib) is able to show full-screen ads\nhttps://uploads.disquscdn.c…\nso there should be some way, it’s good to have little bit more space ))\nShai Almog — August 17, 2018 at 3:40 am (permalink) Shai Almog says:\nThere is an experimental feature to hide the status bar here: https://www.codenameone.com…\nNotice that the ad you are seeing is full screen but it also doesn’t show the battery/clock etc. which is pretty problematic. It might have issues with notche UI’s.\nDenis — August 17, 2018 at 7:19 am (permalink) Denis says:\nthanks Shai, I am developing casual game, and full-screen in context of games is exactly what this ads extension does, hide everything (toolbar, status bar) and use as much as screen space as possible, besides that, even if app itself is not full-screen, ads will be shown in full-screen mode anyway, which creates inconsistent experience, app will jump to full-screen and back, I anyway will test that on real device and see what’s better, thanks\nThomasH99 — January 29, 2021 at 9:29 pm (permalink) ThomasH99 says:\nThe live update of CSS has stopped working for me since some time (not sure exactly when since haven’t edited the CSS for months). Was it disabled? If not, any suggestions for how I might fix this?\nShai Almog — January 30, 2021 at 6:11 am (permalink) Shai Almog says:\nNo. It should work. Look in the simulator console, does it print out anything about CSS when launching?\nThomasH99 — January 30, 2021 at 9:02 pm (permalink) ThomasH99 says:\nI get a load of messages like this:\nThe class com.codename1.ui.plaf.CSSBorder$ColorStop in file /Users/user/NetBeansProjects/CodenameOne/Ports/JavaSE/build/classes/com/codename1/ui/plaf/CSSBorder$ColorStop.class is out of date due to com.codename1.ui.plaf.CSSBorder$ColorStop but has not been deleted because its source file could not be determined\nThen I get this on app start (the simulator does read the css on launch, but apparently not afterwards):\nUpdating merge file /Users/user/NetBeansProjects/MyApp/css/theme.css.merged\nInput: /Users/user/NetBeansProjects/MyApp/css/theme.css\nOutput: /Users/user/NetBeansProjects/MyApp/src/theme.res\nAcquiring lock on CSS checksums file /Users/user/NetBeansProjects/MyApp/.cn1_css_checksums…\nLock obtained\nReleasing lock\nCSS file successfully compiled. /Users/user/NetBeansProjects/MyApp/src/theme.res\nWhen I edit and save the css file while the Simulator is running, I used to get an output trace (getting the lock, etc), but now nothing seems to happen.\nThis is on a Mac.\nShai Almog — January 31, 2021 at 2:26 am (permalink) Shai Almog says:\nSo you don’t see something like \u0026ldquo;CSS\u0026gt; Changed detected in /Users/shai/temp/TestApp/css/theme.css. Recompiling\u0026rdquo; ?\nDid you change something about the project?\nDid you activate CSS via preferences?\nIf you create a new project, update it (using Codename One Settings) and activate CSS. Does the problem still happen?\nThomasH99 — February 2, 2021 at 5:54 pm (permalink) ThomasH99 says:\nNo, I don’t see that text anymore, only when I compile the project, not each time I change the css file. For a new project it works correctly. I’ve also checked that css is activated in the CN1 settings. I’ve made a lot of changes to the project, so difficult to trace it back. What kind of changes could break the css? At least, when this feature is not working anymore, you realize how nice it is 😉\nShai Almog — February 3, 2021 at 3:17 am (permalink) Shai Almog says:\nCheck if codenameone_settings.properties has the csswatcher.enabled=true entry. Also look at the CSS file itself and the related generated files. Make sure they don’t have some weird permissions or restrictions that might be blocking the CSS compiler.\nThomasH99 — February 4, 2021 at 6:55 pm (permalink) ThomasH99 says:\nI tried adding the setting csswatcher.enabled=true, but still not loading. This setting is also not present in the HelloWorld example that works correctly, so it doesn’t seem to be necessary. And since the css file is loaded correctly each time the project is recompiled, I guess there shouldn’t any issues in the file itself or the generated files… I also tried updating the cn1libs, copying over the CodeNameOneBuildClient.jar from HelloWorld and deleting the files theme.css.checksums, theme.css.merged and theme.css.merged.checksums, but also no change. I’m using Netbeans 12.2 – could that have an impact? WIth CN1 Preferences editor is 6.5.\nSteve Hannah — February 4, 2021 at 7:11 pm (permalink) Steve Hannah says:\nI tried adding the setting csswatcher.enabled=true, but still not loading.\n@ThomasH99 Can you file and issue in the issue tracker, and share your codenameone_settings.properties file so I can take a look at the settings.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/live-css-update/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/live-css-update/new-features-6.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eUp until last Friday CSS support has been a second class citizen, with the release of Codename One 4.2 we’re making CSS a core feature. We also improved the builtin CSS support extensively!\u003cbr\u003e\nChanges you make to a CSS file will instantly reflect in the simulator. You don’t need to compile or do anything special. When you launch the simulator we open a CSS watcher thread that automatically recompiles \u0026amp; deploys the CSS whenever you save.\u003c/p\u003e","title":"Live CSS Update"},{"content":"\nOne of our enterprise accounts is working on a complex GIS application that needs fine grained control over mapping. In this case features such as native maps aren’t useful. For some GIS applications the old MapComponent is more useful as it allows working with domain specific data. One of the features he needed was spatial support in the builtin SQL database.\nWhen we initially implemented sqlite support we just delegated all the SQL calls to the OS native equivalents and called it a day. This works well for 98% of the cases but there are two big use cases that are missing by default in Android \u0026amp; iOS: Spatial queries \u0026amp; Security.\nSpatiaLite allows you to use geographic locations in SQL. You can effectively query based on physical location which is surprisingly hard to do accurately without such an API. For simple cases like an Uber app you wouldn’t necessarily need something like that but for the more elaborate use cases it might become essential.\nThe SQL database in iOS/Android isn’t encrypted either, this isn’t a big deal for most applications but for some highly secure implementations that might be a hindrance. There is builtin support for encryption in SQLite that can be turned on as well.\nA Pluggable Solution We needed to solve the first problem so Steve created the Spatialite cn1lib which is now available in the extension manager. The cn1lib extends the Database class \u0026amp; allows you to plug-in a custom version of sqlite to replace the Database.\nThis approach can be extended to support other use cases for security and potentially other capabilities we aren’t aware of.\nAs a side note this took a lot of effort to build. That’s the type of work we do for enterprise customers!\nFacebook Module Status With a quick pivot I’ll also provide a quick update on the facebook clone module. We now have 8 lessons in the module and I’ve been adding more on a daily basis. I’m pretty sure we’ll have way more than 30 lessons so I’ll try to pick up the pace!\nHere is another sample of the new post Form:\nFigure 1. New Post Form in The Facebook Clone App Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJulio Valeriron Ochoa — November 29, 2022 at 2:29 pm (permalink) how turn on encryptation mode in sqlite\nKimotho E — July 9, 2024 at 4:51 pm (permalink) Kimotho E says:\nHow can a custom version of sqlite be plugged in to replace the Database?\nShai Almog — July 10, 2024 at 2:31 am (permalink) Shai Almog says:\nSee https://github.com/shannah/cn1-spatialite create something similar with your version of sqlite.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/spatial-pluggable-sqlite/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/spatial-pluggable-sqlite/maps.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of our enterprise accounts is working on a complex GIS application that needs fine grained control over mapping. In this case features such as native maps aren’t useful. For some GIS applications the old \u003ccode\u003eMapComponent\u003c/code\u003e is more useful as it allows working with domain specific data. One of the features he needed was spatial support in the builtin SQL database.\u003c/p\u003e\n\u003cp\u003eWhen we initially implemented sqlite support we just delegated all the SQL calls to the OS native equivalents and called it a day. This works well for 98% of the cases but there are two big use cases that are missing by default in Android \u0026amp; iOS: Spatial queries \u0026amp; Security.\u003c/p\u003e","title":"Spatial, Pluggable SQLite"},{"content":"\nI mentioned before that I’m really behind on the Facebook Clone module but at least I was able to release the first few lessons by today which makes it fit into an April deadline. I’ll try to release new lessons every day so we can do have the full module out before the end of May. At that point I’ll release two new modules during June.\nThe new Facebook Clone is similar to the Uber clone in some regards and also very different:\nI didn’t do a \u0026ldquo;pixel perfect\u0026rdquo; clone – Facebook is too messy to clone properly\nI used CSS instead of the designer tool – it’s easier to tech CSS as I can go over code instead of screenshots\nI put more logic in the server and tried to make the app more \u0026ldquo;real\u0026rdquo;\nThe things I kept in place are:\nMySQL – it’s a pretty good database and easy to work with when compared to no-SQL solutions. In fact it’s also WAY faster than most of them for real world loads. I see a lot of startups buying into the no-SQL hype which makes sense for some cases but usually doesn’t\nSpring Boot – I chose to use version 2.0 which went GA by now. It’s a great option for Java developers!\nOne of the things I’d love to do is port this to Kotlin, maybe as one of the extra modules to be discussed later.\nI’ll leave you with a couple of screenshot studies of the original vs. clone:\nFigure 1. Original vs. Clone Portrait\nFigure 2. Original vs. Clone Landscape Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbeck — April 30, 2018 at 5:04 pm (permalink) Are these clones (uber \u0026amp; fb clone) apk files available so that we can test them in devices before diving into the courses?\nShai Almog — May 1, 2018 at 4:28 am (permalink) No. That would be legally problematic.\nTommy Mogaka — May 1, 2018 at 6:03 am (permalink) Tommy Mogaka says:\nIn the fb clone, will you also do the messenger part? I mean that little chat widget. That would be really cool…\nKeep up the goodwork! cn1 is truly a solid development tool, best of both worlds i.e. cross-platform and native.\nShai Almog — May 2, 2018 at 2:25 pm (permalink) Shai Almog says:\nNo.\nThe next app that’s currently scheduled for August-September would be a WhatsApp clone so this should probably cover that aspect. See https://www.codenameone.com…\nThanks.\nFrancesco Galgani — May 4, 2018 at 1:28 pm (permalink) Francesco Galgani says:\nDear Shai,\nthank you for your work 🙂\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/facebook-clone-slow-landing/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/facebook-clone-slow-landing/build-real-world-full-stack-mobile-apps-in-java.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI mentioned before that I’m really behind on the Facebook Clone module but at least I was able to \u003ca href=\"https://codenameone.teachable.com/p/build-real-world-full-stack-mobile-apps-in-java\" target=\"_blank\" rel=\"noopener noreferrer\"\u003erelease the first few lessons\u003c/a\u003e by today which makes it fit into an April deadline. I’ll try to release new lessons every day so we can do have the full module out before the end of May. At that point I’ll release two new modules during June.\u003c/p\u003e\n\u003cp\u003eThe new Facebook Clone is similar to the Uber clone in some regards and also very different:\u003c/p\u003e","title":"Facebook Clone Slow Landing"},{"content":"\nThis weekend we pushed out an update that also included new versions of the GUI builder and the designer. We didn’t update the plugins but we still think it warrants the 4.1 version moniker even though we don’t support it in versioned builds. Due to one of the enhancements we added in this update we had a regression in command behavior that we fixed with an update within a few hours.\nThis regression was caused by new features in the Command class that now has the ability to set the material icon. Unfortunately we neglected to add this into the equals method which cascaded into a hard to track issue in toolbar handling. This impacted people using the addMaterialCommand API’s which also included the GUI builder. The update framework allowed us to issue a quick update and resolve that issue.\nLaunch Screen Storyboards With the shift to Xcode 9, which is the default version on the Codename One build servers as of February 2018, it is now possible to use a launch-screen storyboard as the splash screen instead of launch images. This will potentially solve the issue of the proliferation of screenshots, as you can supply a single storyboard which will work on all devices. Launch storyboards are disabled by default at this time, but we will flip the switch for 5.0 so they will be the default. You can enable the LaunchScreen storyboard by adding the ios.multitasking=true build hint and explicitly disable them by setting it to false.\nThe build hint is called \u0026ldquo;multitasking\u0026rdquo;, because iOS’ split-screen and multi-tasking feature requires that the app uses a launch storyboard rather than launch images.\nBesides the advantage of multi-tasking support the launch screen storyboards have a few advantages:\nIt’s the official direction – Apple is clearly heading in this direction instead of splash screens so it’s more \u0026ldquo;future proof\u0026rdquo;\nFaster builds – by now we need to generate 16 screenshots per build, this can slow down builds noticeably\nSmaller binaries – some of these 16 screenshots can be very large\nNative widgets \u0026amp; OS fidelity – the screenshot process has a lot of problems most noticeably it fails if you use a native widget in the home screen. These problems go away with this approach\nLaunch Storyboard vs Launch Images A key benefit of using a launch storyboard right now is that it allows your app to be used in split-screen mode. Storyboards, however, work a little bit differently than launch images. They don’t show a screenshot of the first page of your app. The default Codename One launch storyboard simply shows your app’s icon in the middle of the screen. You can customize the launch screen by providing one or more of the following files in your project’s native/ios directory\nLaunch.Foreground.png – Will be shown instead of your app’s icon in the center of the screen.\nLaunch.Background.png – Will fill the background of the screen.\nLaunchScreen.storyboard – A custom storyboard developed in Xcode, that will be used instead of the default storyboard.\n__ Make sure to add the ios.multitasking=true build hint, or your launch storyboard will not be used. Facebook Clone Status Update It seems pretty clear I won’t finish the Facebook Clone work by the end of the month…​ My newer course modules have been far more thorough than my earlier work and take much longer as a result…​\nThe upshot of this is that it already looks pretty amazing, besides the app itself I’m very pleased with the materials I’ve produced so far and I think content creation will reach a new level.\nUnlike the Uber Clone, I decided to use CSS for the Facebook Clone app. I still prefer working visually with the designer but explaining CSS in a presentation is simpler. For the designer I need to go over multiple UI screens and explain everything which is ultimately slower.\nAs part of that I asked Steve to add a few enhancements to the CSS support which is now noticeably faster. Hopefully this is something we can further improve so it will provide the same benefits we have in the Component Inspector tool. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — April 25, 2018 at 8:05 am (permalink) Francesco Galgani says:\nYou wrote: «The default Codename One launch storyboard simply shows your app’s icon in the middle of the screen». My question is about the size of this icon: because it’s always sized 512×512 pixels, does its actual size vary according the screen DPI? In my apps, I implemented a splash screen with the app’s icon sized as I want it, but if Codename One shows app’s icon in the middle of the screen, probably I’ll have two splash screens, that will be the same app’s icon sized differently… that is not what I want, of course.\nFrancesco Galgani — April 25, 2018 at 12:22 pm (permalink) Francesco Galgani says:\nYou wrote that we can get smaller binaries, but the screenshot images are still generated with ios.multitasking=true and without ios.fastbuild=true build hints. But ios.fastbuild=true is only for debug builds (according to the developer guide). Please see the shannah reply to this issue: https://github.com/codename…\nShai Almog — April 26, 2018 at 5:42 am (permalink) Shai Almog says:\nIt should adapt the size but that would probably be inconsistent with your splash screen.\nI misunderstood Steve’s implementation so the post above gets some current facts wrong. I think we need to shift the implementation to match the post not the other way around. We’re discussing this, I don’t think it makes sense to have both the screenshots and the xib.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/version-4-1-launch-screen-storyboards/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/version-4-1-launch-screen-storyboards/codenameone-4-0-release-image-taxi.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis weekend we pushed out an update that also included new versions of the GUI builder and the designer. We didn’t update the plugins but we still think it warrants the 4.1 version moniker even though we don’t support it in versioned builds. Due to one of the enhancements we added in this update we had a regression in command behavior that we fixed with an update within a few hours.\u003c/p\u003e","title":"Version 4.1 and Launch Screen Storyboards"},{"content":"\nI’ve been working on the new Facebook clone app, I have a lot to say about that but I’ll defer that for now. One of the things that Facebook did is provide a different experience in iOS \u0026amp; Android. I wanted to replicate that by using a more iOS style back behavior in my clone.\nFigure 1. Back Command iOS/Android \u0026amp; Facebooks native on Android\nOn Android we use an arrow to indicate back but on iOS we usually show the title of the previous form with a \u0026lt; icon to indicate the back action. Up until recently this was represented in the BackCommand UIID with a an image aligned to the left of the command. This was hard to style and made very little sense.\nWith the next update we’ll use the builtin material icon for this when you set a back command. In this form I used the following code for back:\ngetToolbar().setBackCommand(backLabel, Toolbar.BackCommandPolicy.WHEN_USES_TITLE_OTHERWISE_ARROW, e -\u0026gt; previous.showBack()); The backLabel variable represents the title of the previous form. The toolbar policy indicates an arrow will be used on Android and a Title will appear on iOS.\nThis will work with the new material font code in the next update (you need to update the skins too). You can disable or force the font image behavior with the new theme constant iosStyleBackArrowBool=false.\nMaterial Icon Commands As part of that work we added three new methods to Command:\npublic void setMaterialIcon(char materialIcon); public void setMaterialIconSize(float size); public void setIconGapMM(float iconGapMM); These allow control over the gap between the icon and the label for the command element as well as set the icon as a material icon.\nWe updated a lot of the Toolbar code to use these internally so UI will adapt better to changes in UIID’s.\nLandscape UIID’s setUIID is a core API that hasn’t changed in ages. We just added a new version of this API that accepts two strings. One represents the UIID in portrait and the other (optional one) can represent a different UIID for landscape.\n__ If they are the same the other string should be null This allows us to easily implement minor UI changes that make sense when switching orientation e.g. smaller font/padding in the title area. Since that is the chief use case we also added a theme constant which is currently false by default: landscapeTitleUiidBool=true.\nWhen you set this to true the UIID’s: ToolbarLandscape, TitleCommandLandscape, BackCommandLandscape \u0026amp;TitleLandscape will be used for landscape mode. They all derive their non-landscape versions so just setting the flag to true should have no effect. You will need to edit these styles to support this behavior.\nContainer UIID \u0026amp; Font Api’s While we are on the subject of UI enhancements we also made a few enhancements to the general API.\nContainer now accepts a UIID in the constructor with the layout. It’s one less line of code when you create a container.\nWe moved the constants from Font into the CN class and added a couple of helper methods to create fonts more easily. Specifically:\npublic static Font createTrueTypeFont(String fontName); public static Font createTrueTypeFont(String fontName, float sizeMm); So instead of doing:\nFont n = Font.createTrueTypeFont(\u0026quot;native:MainLight\u0026quot;, \u0026quot;native:MainLight\u0026quot;). derive(convertToPixels(3)); You can do:\nFont n = Font.createTrueTypeFont(\u0026quot;native:MainLight\u0026quot;, 3); Summary I hope we won’t break anything with these changes but experience tells me there is always some nuance. Hopefully these will resolve themselves as we move forward.\nI have a lot more to say about the Facebook app, I hope I’ll complete it in time but frankly with my current status it’s a bit doubtful as I’m seriously delayed and back logged. On the plus side what I have so far looks great! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — May 18, 2018 at 7:43 am (permalink) Thank you very much for this information, this post helped me on setting correctly the back buttons for iOS and Android. Thank you for all the other news.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/ios-back-command-behavior/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/ios-back-command-behavior/pixel-perfect.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been working on the new Facebook clone app, I have a lot to say about that but I’ll defer that for now. One of the things that Facebook did is provide a different experience in iOS \u0026amp; Android. I wanted to replicate that by using a more iOS style back behavior in my clone.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Back Command iOS/Android \u0026amp; Facebooks native on Android\" loading=\"lazy\" src=\"/blog/ios-back-command-behavior/facebook-clone-back-command.png\"\u003e\u003c/p\u003e\n\u003cp\u003eFigure 1. Back Command iOS/Android \u0026amp; Facebooks native on Android\u003c/p\u003e","title":"iOS Back Command Behavior and Facebook Clone Update"},{"content":"\nI’ve been working on improved learning materials for Codename One. One of the problems with videos is that I can sometimes unintentionally drag an idea that can be explained with a single image. DPI is one of those ideas, I’m assuming most of you already understand it but even if you do, I think this graphic helps put things in perspective.\nFigure 1. Device Density Explained in One Image Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nmaxii123 — April 11, 2018 at 11:30 am (permalink) I think you need to step back and re-evaluate. That picture explains nothing. And I’m a professional programmer well versed in dpi and scaling issues. That’s just a lot of figures that only mean anything if you already understand it.\nShai Almog — April 11, 2018 at 1:11 pm (permalink) Shai Almog says:\nThanks for the feedback. How would you improve that graphic?\nThe target audience for this graphic are programmers who have no experience in mobile. I just want to help visualize the density issue, not the solutions which would require a different graphic.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-dpi-explained/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-dpi-explained/learn-codenameone-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been working on improved learning materials for Codename One. One of the problems with videos is that I can sometimes unintentionally drag an idea that can be explained with a single image. DPI is one of those ideas, I’m assuming most of you already understand it but even if you do, I think this graphic helps put things in perspective.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Device Density Explained in One Image\" loading=\"lazy\" src=\"/blog/tutorial-dpi-explained/dpi-explained.jpg\"\u003e\u003c/p\u003e\n\u003ch2 id=\"figure-1-device-density-explained-in-one-image\"\u003eFigure 1. Device Density Explained in One Image\u003c/h2\u003e\n\u003ch2 id=\"archived-comments\"\u003eArchived Comments\u003c/h2\u003e\n\u003cp\u003e\u003cem\u003eThis post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\u003c/em\u003e\u003c/p\u003e","title":"Tutorial – DPI Explained"},{"content":"\nI published two articles on MapLayout here and here. After all that work they are now effectively obsolete thanks to a new API in MapContainer that builds component placement directly into the map itself.\nUnfortunately the Google API doesn’t let us position components (native or otherwise) accurately as it pans the map. This creates a small delay when panning/zooming as the components try to catch up to the map. The only workaround is to convert the components to images and ask the map to move images within it. Then convert the images back when the map finishes panning. That’s exactly what Steve implemented within the native maps.\nFor you as a developer this is all seamless. If you use the map API and add components into the map they will \u0026ldquo;magically\u0026rdquo; update to the right position \u0026amp; transition between rendering as an image and as a component. If you would like more control over this process you can override the new toImage() method of Component to tune that behavior.\nThe new API works just like the regular marker API, you can add a component to the map at a given latitude/longitude position using:\nmap.addMarker(component,location); You can also anchor the location to a specific alignment vertically and horizontally.\nThis makes the Uber demo app much simpler. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — April 10, 2018 at 1:50 pm (permalink) Francesco Galgani says:\nIt’s a very good news 🙂\nHowever, in the past (in one of my StackOverflow questions) you suggested me to implement a new custom layout extending the abstract class Layout. I’ve done it and it solved my problem, I used your MapLayout as an example of custom external Layout. My suggestion is to add some documentation (in the developer guide and/or in a tutorial) on the basic steps to implement a simple custom layout, because your example of MapLayout is quite complex. Thank you 🙂\nShai Almog — April 11, 2018 at 7:16 am (permalink) Shai Almog says:\nThe original version of that layout was simpler. The complexity came from communicating with the underlying map API. We used to have a different sample which I can no longer find but it wasn’t very realistic. The gist of the layout manager is just the logic within layoutContainer. Not much more. You can check out the existing layout managers for samples.\nUnfortunately I can’t think of a layout manager that I would want to write that isn’t easier to implement with existing layout managers.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/map-component-positioning-revisited/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/map-component-positioning-revisited/maps.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI published two articles on \u003ccode\u003eMapLayout\u003c/code\u003e \u003ca href=\"/blog/map-layout-update/\"\u003ehere\u003c/a\u003e and \u003ca href=\"/blog/tip-map-layout-manager/\"\u003ehere\u003c/a\u003e. After all that work they are now effectively obsolete thanks to a new API in \u003ccode\u003eMapContainer\u003c/code\u003e that builds component placement directly into the map itself.\u003c/p\u003e\n\u003cp\u003eUnfortunately the Google API doesn’t let us position components (native or otherwise) accurately as it pans the map. This creates a small delay when panning/zooming as the components try to catch up to the map. The only workaround is to convert the components to images and ask the map to move images within it. Then convert the images back when the map finishes panning. That’s exactly what Steve implemented within the native maps.\u003c/p\u003e","title":"Map Component Positioning Revisited"},{"content":"\nTimezones suck. Especially daylight saving. I don’t mind moving the clock or losing an hour of sleep as much as the programming bugs related to that practice. The thing that sucks even more is Java’s old date/time API.\nThis was publicly acknowledged by the Java community with JSR 310 which replaced the Java Date \u0026amp; Time API’s however due to its complexity we still don’t have it yet. As a small workaround we created a small API to perform some common date calculations.\nDateUtil allows you to check if a day is in the daylight saving era or if it isn’t. It works consistently on all platforms without a problem e.g.:\nDateUtil du = new DateUtil(); Log.p(\u0026quot;Currently in daylight savings time? \u0026quot;+du.inDaylightTime(new Date())); Log.p(\u0026quot;Offset: \u0026quot;+du.getOffset(new Date().getTime())); Date dec30 = new Date(1483056000000l); Log.p(\u0026quot;Dec 30 is daylight savings time? \u0026quot;+du.inDaylightTime(dec30)); Log.p(\u0026quot;Offset: \u0026quot;+du.getOffset(dec30.getTime())); The DateUtil constructor can take a TimeZone as parameter. Without it, it uses the default TimeZone.\nCompletion Listeners Media allows us to track whether it finished playing or not when we first set it up. After that point you were on your own.\nLast week we added a new ability to bind a completion listener after the fact and potentially have multiple listeners:\nMediaManager.addCompletionHandler(myMediaObject, () -\u0026gt; Log.p(\u0026quot;This is a runnable callback\u0026quot;)); Partial Round I’ve been working on improving this issue. The UI part isn’t there yet but the code is…​\nThe gist of it is that with the round rect border we currently have 3 options:\nAll corners should be rounded\nOnly the top corners\nOnly the bottom corners\nThe issue pointed out a use case for some of the corners and I can think of a case where I’d like the left or right corners rounded…​\nWith that in mind I decided the right thing to do is offer control over individual corners. This is possible only in code at the moment but would hopefully make it to the designer tool too at some point:\nRoundRectBorder rb = RoundRectBorder.create().bottomLeftMode(false); This would create a border whose corners are round except for the bottom left corner. While I was working on the class I also improved the performance/memory overhead of the border for solid colors.\nSupport for PATCH HTTP Request In Rest The Rest class now supports the HTTP PATCH method which was missing from the API before. It’s not as common as other API’s so it went unnoticed for a while.\nIt works pretty much like every other Rest API request. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — April 9, 2018 at 12:07 pm (permalink) Francesco Galgani says:\nThank you very much for the partial RoundRectBorder, it works as expected. I hope you can integrate it in the Designer 🙂\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/date-util/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/date-util/new-features-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eTimezones suck. Especially daylight saving. I don’t mind moving the clock or losing an hour of sleep as much as the programming bugs related to that practice. The thing that sucks even more is Java’s old date/time API.\u003cbr\u003e\nThis was publicly acknowledged by the Java community with JSR 310 which replaced the Java Date \u0026amp; Time API’s however due to its complexity we still don’t have it yet. As a small workaround we created a small API to perform some common date calculations.\u003c/p\u003e","title":"Date Util"},{"content":"\nI discussed the new Camera cn1lib last week. One of the motivations for doing it (besides the request from an enterprise account) was that of a new course module. Last week I added a new module covering the process of building the camera cn1lib…​\nWe have several online videos (both in the course and outside of it) covering native interfaces. So why do we need another one?\nWorking with native code is error prone \u0026amp; complex. A lot of the tutorials we built in the past ended up spending more time on configuration issues than on code.\nIn this module I talked a lot about Objective-C, callbacks, delegates \u0026amp; more. If you are thinking about native integration this helps give a more rounded view of the options.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/build-native-interfaces-module-camera-edition/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/build-native-interfaces-module-camera-edition/deep-dive-into-mobile.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI discussed the new \u003ca href=\"/blog/camerakit-low-level-camera-api.html\"\u003eCamera cn1lib last week\u003c/a\u003e. One of the motivations for doing it (besides the request from an enterprise account) was that of a new course module. Last week I added a \u003ca href=\"https://codenameone.teachable.com/p/deep-dive-into-mobile-development-with-codename-one\" target=\"_blank\" rel=\"noopener noreferrer\"\u003enew module\u003c/a\u003e covering the process of building the camera cn1lib…​\u003cbr\u003e\nWe have several online videos (both in the course and outside of it) covering native interfaces. So why do we need another one?\u003c/p\u003e\n\u003cp\u003eWorking with native code is error prone \u0026amp; complex. A lot of the tutorials we built in the past ended up spending more time on configuration issues than on code.\u003cbr\u003e\nIn this module I talked a lot about Objective-C, callbacks, delegates \u0026amp; more. If you are thinking about native integration this helps give a more rounded view of the options.\u003c/p\u003e","title":"Build Native Interfaces – Camera Edition"},{"content":"\nI’m used to NetBeans but if I will ever switch it will be to IntelliJ/IDEA. It’s a great IDE. I just need to rewire the muscle memory of my fingers for it. The Codename One plugin support on IntelliJ should be as good as the NetBeans support as the code is very similar. There are however a couple of pitfalls that a lot of people trip over which I’d like to discuss.\nTree Mode IntelliJ defaults to showing errors as a \u0026ldquo;tree\u0026rdquo;. It parses the output of the app to the console and shows \u0026ldquo;pretty\u0026rdquo; output. Unfortunately this doesn’t always play nice with Codename One and hides things like compiler errors.\nWe strongly recommend you disable that setting…​\nFigure 1. Toggling off the Tree Mode\nOut of Memory in Ant Build When you start working and your code grows (especially with Kotlin) you might run into an out of memory error during compilation. You can resolve that by setting the memory available to Ant as explained in this image.\nFigure 2. Configuring the Memory Available to Ant Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\ndavidwaf — April 4, 2018 at 8:16 am (permalink) Netbeans here too. Can’t just switch.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-intellij-idea-ram/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-intellij-idea-ram/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’m used to NetBeans but if I will ever switch it will be to IntelliJ/IDEA. It’s a great IDE. I just need to rewire the muscle memory of my fingers for it. The Codename One plugin support on IntelliJ should be as good as the NetBeans support as the code is very similar. There are however a couple of pitfalls that a lot of people trip over which I’d like to discuss.\u003c/p\u003e","title":"TIP: IntelliJ/IDEA RAM"},{"content":"\nWhen we introduced support for z-ordering of peer components in Codename One we listed two major targets. The first was already available: Map. The second was still pending: Camera.\nOur current Capture API is very high level and removes a lot of the control from the developer. In order to give developers a high level of control we created Camera Kit.\nCamera Kit is based on a native Android Camera Kit project whose API we used to implement the Android port and for inspiration. This new API works on Android \u0026amp; iOS at this time. It allows you to grab photos/videos \u0026amp; view the camera preview like you would any other media.\nYou can overlay your Codename One widgets on top of the camera view as you can see in the project sample and screenshot.\nThis effectively makes a lot of previously impossible use cases possible. E.g. grabbing a photo after a given interval, grabbing a video for a fixed number of seconds. Placing a UI element on top of the camera view etc.\nOne of the really cool things about this is that it’s entirely in a cn1lib. That means you can grok the code without understanding Codename One. You can fix issues and add functionality without knowing too much.\nAs a sidenote the reason we picked up this task is because an enterprise customer asked for this…​ If you can afford an enterprise account we really appreciate it and everyone gets the benefit of the new functionality!\nSo if the company you work for can purchase an enterprise account this can help everyone who uses Codename One.\nStatus \u0026amp; Future Right now only a part of the functionality is implemented on iOS with some nuances still missing. On Android we get errors due to a bug in the native Android Camera Kit library. Since the native library is heading for a 1.0 version this should be resolved when we update to that.\nI would love to see ports of this to other Codename One platforms and the simulator. We’ll take a look at these as we move forward based on user demand. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAmuche Chimezie — March 29, 2018 at 3:45 pm (permalink) Amuche Chimezie says:\nAwesome!! Finally.. Thank you Shai\nthunderkilll — April 27, 2018 at 5:47 am (permalink) thunderkilll says:\nplease i have question how can i change the file Path trajectory String filePath = Capture.capturePhoto();\nand instead the filePath = \u0026ldquo;http://localhost/images/\u0026quot;+imageName ;\nShai Almog — April 28, 2018 at 5:32 am (permalink) Shai Almog says:\nThat’s a URL not a file path. Your app needs to save the file to a path you \u0026ldquo;own\u0026rdquo; which is the file system app home directory. Can you clarify what you are trying to do?\nNotice that you can’t copy a file everywhere in a mobile OS as devices isolate the apps from one another to prevent security exploits.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/camerakit-low-level-camera-api/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/camerakit-low-level-camera-api/camera-kit-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen we introduced support for z-ordering of peer components in Codename One we listed two major targets. The first was already available: Map. The second was still pending: Camera.\u003cbr\u003e\nOur current \u003ccode\u003eCapture\u003c/code\u003e API is very high level and removes a lot of the control from the developer. In order to give developers a high level of control we created \u003ca href=\"https://github.com/codenameone/CameraKitCodenameOne/tree/master\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCamera Kit\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/codenameone/CameraKitCodenameOne/tree/master\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCamera Kit\u003c/a\u003e is based on a native \u003ca href=\"https://github.com/CameraKit/camerakit-android/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eAndroid Camera Kit project\u003c/a\u003e whose API we used to implement the Android port and for inspiration. This new API works on Android \u0026amp; iOS at this time. It allows you to grab photos/videos \u0026amp; view the camera preview like you would any other media.\u003c/p\u003e","title":"Camera Kit – Low Level Camera API"},{"content":"\nA while back Google announced that starting in August 2018 they will no longer accept applications targeting API levels below 26. With that in mind we plan to migrate our builds to use API level 27 which brings with it a lot of great new features but will probably break some things as we go through the migration. Please read this post carefully, I’ll try to cover everything.\nNotice that this announcement means that we will need to start updating the API levels every year which is a much faster pace.\nI’ve constructed this post as a set of questions/answers.\nWhat’s an API Level? Every time Google releases a new version of Android it updates the API level e.g. currently Oreo (8.1) is API level 27.\nWhen we build a native Android application we need to declare the \u0026ldquo;target\u0026rdquo; this means we compiled the project against this given API level. This is a double edged sword…​ When we pick a higher API level we can target new features of newer OS’s but we are also subject to new restrictions and changes.\nE.g. when we migrated to API level 23 we had to change the way permissions are processed in applications. For Codename One code this was mostly seamless but if you relied on native code this sometimes triggered issues.\nAPI level 27 can impact things such as background behavior of your application and can break some cn1libs/native code you might have in place.\nFYI this is also explained in this article from Ars.\nWill this Work for Older Devices? The target API level doesn’t restrict older devices. For that we have a separate minimum target device and it indicates the lowest API level we support. Currently the default is 15 (Android 4.0.3 – Ice Cream Sandwich) but you can probably set it as low as 9 (Android 2.3 – Gingerbread) as long as you test the functionality properly and disable Google Play Services.\nSee this for a table of all the API levels from Google.\nWhat API Level do we use Now? That depends on your app. Our default is 23 but some cn1libs set the API level to 25.\nWe chose to migrate slowly as level 23 is generally good and stable.\nTest This Now! Test API level 27 right now before we flip the switch!\nThis is important as we want to iron out bugs/regressions before they impact everyone. You can enable this seamlessly by setting the build hint: android.buildToolsVersion=27\n__ Remove this build hint after testing, otherwise when we migrate to a newer version later on it might fail! This will implicitly set a lot of other values including the target level and it will change the gradle version from 2.12 to 4.6.\nOther Benefits. By flipping this switch the build should now work on Android Studio 3.x out of the box without the changes listed in this tip. We also plan to enable other things in the resulting project such as using Googles builtin Java 8 support instead of ours (this isn’t enabled yet).\nThis will mean that native Android code would be able to use Java 8 features. Notice that this currently applies to the native interfaces only and not to the code in the Codename One implementation.\nThis should make it easier to work with some 3rd party libraries that already moved forward.\nWhen Will this Happen? The 27 build target is available now using the build hint: android.buildToolsVersion=27.\nCurrently we are aiming to flip the switch by May. This might be pushed to a different date based on responses/feedback on the current status. We want to have enough time ahead so the July release of Codename One 5.0 (Social) will use this.\nIs this a Good Thing? I think it is. It prevents stagnation within the appstore.\nI still see apps in the stores that target Gingerbread (API level 9). That’s a problem both visually \u0026amp; in terms of permissions/security.\nI don’t think it will do enough to combat fragmentation. Google will need to change a lot more to fix that pickle but it’s a baby step in the right direction. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — April 6, 2018 at 9:56 am (permalink) Francesco Galgani says:\nI’ve done some tests with \u0026ldquo;android.buildToolsVersion=27\u0026rdquo; in Android 7 and Android 5 devices and I didn’t notice any difference 🙂\nHowever, I don’t understand why the target API level doesn’t restrict older devices: if the API 27 is for Android 8.1, how is it possible that the older devices are supported? Is it possible because Codename One build servers don’t generate code that is supported only by recent devices?\nShai Almog — April 7, 2018 at 4:42 am (permalink) Shai Almog says:\nGood to hear.\nThis is a feature from native Android not us. There are 2 different values: minimum API level and Target API level.\nWhen we use a feature from API 27 we check if the device supports API 27 first then call it. This means it will still work on an API 15 device without a problem.\nThis is a \u0026ldquo;statement\u0026rdquo; from the app to the runtime environment saying we tested on an Android 8 device. That means that Google will enable small incompatible changes to Android once this is set. A good example is background behavior which will now be more aggressive.\nE.g. In API 23 (Andoid 6) Google introduced a new permission system.\nSo if you had an Android 5 device and installed an app compiled with target 23 it would still work and show the permission prompt during install.\nIf you have an Android 6 device and installed an old app (target smaller than 23) it would behave like an Android 5 device and show permissions during install.\nHowever, if both the app and the device are API 23 or newer the app would install instantly and prompt for permissions in runtime.\nDenis — May 12, 2018 at 8:45 am (permalink) Denis says:\nHi Shai,\nI have put android.buildToolsVersion=27 in build hints, however when I upload apk to Play Console, it warns that app still targets API 23, could you please take a look at screenshots and advise ?\nThanks,\nDenis\nhttps://uploads.disquscdn.c… https://uploads.disquscdn.c…\nShai Almog — May 13, 2018 at 4:25 am (permalink) Shai Almog says:\nHi,\nwhat do you have within your [codenameone_settings.proper…](http://codenameone_settings.properties?) It looks like this isn’t passing through.\nDenis — May 13, 2018 at 6:38 am (permalink) Denis says:\nHi,\ncodename1.arg.android.buildToolsVersion=27 is there, so it looks correct as I understand, please confirm\nThanks\nShai Almog — May 14, 2018 at 4:25 am (permalink) Shai Almog says:\nHi,\nyes. But other build hints might collide with this functionality so are there other android.* build hints in the file?\nDenis — May 14, 2018 at 7:24 am (permalink) Denis says:\nHi Shai,\nyes, that makes, I don’t know why I haven’t post entire file right away ))\nhere it is, take a look please\nandroid.playService.ads=true\ncodename1.android.keystore=XXXXXXXXXXXXXXXXXXXXX\ncodename1.android.keystoreAlias=XXXXXXXXXXXXXXXX\ncodename1.android.keystorePassword=XXXXXXXXXXXXX\ncodename1.arg.android.buildToolsVersion=27\ncodename1.arg.android.debug=false\ncodename1.arg.android.licenseKey=XXXXXXXXXXXXXXX\ncodename1.arg.android.release=true\ncodename1.arg.android.statusbar_hidden=true\ncodename1.arg.android.xapplication=\ncodename1.arg.ios.add_libs=AdSupport.framework;SystemConfiguration.framework;CoreTelephony.framework\ncodename1.arg.ios.newStorageLocation=true\ncodename1.arg.ios.objC=true\ncodename1.arg.ios.pods=,Firebase/Core,Firebase/AdMob\ncodename1.arg.ios.pods.platform=,7.0\ncodename1.arg.ios.pods.sources=,https://[github.com/CocoaPods/Specs.git%5D(http://github.com/CocoaPods/Specs.git)\ncodename1.arg.ios.statusbar_hidden=true\ncodename1.arg.java.version=8\ncodename1.displayName=XXXXXXXXXXXXXXXXXXXXXXXXXX\ncodename1.icon=icon.png\ncodename1.ios.certificate=\ncodename1.ios.certificatePassword=\ncodename1.ios.provision=\ncodename1.j2me.nativeTheme=nativej2me.res\ncodename1.languageLevel=5\ncodename1.mainName=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX\ncodename1.packageName=com.manyukhin.XXXXXXXXXXXX\ncodename1.rim.certificatePassword=\ncodename1.rim.signtoolCsk=\ncodename1.rim.signtoolDb=\ncodename1.secondaryTitle=XXXXXXXXXXXXXXXXXXXXXXX\ncodename1.vendor=Denis Manyukhin\ncodename1.version=1.11\nShai Almog — May 15, 2018 at 4:08 am (permalink) Shai Almog says:\nThanks,\nit looks like you are missing codename1.arg. before the android.playService.ads but that’s unrelated.\nLooking again at the code I think you might need to explicitly specify android.sdkVersion=27 for this to work.\nDenis — May 15, 2018 at 4:25 am (permalink) Denis says:\nThanks Shai,\nSoo, I should put sdkVersion build hint in codenameone_settings.proper…, right ?\nalso it’s better to move android.playService.ads below Android build hints, is that correct ?\nShai Almog — May 15, 2018 at 4:48 am (permalink) Shai Almog says:\nIf you edit codenameone_settings.proper… you need to prefix it with codename1.arg. I suggest using the Codename One Setting UI under \u0026ldquo;Build Hints\u0026rdquo; to edit these and not edit the file directly.\nDenis — May 15, 2018 at 6:44 am (permalink) Denis says:\nI have added android.sdkVersion=27 to Build hints via corresponding UI, it appears as codename1.arg.android.sdkVersion=27 in codenameone_settings.proper…,\nbut still the same warning in Google Play Console, app targeted to API 23, any ideas ?\nalso I can’t see \u0026ldquo;android.playService.ads=true\u0026rdquo; in Build Hints UI, it only appears in codenameone_settings.proper…, is it ok ?\nDenis — May 15, 2018 at 9:20 pm (permalink) Denis says:\nhave you meant android.targetSDKVersion build hint ?\nif not, may be it worth to set android.targetSDKVersion value explicitly ?\nShai Almog — May 16, 2018 at 5:56 am (permalink) Shai Almog says:\nDoes targetSDKVersion solve this issue?\nThere is a bit of a mess of build hints here, we should clean it up a bit and ideally expose them in the Android section of Codename One Settings.\nOnly things with the codename1.arg. prefix will appear in the build hints UI so that flag is effectively ignored.\nDenis — May 16, 2018 at 6:16 am (permalink) Denis says:\nyes, android.targetSDKVersion solved the issue, no target API warnings, wondering if I shall keep android.sdkVersion and android.buildToolsVersion records in build hints\nShai Almog — May 17, 2018 at 11:05 am (permalink) Shai Almog says:\nWe’ll switch all of these to default to 27 probably next weekend. I want to give this enough time before we release 5.0 in July.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/android-build-target-27-migration/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/android-build-target-27-migration/android_studio.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA while back \u003ca href=\"https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGoogle announced\u003c/a\u003e that starting in August 2018 they will no longer accept applications targeting API levels below 26. With that in mind we plan to migrate our builds to use API level 27 which brings with it a lot of great new features but will probably break some things as we go through the migration. Please read this post carefully, I’ll try to cover everything.\u003c/p\u003e","title":"Android Build Target 27 Migration"},{"content":"\nA while back a question was asked on stack overflow How do you uninstall an extension using the CodenameOne Settings tool in NetBeans?\nUnfortunately this isn’t automatic due to the way cn1libs are implemented. In some cases you need to uninstall a cn1lib if you no longer need its functionality and this is far from seamless.\nThese are the steps you need to take:\nRemove the files with the name of the extension (the .cn1lib and the .ver file) from the lib directory – you can see them in the files tab in NetBeans or in the file explorer of your OS.\nOpen Codename One Settings → Build Hints \u0026amp; remove the ios.****\u0026amp; android. entries you didn’t add manually\nRight click project and select Codename One → Refresh Client Libs\nThis last step will recreate the ios.****andandroid. entries needed by other cn1libs you might have installed.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-uninstall-cn1lib/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-uninstall-cn1lib/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA while back a question was asked on stack overflow \u003ca href=\"https://stackoverflow.com/questions/46985038/how-do-you-uninstall-an-extension-using-the-codenameone-settings-tool-in-netbean\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHow do you uninstall an extension using the CodenameOne Settings tool in NetBeans?\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eUnfortunately this isn’t automatic due to the way cn1libs are implemented. In some cases you need to uninstall a cn1lib if you no longer need its functionality and this is far from seamless.\u003c/p\u003e\n\u003cp\u003eThese are the steps you need to take:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003eRemove the files with the name of the extension (the \u003ccode\u003e.cn1lib\u003c/code\u003e and the \u003ccode\u003e.ver\u003c/code\u003e file) from the \u003ccode\u003elib\u003c/code\u003e directory – you can see them in the files tab in NetBeans or in the file explorer of your OS.\u003c/p\u003e","title":"TIP: Uninstall cn1lib"},{"content":"\nWe are thrilled to announce the release of Codename One 4.0 – Taxi. Codename One is an open source \u0026ldquo;Write Once Run Anywhere\u0026rdquo; mobile solution for Java \u0026amp; Kotlin developers!\nThis new release overhauled the way Codename One is updated, added support for Progressive Web Apps (PWA’s), overhauled device skins \u0026amp; updated the backend iOS build tools. A major focus of this release is better support for peer (native) components, stability, unit testing and continuous integration.\nCodename One is the only platform that…​\nHas Write Once Run Anywhere with no special hardware requirements and 100% code reuse\nCompiles Java or Kotlin into native code for iOS, UWP (Universal Windows Platform), Android \u0026amp; even JavaScript\nIs Open Source \u0026amp; Free for commercial use with an enterprise grade commercial support\nIs Easy to use with 100% portable Drag \u0026amp; Drop GUI builder\nHas Full access to underlying native OS capabilities using the native OS programming language (e.g. Objective-C) without compromising portability\nHas full control over every pixel on the screen! Just override paint and draw or use a glass pane to draw anywhere…​\nLets you use native widgets (views) and mix them with Codename One components within the same hierarchy (heavyweight/lightweight mixing)\nSupports seamless Continuous Integration out of the box\nTo learn more about Codename One check out the about page you can download it for free right now.\nVersion 4.0 is nicknamed Taxi because of the Uber Clone application that was developed with it for the online course in the Codename One Academy.\nFigure 1. Uber sidemenu next to the clone\nFigure 2. The Uber login form next to the clone\nHighlights of this Release The top 5 features of this release are covered in this short video, check out further details below…​\nProgressive Web App Support (PWA) – Progressive Web Apps allow us to try an application on the web and seamlessly transition to a native app. This makes user acquisition easier and installation frictionless. Codename One is the only tool in the world that supports PWA’s seamlessly\nNew Device Skins – We updated the look of Codename One by releasing 33 new device skins including iPhone X \u0026amp; Pixel 2 XL. We included support for non-rectangular device skins and better device fidelity. We also added the ability to grab a screenshot that includes the skin frame around it\nXcode 9.2 – Codename One apps are built using xcode 9.2. This change is seamless for most developers as the update happened on the build servers. Xcode 9.2 requires additional permission messages which are added automatically by the simulator\nUpdate Framework – Updates to Codename One libraries are now delivered using a unified framework instead of separate adhoc tools\nContinuous Integration Support – We now support Travis CI out of the box seamlessly. Adding support for additional CI tools should be just as easy\nNew Async JavaScript Interop API – The Java → JavaScript bridge with the embeddable browser component was completely replaced. The new implementation should be faster than the old system\nBuiltin Unit Tests – Unit tests to Codename One are integrated into the core repository and are executed with every commit\nImproved Peer Components – Multiple bugs and minor issues were fixed in the peer component layer this effectively enabled the Uber clone to work properly with the native map\nBetter Hello World – The new Codename One projects generate better code that handles things such as network errors more effectively\nGUI Builder Refinements – There were many refinements to the new GUI builder most notably:\nImproved support for layout nesting in auto-layout mode – you can use all the existing layout managers within an autolayout parent\nNew Window Manager allows you to customize the positioning of the windows \u0026amp; palettes\nTabs component is supported again\nTest Push In the Simulator – The simulator now supports testing push notification\nThere are many other features both big and small. Check out our blog and the github project history.\nLowlights As we always do with a release we’d like to shine a spotlight on the things this version could do better and the things the next version can improve. Overall we are thrilled with this release but here are a few things we can do better:\nOn device debugging – I wasn’t optimistic about getting this out for 4.0 and I’m still not optimistic about 5.0. We already have a lot on our plate for 5.0 and this is a huge feature\nImproved default themes \u0026amp; material design – we did a lot of work on the skins but didn’t move the native theme or make a separate material design theme. We need to do a lot of work on the default hello world applications to make them look great out of the door.\nOverall while we implemented a lot of features in 4.0 we didn’t really address most of the problems we highlighted in this section when 3.8 was released. I’m not sure if we have enough time in the 5.0 cycle to improve that but hopefully we can at least move theming more aggressively again.\nOnwards to 5.0 – Social The 5.0 release cycle is relatively short \u0026amp; we already have a lot of things planned for it.\nWe should have the new social app tutorial in the Codename One Academy which will cover cloning Facebook.\nCheck out our survey results to see the future apps we’ll release into the academy. Even if you never plan to signup to the academy this should be interesting as it gives you a good notion of what can be built with Codename One.\nOther than that we’ll try to launch better docs and designs. We’ve put a lot of effort into improving our design capabilities and one of the big things we’d like to pick up again is app templates. In the past we released a few free themes as Codename One stubs. We’d like to do that again so developers can start from \u0026ldquo;something\u0026rdquo;.\nWe Need your Help If you think we are doing a good job and appreciate our help please help us by:\nSpreading the word\nEdit our docs\nEdit our sources and submit bug fixes\nOr just sign up for enterprise accounts which literally keep the lights on here…​ If your company can afford it please take the time and upgrade to enterprise, this will allow us to work on the things that are important for your company!\nThanks for reading this far and if you have any thoughts/suggestions of any kind please let us know! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDalvik — March 20, 2018 at 10:58 am (permalink) Congratulations, I hadn’t noticed half of these features as they went in 😉\nBluewater — March 22, 2018 at 6:05 am (permalink) Nice work! Were any of the deprecated APIs removed or is 4.0 fully backward compatible with 3x code?\nShai Almog — March 22, 2018 at 8:43 am (permalink) Shai Almog says:\nThanks!\nIt should be compatible. We didn’t remove any deprecated API’s but there are changes and some things can always break.\nRoss Taylor — March 31, 2018 at 10:31 am (permalink) Ross Taylor says:\nTowards around 1:57 – 59 of the video, I notice a slight flicker of the menu when displayed over the map. Is this a problem of the Google Map you were referring?\nShai Almog — April 1, 2018 at 4:07 am (permalink) Shai Almog says:\nThat’s related to the incoming animation. I used a background painter in one of the elements and I think I have an issue in that.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-4-0-taxi-live/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-4-0-taxi-live/codenameone-4-0-release-image-taxi.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are thrilled to announce the release of \u003ca href=\"https://www.codenameone.com/\"\u003eCodename One\u003c/a\u003e 4.0 – Taxi. Codename One is an open source \u0026ldquo;Write Once Run Anywhere\u0026rdquo; mobile solution for Java \u0026amp; Kotlin developers!\u003cbr\u003e\nThis new release overhauled the way Codename One is updated, added support for Progressive Web Apps (PWA’s), overhauled device skins \u0026amp; updated the backend iOS build tools. A major focus of this release is better support for peer (native) components, stability, unit testing and continuous integration.\u003c/p\u003e","title":"Codename One 4.0 \"Taxi\" is now Live"},{"content":"\nI already teased about the surprises I got from our annual survey results and there are still quite a few surprises but as more people filled out the survey some of the big surprises tamed and a lot of interesting results emerged. I also found the comments very interesting so I’ll go over the numbers/comments and provide my thoughts. If you think I misinterpreted the results please let me know…​\nWhich would you prefer for the \u0026ldquo;Social App\u0026rdquo; clone? In retrospect I think I made a mistake by not separating Snapchat \u0026amp; Instagram into the next question. But I’m not sure I’d want to create \u0026ldquo;another\u0026rdquo; social app too soon so placing them in the 2019 survey might be better:\nFigure 1. Which would you prefer for the \u0026ldquo;Social App\u0026rdquo; clone?\nFacebook is a clear winner here so the next app I’ll release would be a Facebook clone. Having said that there is clear interest in both ephemeral communication (snapchat) \u0026amp; in photo sharing/manipulation so I’ll try to discuss both of these to some degree. I’m not sure if they will make it into the current app though.\n__ I stripped out a few \u0026ldquo;no opinion\u0026rdquo; responses to make the results easier to read The Next App I divided the question of the next app into two, the #1 choice and the #2 choice. A lot of developers are focused on one thing so having two choices might help us get a better/wider sense of the things you are building.\nWhat’s your #1 Choice for the Next App? (After Facebook) Lets start with the data:\nFigure 2. What’s your #1 Choice for the next App?\nBefore I proceed one of the feedback comments brought my attention to the fact that I might have biased the poll by phrasing the question as \u0026ldquo;After the Facebook App\u0026rdquo;. I totally missed that. I’ll try to pay more attention next time!\nClearly whatsapp won. Initially this wasn’t the case. It was losing to AirBnB. After a while Netflix came from behind to grab the second place spot. Notice that there are a lot of people who specified other which means I missed a few important apps (I’ll get into that soon).\nBefore I go into the analysis I think it helps to see the second choice too…​\nWhat’s your #2 Choice for the Next App? Figure 3. What’s your #2 Choice for the next App?\nWhatsapp and Netflix pretty much tied here but AirBnb shrunk.\nAnalysis Before I go into analysis and comments I’d like to declare the winners!\nFacebook – The social app which won #2 place in last years survey will be a Facebook clone\nWhatsapp – The next app released in the summer should be a whatsapp clone\nNetflix – The app after that should be a Netflix clone\nAirBnB – Currently the AirBnB app is in the lead for 4th place but I might revisit that with a new survey\nUnsurprising Results There were quite a few things that seem obvious and made sense in the results. At least in retrospect.\nWhatsapp has always been a popular app and our old chat app tutorial is pretty old by now.\nAirBnB is one of the best looking apps out in the market, I’m sure people want to learn how to build something like that. It also rides the wave of the sharing economy which is a popular target.\nProtosketch got low votes. People don’t know it. Most of the drawing apps don’t enjoy mass market appeal. I added it because people have asked for a drawing app repeatedly, it’s something I’d like to build but it clearly doesn’t have enough commercial appeal.\nOne thing that didn’t exactly surprise me was the showing for a Mario game. It came in 4th which makes a lot of sense. Most of our developers aren’t game developers but there are a few.\nSurprising Results I was surprised by a lot of the results…​\nNetflix is big but I don’t see many Netflix clones or people trying to compete with Netflix. I think this mostly indicates interest in the video browsing/distribution process. I think it would have given similar results if I’d had youtube as an option. I think video streaming is an interesting app type so I’m excited to do something similar to Netflix.\nTinder probably surprised me the most but I was also relieved. To clone an app I need to use it and I doubt my spouse would accept an \u0026ldquo;I’m just cloning the app\u0026rdquo; excuse…​\nI honestly don’t know why this wasn’t a popular choice.\nSquare is also surprising. I’m personally familiar with at least two PoS vendors who use Codename One so I assumed there would be more interest in that. It’s possible that this is because square is so focused in the US market \u0026amp; unfamiliar outside of it. Or maybe it’s because of the hardware reader. I’m not sure.\nI would have expected Spotify to have a better showing. I’m guessing that most developers feel the music field is too competitive to enter at this time.\nComments \u0026amp; Suggestions I very much appreciate all the comments and suggestions that highlighted some omissions and also some things I should improve in our communication.\n__ Notice I cleaned up the comments a bit and unified them to make them more readable, if I missed a comment it might be by mistake! App Suggestions A common request was for business oriented apps:\nAppointment Setting App (e.g. for Doctors)\nBusiness oriented app (e.g. CRM mobile client)\nERP client\nI’d love to do one of those but these are harder to market and generalize. Each business is doing something different in their backend and it’s much harder to just make up something from scratch.\nIf there was a business app I can replicate or a backend ERP platform we can target that could be interesting but it’s very hard to teach/build something vague.\nOne of the things I did think about was an Intercom clone. It’s a CRM of sort. We use them for the website support and emails. I really don’t like that tool and would love to replace them. I just forgot to add it to the survey, although I don’t think it would have made an impact.\nOther suggestions included:\nFaceApp – Most of the app is in the face processing code, I think this would step outside of our comfort zone. Having said that there are some cool open source image recognition libraries that I’d love to integrate into Codename One given the time/user demand\nRuntastic/Fitbit – I totally missed those…​ They should have been on the list!\nSmart tv universal remote – I’m guessing these just use a communication protocol with the TV. I’m not sure what value we can bring here?\nAndroid Pay – I’m assuming this means Google Pay? I can’t install it on my device but PayPal might be an interesting option here. My bank also has a nice app but I’m not sure if it’s something that’s marketable\nUber clone – Someone actually asked for this…​ I guess I don’t send out enough emails…​\nComments I’ve removed a lot of the comments especially the positive ones. Thank you for them but I’m not sure those are interesting in this context…​\nOf the other comments I tried to moderate as little as possible. If people took the time to write something I’m guessing it’s unclear.\nCodenameone networking is not supporting real time updates. Would be nice if it did. I’m not sure I understand this comment.\nOur networking does support realtime updates via: WebSockets, Sockets, Long Polling \u0026amp; Push. Otherwise I wouldn’t have even suggested a whatsapp clone…​\nDo you mean something like socket.io or pubnub?\nWe have somewhat out of date support for the latter but not the former. If there is specific demand we can help with that.\nWhy social application? Because people voted on that last year and picked it.\nWe try to do what people ask for. I think that even if you build completely closed backend systems a lot of your UI and code would be influenced by the top apps in the market today (e.g. Uber, Facebook, whatsapp etc.) so even if you aren’t building a social app you can learn a lot by following a course on how it’s made.\nBluetooth \u0026amp; Hardware Integration \u0026ldquo;My proposal is Bluetooth BLe, Application for sensors and anything that can help normal people with real needs \u0026quot;\n\u0026ldquo;Apps with high hardware integration e.g. AR, Bluetooth or development boards for Embedded devices. \u0026quot;\nThose are great but also vague. I agree we need better demos for bluetooth support but We also need mass appeal. We need concrete targets that we can implement.\nOne of the huge problems with bluetooth is that the standard is so big and varied. One person sees bluetooth as file sharing, while another sees it as hardware monitoring and another as a data transfer tool. Add to that the need to get physical hardware that works with this and you end up with something most people will find hard to pick up.\nAI is becoming the in thing…​ any app that incorporates Artificial Intelligence I started my professional career working in AI so I’d love to do some more. But moving out of my personal space, the question is what can I teach and how can I help?\nI agree, I’d love to have builtin integration for things like tensorflow and other AI related API’s. I’m not sure if it’s something that should go into an app or just a small tutorial. I’d also love to integrate one of the image recognition libraries in the market.\nERP/CRM \u0026ldquo;Most of commercial software vendors work on business apps. Not social apps. So I would love to see something resembling CRM, ERP, HCM or anything similar \u0026quot;\nI tend to agree with that statement. The problem is that there is no real uniform standard we can target here in the app space. If you have more concrete suggestions for something we can build I’m open to it. The only thing that comes close to this is Intercom but I doubt it would have been popular in this survey.\nTo be fair I worked with a lot of businesses and they expect things to look like commercial apps. The app from my current bank looks like Facebook with a feed of \u0026ldquo;stories\u0026rdquo; that match my spending \u0026amp; stats from the bank. They even have a chat interface to a teller which should be close to whatsapp. It’s actually pretty nice.\nMy point is that business app developers would probably find more benefit from a tutorial on building facebook than one that’s too business specific. E.g. one could take the Uber app in a business and use it to manage their vehicle fleet.\nOffline Builds Let developers enjoy CN1 features! Offline Build server capabilities for free!\nThat’s a bit unrelated but I’d like to address that as there are several common misconceptions here.\nFirst is that offline building isn’t free. Offline building is free, the source for building Codename One is 100% open source and all the instructions are publically available. If you don’t want to make the effort to learn how to do it we have a course module that explains the steps one by one.\nThere is an enterprise grade offline build tool but the cost there is mostly support overhead.\nFurthermore, the build servers are free to use commercially with reasonable limits. Notice that the Uber app and all our demos fall within the free quota.\nThe second misconception is that this would be enjoyable. It’s a pain to build offline. E.g. from our enterprise customers who can build offline (as it’s included in their subscription) a very small percentage makes use of that feature. I can build offline and I don’t use that feature.\nIt’s painful and surprisingly slower than using the build servers even with our enterprise integration. Even when I want to debug in an IDE I generally prefer sending a build and downloading the source code than going through the offline builder. The only reason we added that feature was for government and other cloud averse entities.\nNow back to our regularly scheduled suggestions…​\nAny Online shopping App We already have the restaurant app which is a shopping app of a sort in the building course.\nLeading the Survey? \u0026ldquo;What’s your #1 Choice for the next App? (after the Facebook app)\u0026rdquo; is biased.. should be \u0026ldquo;What’s your #1 Choice for the next App? (after the social app)\u0026rdquo;\nDamn. You are right. I’ll try to be more careful with those subtle things next time. That was unintentional.\nKraken or some other crypto exchange I don’t use crypto currencies but adding something around them seems appealing. This specific app might be problematic as it’s very poorly rated with a mediocre UI. I’m open to suggestions around this field.\nTL;DR The winners of for the next apps we will build starting this summer are:\nFacebook\nWhatsapp\nNetflix\nAirBnB is a strong runner up but we’ll probably do a new survey to determine whether it should be the leader.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/survey-results-2018/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/survey-results-2018/codenameone-academy.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI already teased about the surprises I got from our annual survey results and there are still quite a few surprises but as more people filled out the survey some of the big surprises tamed and a lot of interesting results emerged. I also found the comments very interesting so I’ll go over the numbers/comments and provide my thoughts. If you think I misinterpreted the results please let me know…​\u003c/p\u003e","title":"Survey Results (2018) Upcoming Apps"},{"content":"\nCodename One 4.0 (Taxi) will launch next week, to keep the code stable we are entering a week long code freeze. Please update your plugin installs frequently and report bugs immediately so we will have a stable release!\nWe’ve added a lot of new features to 4.0 but the big things are pretty disruptive:\nXcode 9.2 switch\nUpdate Framework\nBecause both of these changes have many subtle implications we are relying on feedback from you on what’s working and what isn’t. If you run into any issue please file the issue ASAP so we can move quickly and update the release if necessary.\nDuring this week of code freeze we’ll try to update the documentation and prepare everything for the release.\nUpcoming Milestones This is our first release in the new numbering scheme and our first code named release.\nWe will branch to the 4.0 branch in our repository and every change to the branch will be cherry picked individually.\nHere are the coming releases after 4.0 (Taxi):\n5.0 (Social) – Scheduled for July 17th 2018\n6.0 (Name Pending) – Scheduled for November 14 2018\nYou can track these milestones and the related tasks in our github project here.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codefreeze-4-taxi/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codefreeze-4-taxi/codenameone-4-0-release-image-taxi.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One 4.0 (Taxi) will launch next week, to keep the code stable we are entering a week long code freeze. Please update your plugin installs frequently and report bugs immediately so we will have a stable release!\u003c/p\u003e\n\u003cp\u003eWe’ve added a lot of new features to 4.0 but the big things are pretty disruptive:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eXcode 9.2 switch\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eUpdate Framework\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eBecause both of these changes have many subtle implications we are relying on feedback from you on what’s working and what isn’t. If you run into any issue please \u003ca href=\"http://github.com/codenameone/CodenameOne/issues/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003efile the issue\u003c/a\u003e ASAP so we can move quickly and update the release if necessary.\u003c/p\u003e","title":"Codefreeze for Codename One 4.0 – Taxi"},{"content":"\n__ The information in this blog post is slighly out of date. Check out the newer blog post that covers positioning components on the map. A while back I introduced a MapLayout class as a tip and discussed the usage of this class. Since that introduction we ran into some scale issues as the layout misbehaved when a lot of elements were added to it. The crux of the issue is in the native map API which runs on the OS native thread and the Codename One API which needs immediate responses for layout.\nThese issues became very apparent in the Uber app clone code. As a solution we updated the layout to use an approach that’s asynchronous and fetches data in batches. This made the layout far more responsive.\nWhile we were there we also needed a way to align components to the position in the map e.g. a marker needs a center/bottom position while a car would be centered etc. So we added support for alignment as well which you can specify in the new API using:\nMapLayout.setHorizontalAlignment(myCmp, HALIGN.LEFT); MapLayout.setVerticalAlignment(myCmp, VALIGN.BOTTOM); This tool is still a bit of a cludge, ideally as we work with it in the future we’ll abstract it as a nice API into the map cn1lib. For now this is the revised version of the class:\npublic class MapLayout extends Layout implements MapListener { private static final String COORD_KEY = \u0026quot;$coord\u0026quot;; private static final String POINT_KEY = \u0026quot;$point\u0026quot;; private static final String HORIZONTAL_ALIGNMENT = \u0026quot;$align\u0026quot;; private static final String VERTICAL_ALIGNMENT = \u0026quot;$valign\u0026quot;; private final MapContainer map; private final Container actual; private boolean inUpdate; private Runnable nextUpdate; private int updateCounter; public static enum HALIGN { LEFT { int convert(int x, int width) { return x; } }, CENTER { int convert(int x, int width) { return x - width / 2; } }, RIGHT { int convert(int x, int width) { return x - width; } }; abstract int convert(int x, int width); } public static enum VALIGN { TOP { int convert(int y, int height) { return y; } }, MIDDLE { int convert(int y, int height) { return y + height / 2; } }, BOTTOM { int convert(int y, int height) { return y + height; } }; abstract int convert(int y, int height); } public MapLayout(MapContainer map, Container actual) { this.map = map; this.actual = actual; map.addMapListener(this); } @Override public void addLayoutComponent(Object value, Component comp, Container c) { comp.putClientProperty(COORD_KEY, (Coord) value); } @Override public boolean isConstraintTracking() { return true; } @Override public Object getComponentConstraint(Component comp) { return comp.getClientProperty(COORD_KEY); } @Override public boolean isOverlapSupported() { return true; } public static void setHorizontalAlignment(Component cmp, HALIGN a) { cmp.putClientProperty(HORIZONTAL_ALIGNMENT, a); } public static void setVerticalAlignment(Component cmp, VALIGN a) { cmp.putClientProperty(VERTICAL_ALIGNMENT, a); } @Override public void layoutContainer(Container parent) { int parentX = 0; int parentY = 0; for (Component current : parent) { Coord crd = (Coord) current.getClientProperty(COORD_KEY); Point p = (Point) current.getClientProperty(POINT_KEY); if (p == null) { p = map.getScreenCoordinate(crd); current.putClientProperty(POINT_KEY, p); } HALIGN h = (HALIGN)current.getClientProperty(HORIZONTAL_ALIGNMENT); if(h == null) { h = HALIGN.LEFT; } VALIGN v = (VALIGN)current.getClientProperty(VERTICAL_ALIGNMENT); if(v == null) { v = VALIGN.TOP; } current.setSize(current.getPreferredSize()); current.setX(h.convert(p.getX() - parentX, current.getWidth())); current.setY(v.convert(p.getY() - parentY, current.getHeight())); } } @Override public Dimension getPreferredSize(Container parent) { return new Dimension(100, 100); } @Override public void mapPositionUpdated(Component source, int zoom, Coord center) { Runnable r = new Runnable() { public void run() { inUpdate = true; try { List\u0026lt;Coord\u0026gt; coords = new ArrayList\u0026lt;\u0026gt;(); List\u0026lt;Component\u0026gt; cmps = new ArrayList\u0026lt;\u0026gt;(); int len = actual.getComponentCount(); for (Component current : actual) { Coord crd = (Coord) current.getClientProperty(COORD_KEY); coords.add(crd); cmps.add(current); } int startingUpdateCounter = ++updateCounter; List\u0026lt;Point\u0026gt; points = map.getScreenCoordinates(coords); if (startingUpdateCounter != updateCounter || len != points.size()) { // Another update must have run while we were waiting for the bounding box. // in which case, that update would be more recent than this one. return; } for (int i=0; i\u0026lt;len; i++) { Component current = cmps.get(i); Point p = points.get(i); current.putClientProperty(POINT_KEY, p); } actual.setShouldCalcPreferredSize(true); actual.revalidate(); if (nextUpdate != null) { Runnable nex = nextUpdate; nextUpdate = null; callSerially(nex); } } finally { inUpdate = false; } } }; if (inUpdate) { nextUpdate = r; } else { nextUpdate = null; callSerially(r); } } } Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/map-layout-update/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/map-layout-update/build-real-world-full-stack-mobile-apps-in-java.jpg\"\u003e\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eThe information in this blog post is slighly out of date. Check out the \u003ca href=\"/blog/map-component-positioning-revisited.html\"\u003enewer blog post\u003c/a\u003e that covers positioning components on the map.\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eA while back I \u003ca href=\"/blog/tip-map-layout-manager.html\"\u003eintroduced a MapLayout class\u003c/a\u003e as a tip and discussed the usage of this class. Since that introduction we ran into some scale issues as the layout misbehaved when a lot of elements were added to it. The crux of the issue is in the native map API which runs on the OS native thread and the Codename One API which needs immediate responses for layout.\u003c/p\u003e","title":"Map Layout Update"},{"content":"\nThis is new behavior that went in without fanfare. If you created a new hello world app you might have noticed this. We changed the default boilerplate for Codename One and made it more representative of what you’d want to see in a hello world app.\nThe entire change to the default generated app is within the init method:\npublic void init(Object context) { // use two network threads instead of one updateNetworkThreadCount(2); __**(1)** theme = UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;); // Enable Toolbar on all Forms by default Toolbar.setGlobalToolbar(true); // Pro only feature Log.bindCrashProtection(true); addNetworkErrorListener(err -\u0026gt; { __**(2)** // prevent the event from propagating err.consume(); if(err.getError() != null) { Log.e(err.getError()); } Log.sendLogAsync(); Dialog.show(\u0026quot;Connection Error\u0026quot;, \u0026quot;There was a networking error in the connection to \u0026quot; + err.getConnectionRequest().getUrl(), \u0026quot;OK\u0026quot;, null); }); } __1 By default networking in Codename One runs on one network thread for consistency. Two threads make more sense from a performance standpoint. We wanted to make this easily configurable and it should be easy in the init() method __2 Handling network errors in a generic way is probably one of the hardest things to grasp. So many developers are still stuck with the default error handling code…​ With that in mind we added a bit of boilerplate to handle network errors in a way that makes sense and should be easily customizable I had some thoughts about removing this boilerplate and packaging it in a class. But then I thought again.\nI Like Boilerplate It’s simple\nIt’s obvious\nYou can instantly find what you want\nThis isn’t code for the sake of code or declaration. The code is still concise and does what we expect. This is one of those cases where boilerplate makes more sense.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-default-code/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-default-code/new-features-5.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is new behavior that went in without fanfare. If you created a new hello world app you might have noticed this. We changed the default boilerplate for Codename One and made it more representative of what you’d want to see in a hello world app.\u003c/p\u003e\n\u003cp\u003eThe entire change to the default generated app is within the init method:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003epublic void init(Object context) {\n    // use two network threads instead of one\n    updateNetworkThreadCount(2); __**(1)**\n\n    theme = UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;);\n\n    // Enable Toolbar on all Forms by default\n    Toolbar.setGlobalToolbar(true);\n\n    // Pro only feature\n    Log.bindCrashProtection(true);\n\n    addNetworkErrorListener(err -\u0026gt; { __**(2)**\n        // prevent the event from propagating\n        err.consume();\n        if(err.getError() != null) {\n            Log.e(err.getError());\n        }\n        Log.sendLogAsync();\n        Dialog.show(\u0026quot;Connection Error\u0026quot;, \u0026quot;There was a networking error in the connection to \u0026quot; + err.getConnectionRequest().getUrl(), \u0026quot;OK\u0026quot;, null);\n    });\n}\n\u003c/code\u003e\u003c/pre\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003cstrong\u003e1\u003c/strong\u003e\u003c/th\u003e\n          \u003cth\u003eBy default networking in Codename One runs on one network thread for consistency. Two threads make more sense from a performance standpoint. We wanted to make this easily configurable and it should be easy in the \u003ccode\u003einit()\u003c/code\u003e method\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e__\u003cstrong\u003e2\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eHandling network errors in a generic way is probably one of the hardest things to grasp. So many developers are still stuck with the default error handling code…​ With that in mind we added a bit of boilerplate to handle network errors in a way that makes sense and should be easily customizable\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eI had some thoughts about removing this boilerplate and packaging it in a class. But then I thought again.\u003c/p\u003e","title":"New Default Code"},{"content":"\nI covered the include source feature extensively. For the most part it’s the simplest way to debug an application directly on the device. When I made that video the current version of Android Studio and Gradle were much older. We still use API version 23 on the build servers to keep everything compatible but you might want to use a newer version of the IDE.\nIn that case you can use the newer version 3.0+ of Android Studio but you will need to make a few updates to the process.\n__ Notice that this is a temporary thing as eventually we’ll update the build servers to emit newer target versions too as features \u0026amp; devices proliferate Automatic Update One of the features in Android Studio is its ability to automatically update the project. You should use that feature to update gradle to the latest version and the SDK version as well. I’ve tested version 26 and it seems to work fine but I haven’t done any stress testing and wouldn’t recommend it other than for debugging purposes.\n__ If you submit an APK to Google play with a newer SDK version they will no longer accept an older version of the same APK! Once the automatic update is done you will need to update a few files and settings.\ngradle.properties In this file you just need to add the line:\nandroid.enableAapt2=false This will fix issues with styles later on.\nStyle Files There are 3 style files named styles.xml under the directories: res/values, res/values-v11 \u0026amp; res/values-v21.\nThey appear in the IDE as one file with 3 versions. The default versions from our servers include some @ characters in the wrong place that Google doesn’t play nicely with. Since they are auto-generated they are badly formatted and hard to fix manually. So here are the full versions of all 3 files that you can paste on top of the existing files.\nres/values/styles.xml :\n\u0026lt;?xml version=\u0026quot;1.0\u0026quot; encoding=\u0026quot;utf-8\u0026quot;?\u0026gt; \u0026lt;resources\u0026gt; \u0026lt;style name=\u0026quot;CustomTheme\u0026quot; parent=\u0026quot;android:Theme.Black\u0026quot;\u0026gt; \u0026lt;item name=\u0026quot;attr/cn1Style\u0026quot;\u0026gt;@style/CN1.EditText.Style\u0026lt;/item\u0026gt; \u0026lt;/style\u0026gt; \u0026lt;attr name=\u0026quot;cn1Style\u0026quot; format=\u0026quot;reference\u0026quot; /\u0026gt; \u0026lt;style name=\u0026quot;CN1.EditText.Style\u0026quot; parent=\u0026quot;@android:style/Widget.EditText\u0026quot;\u0026gt; \u0026lt;item name=\u0026quot;android:textCursorDrawable\u0026quot;\u0026gt;@null\u0026lt;/item\u0026gt; \u0026lt;/style\u0026gt; \u0026lt;/resources\u0026gt; res/values-v11/styles.xml :\n\u0026lt;?xml version=\u0026quot;1.0\u0026quot; encoding=\u0026quot;utf-8\u0026quot;?\u0026gt; \u0026lt;resources\u0026gt; \u0026lt;style name=\u0026quot;CustomTheme\u0026quot; parent=\u0026quot;@android:style/Theme.Holo.Light\u0026quot;\u0026gt; \u0026lt;item name=\u0026quot;attr/cn1Style\u0026quot;\u0026gt;@style/CN1.EditText.Style\u0026lt;/item\u0026gt; \u0026lt;item name=\u0026quot;android:windowActionBar\u0026quot;\u0026gt;false\u0026lt;/item\u0026gt; \u0026lt;item name=\u0026quot;android:windowTitleSize\u0026quot;\u0026gt;0dp\u0026lt;/item\u0026gt; \u0026lt;/style\u0026gt; \u0026lt;style name=\u0026quot;CN1.EditText.Style\u0026quot; parent=\u0026quot;@android:style/Widget.EditText\u0026quot;\u0026gt; \u0026lt;item name=\u0026quot;android:textCursorDrawable\u0026quot;\u0026gt;@null\u0026lt;/item\u0026gt; \u0026lt;/style\u0026gt; \u0026lt;/resources\u0026gt; res/values-v21/styles.xml :\n\u0026lt;?xml version=\u0026quot;1.0\u0026quot; encoding=\u0026quot;utf-8\u0026quot;?\u0026gt; \u0026lt;resources\u0026gt; \u0026lt;style name=\u0026quot;CustomTheme\u0026quot; parent=\u0026quot;@android:style/Theme.Material.Light\u0026quot;\u0026gt; \u0026lt;item name=\u0026quot;attr/cn1Style\u0026quot;\u0026gt;@style/CN1.EditText.Style\u0026lt;/item\u0026gt; \u0026lt;item name=\u0026quot;android:windowActionBar\u0026quot;\u0026gt;false\u0026lt;/item\u0026gt; \u0026lt;item name=\u0026quot;android:windowTitleSize\u0026quot;\u0026gt;0dp\u0026lt;/item\u0026gt; \u0026lt;item name=\u0026quot;android:colorPrimary\u0026quot;\u0026gt;@color/colorPrimary\u0026lt;/item\u0026gt; \u0026lt;item name=\u0026quot;android:colorPrimaryDark\u0026quot;\u0026gt;@color/colorPrimaryDark\u0026lt;/item\u0026gt; \u0026lt;item name=\u0026quot;android:colorAccent\u0026quot;\u0026gt;@color/colorAccent\u0026lt;/item\u0026gt; \u0026lt;/style\u0026gt; \u0026lt;style name=\u0026quot;CN1.EditText.Style\u0026quot; parent=\u0026quot;@android:style/Widget.EditText\u0026quot;\u0026gt; \u0026lt;item name=\u0026quot;android:textCursorDrawable\u0026quot;\u0026gt;@null\u0026lt;/item\u0026gt; \u0026lt;/style\u0026gt; \u0026lt;/resources\u0026gt; Finally All of this should work and run with Android Studio 3.0. Ideally this blog post will be unnecessary by the time you read it as we’d move forward to align with the current approach from Google.\nI’m not sure when we’ll upgrade from 23 as it’s a relatively good target version, to a large degree it depends on feedback from you.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-include-source-android-studio-3/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-include-source-android-studio-3/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI covered the \u003ca href=\"/how-do-i---use-the-include-sources-feature-to-debug-the-native-code-on-iosandroid-etc/\"\u003einclude source feature\u003c/a\u003e extensively. For the most part it’s the simplest way to debug an application directly on the device. When I made that video the current version of Android Studio and Gradle were much older. We still use API version 23 on the build servers to keep everything compatible but you might want to use a newer version of the IDE.\u003c/p\u003e\n\u003cp\u003eIn that case you can use the newer version 3.0+ of Android Studio but you will need to make a few updates to the process.\u003c/p\u003e","title":"TIP: Include Source with Android Studio 3.0"},{"content":"\nLast week I mentioned we are considering postponing the release planned for next week. We eventually did just that and the release is now scheduled for the 20th with code freeze on the 13th. So far we didn’t change future release dates but there might be a cascading effect. As I explained before, this is an inevitable result of the migration to xcode 9.2 which is something we need to stabilize before the release.\nWe already have a lot of big features in the release so the big pieces are already there.\nRelease Code Names With the switch to major release numbers we decided to name the releases. We thought about silly names similar to the spirit of Android, RedHat etc.\nThen it occurred to us that with the Uber Clone application we essentially proved a use case of a taxi app built with Codename One. It’s not a feature that you can list in the \u0026ldquo;new features\u0026rdquo; section but it’s an important highlight…​ Since we will be releasing additional applications to the academy as we go it makes sense to tie them into the release versions.\nWith that in mind Codename One 4.0 is nicknamed – Taxi.\nCodename One 5.0 is tentatively nicknamed – Social.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/updated-4-release-date/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/updated-4-release-date/codenameone-4-0-release-image-taxi.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eLast week I mentioned we are considering postponing the release planned for next week. We eventually did just that and the release is now scheduled for the 20th with code freeze on the 13th. So far we didn’t change future release dates but there might be a cascading effect. As I explained before, this is an inevitable result of the migration to xcode 9.2 which is something we need to stabilize before the release.\u003c/p\u003e","title":"Updated 4.0 Release Date"},{"content":"\nI promised 2 new course modules for February and just published the second one. In case you don’t recall I discussed the first one here and it covered building Codename One applications from the open source code.\nThis new module goes through seven lessons that cover everything you need to know when building a performant app. It covers everything from generic performance tips/analysis all the way to profiling and a case study. You can check out the full module in the Deep Dive into Mobile Programming course in the academy.\n__ The deep dive course is bundled into the full Build real world full stack mobile apps course for free! Together with the offline build course I added 2 hours of additional material this month alone.\nThis opens the question of where do we go from here?\nI’m still weighing some ideas for the module I’ll release in March. I would also like you to help me pick the following apps after that…​\nWith that in mind I’m publishing a new survey which I would hope you can help me with here.\nThis will help me create new content that better suits the apps you are trying to build.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tune-performance-profile-on-devices/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tune-performance-profile-on-devices/deep-dive-into-mobile.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI promised 2 new course modules for February and just published the second one. In case you don’t recall I discussed the first one \u003ca href=\"/blog/use-open-source-build-offline/\"\u003ehere\u003c/a\u003e and it covered building Codename One applications from the open source code.\u003cbr\u003e\nThis new module goes through seven lessons that cover everything you need to know when building a performant app. It covers everything from generic performance tips/analysis all the way to profiling and a case study. You can check out the full module in the \u003ca href=\"https://codenameone.teachable.com/p/deep-dive-into-mobile-development-with-codename-one\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDeep Dive into Mobile Programming\u003c/a\u003e course in the academy.\u003c/p\u003e","title":"Tune Performance, Profile on Devices in Latest Academy Update"},{"content":"\nWe got a pull request the other day that reminded me of some hidden functionality in Codename One that most developers aren’t aware of: observable input streams. By default Codename One API’s try to return BufferedInputStream and BufferedOutputStream instances from our internal API’s. Those classes aren’t the typical java.io versions but rather ones from the com.codename1.io package.\nThat API allows us to add functionality into the streams without breaking the Java compatibility or specs. One such feature is setProgressListener(IOProgressListener). This is probably better explained with a simple sample:\nfinal Status status = ToastBar.getInstance().createStatus(); __**(1)** status.setMessage(\u0026quot;Reading file\u0026quot;); status.setShowProgressIndicator(true); status.showDelayed(300); BufferedInputStream bi; __**(2)** if(inputStream instanceof BufferedInputStream) { bi = (BufferedInputStream)inputStream; } else { bi = new BufferedInputStream(inputStream); } bi.setProgressListener((source, bytes) -\u0026gt; { __**(3)** callSerially(() -\u0026gt; status.setProgress(100 * bytes / streamLength)); __**(4)** }); __1 The toastbar has a special mode that lets us display progress from 0 to 100 __2 Since streams would often already be observable the instanceof should be true for a few cases. In the exception this fallback would be reasonable __3 Notice that the progress listener carries an overhead and might slow your application. This might not be a big deal for some cases __4 The value is between 0 and 100 so we need to know the stream length in advance for the toastbar API Finally There are quite a few API’s in Codename One that are hidden under the surface. From our vantage point it’s often hard to remember everything that’s there even if we put it there. It’s worth asking us as some things can be hidden from view. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChibuike Mba — March 1, 2018 at 8:48 pm (permalink) Chibuike Mba says:\nHi Shai, this week I came across a Java library for bringing Reactive Programming into Java called RxJava [https://github.com/Reactive…] as I was researching on the topic because I needed the programming pattern in CodenameOne project am working on.\nAfter seeing the library’s capabilities and benefits I became interested in it and have been wondering on how to port/extend it into CodenameOne, Android has an extension already called RxAndroid [https://github.com/Reactive…].\nCan you guide me on the best way about bringing the RxJava library into CodenameOne?\nShai Almog — March 2, 2018 at 4:50 am (permalink) Shai Almog says:\nHi,\nI looked at this a while back and thought it would be interesting too. It should be pretty easy to port the standard project to Codename One and wrap it in a cn1lib. It uses a couple of features we don’t support such as atomic values etc. but those should be relatively simple to implement locally to get it working.\nThe main reason I didn’t port it is that I consider it to be of relatively limited benefit in Codename One. Android has a lot of synchronous IO code that should be serialized. This makes a lot of sense there.\nCodename One already handles a lot of these things thanks to NetworkManager albeit not as \u0026ldquo;elegantly\u0026rdquo; in some cases. So I just didn’t see this as a personal priority but if you need help I’ll be happy to help with that.\nChibuike Mba — March 2, 2018 at 6:53 am (permalink) Chibuike Mba says:\nThanks for your response. I will really need your help. I want to combine reactive programming with MVVM pattern to mimic something like android fragment in codenameone where your app can behave differently based on device screen size and orientation. For example, on mobile phone you have a list of properties displayed on a form, clicking an item opens another form and displays the property details. But on desktop version of the same app or on tablet landscape orientation one form splits into vertical panels, one panel holds the properties listing while another panel displays selected property details. The app’s screen splits into panels on one device and multiple forms on another device. Using reactivity and mvvm patterns will make this use case easier to accomplish with much cleaner code.\nWhat do you think, does codenameone have a way of doing this kind of thing already which i may not know of? Can this patterns benefit codenameone, being write once run anywhere platform?\nShai Almog — March 3, 2018 at 9:39 am (permalink) Shai Almog says:\nFragments are one of the most hated features in Android developer community so I’m not sure why you would want something like that?\nWe did somethings like this in the kitchen sink which looks very different on phones/tablets and just did that with a simple isTablet() call. I think a lot of engineers overthink these problems trying to over generalize something that’s easily solvable with an if statement and a couple of methods.\nThe orientation listener also allows you to create special cases for specific issues. In the latest version of the kitchen sink I removed that code but I didn’t commit it to git yet so you can check it out here: https://github.com/codename…\nI just re-arrange the test fields etc. based on orientation and based on whether this is a tablet or desktop.\nI think Android is a combination of low level hacks that expose way too much of the implementation details combined with nose bleed high level of abstraction. Both are horrible for developers but both are really hard to remove from Android due to the legacy and binary compatibility requirements.\nChibuike Mba — March 5, 2018 at 2:48 pm (permalink) Chibuike Mba says:\nHi Shai, my aim is not to implement Fragments in Codename One but to utilize device screen sizes as you have point me in the right direction with the Kitchen sink demo link.\nFor the RxJava, I still need its reactivity and will start the porting process. When ever I encounter challenges I will seek for you assistance.\nThanks.\nChibuike Mba — March 7, 2018 at 5:55 pm (permalink) Chibuike Mba says:\nHi Shai, am on the process of porting RxJava into Codename One by wrapping it into .cn1lib but there is an issue: RxJava has a dependency on this package java.util.concurrent which seem not available on Codename One.\nQuestions:\nIs it legal to copy the missing package source code from openjdk-8 project?\nWill there be any conflict in Codename One if java.util.concurrent or other packages are copied into the .cn1lib?\nCan I have private conversations with you through email or is this place acceptable to you? as I work on the porting process.\nLooking forward for your reply.\nShai Almog — March 8, 2018 at 6:26 am (permalink) Shai Almog says:\nHi,\nhere would be good and so would the discussion forum etc. I like keeping these things in public forums so they are searchable by google if someone is interested in this subject in the future.\nAssuming you are setting up a public github fork you can also assign me to an issue and discuss it with me there.\nYou can define java.util.concurrent classes that are missing although personally I would just rename the dependencies to the RxJava package space to avoid potential conflict.\nI can’t comment on the legal implications as this is a touchy subject with Oracle. I would generally prefer the Android source over OpenJDK but in this case I’m not sure if this will be a good idea to begin with.\nThis specific package is implemented with very low VM specific behaviors that might make things even more complicated. Since there are very few API dependencies into the package I would just build a clean room implementation of that API in pure Java which should be relatively trivial.\nSuch a clean room port might be a worthwhile contribution to Codename One’s core for people looking to port similar code. If you need some guidance or review to a specific class just point it to me in github and I’ll try helping with this.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-streams-observable/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-streams-observable/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe got a \u003ca href=\"https://github.com/codenameone/CodenameOne/pull/2336\" target=\"_blank\" rel=\"noopener noreferrer\"\u003epull request\u003c/a\u003e the other day that reminded me of some hidden functionality in Codename One that most developers aren’t aware of: observable input streams. By default Codename One API’s try to return \u003ca href=\"/javadoc/com/codename1/io/BufferedInputStream/\"\u003eBufferedInputStream\u003c/a\u003e and \u003ca href=\"/javadoc/com/codename1/io/BufferedOutputStream/\"\u003eBufferedOutputStream\u003c/a\u003e instances from our internal API’s. Those classes aren’t the typical \u003ccode\u003ejava.io\u003c/code\u003e versions but rather ones from the \u003ccode\u003ecom.codename1.io\u003c/code\u003e package.\u003c/p\u003e\n\u003cp\u003eThat API allows us to add functionality into the streams without breaking the Java compatibility or specs. One such feature is \u003ca href=\"/javadoc/com/codename1/io/BufferedInputStream/#setProgressListener-com.codename1.io.IOProgressListener-\"\u003esetProgressListener(IOProgressListener)\u003c/a\u003e. This is probably better explained with a simple sample:\u003c/p\u003e","title":"TIP: Streams are Observable in Codename One"},{"content":"\nI added support for binding a property object to Preferences a while back and just didn’t have the time to blog about it. I didn’t consider it too crucial as the functionality is very simple to figure out, the only difficult part is knowledge of the features existence.\nSome objects make sense as global objects, we can just use the Preferences API to store that data directly but then we don’t have the type safety that property objects bring to the table. That’s where the binding of property objects to preferences makes sense. E.g. say we have a global Settings property object we can just bind it to preferences using:\nPreferencesObject.create(settingsInstance).bind(); So if settings has a property called companyName it would bind into Preferences under the Settings.companyName entry.\nWe can do some more elaborate bindings such as:\nPreferencesObject.create(settingsInstance). setPrefix(\u0026quot;MySettings-\u0026quot;). setName(settingsInstance.companyName, \u0026quot;company\u0026quot;). bind(); This would customize all entry keys to start with MySettings- instead of Settings.. This would also set the company name entry to company so in this case instead of Settings.companyName we’d have MySettings-company.\ngetAndSet A part of getting this to work seamlessly is the getAndSet API added to the Preferences API. This is a bit of a weird API but it’s pretty useful so lets explain it by example.\nSay we have a user setting for refresh as an integer in minutes:\nint refresh = Preferences.get(\u0026quot;refresh\u0026quot;, 60); That will return the refresh value as 60 if it doesn’t exist. The problem is: \u0026ldquo;how do we know we got back the default?\u0026rdquo;.\nNormally that isn’t a big deal but if we have one path that invokes Preferences.get(\u0026quot;refresh\u0026quot;, 60) and another one that does a Preferences.get(\u0026quot;refresh\u0026quot;, 100); how can we tell which one is correct?\nI could use Preferences.get(\u0026quot;refresh\u0026quot;, 60); and if 60 is returned I can invoke set to explicitly set the 60 value just to make sure that 60 will be used from now on. But that would mean changing preferences with every invocation even if the data didn’t change.\ngetAndSet() essentially solves that problem. You get the data one and if the default is used that default is then stored into the Preferences so you can’t get inconsistent results for a specific entry.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/preferences-binding-getandset/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/preferences-binding-getandset/new-features-4.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI added support for binding a property object to \u003ccode\u003ePreferences\u003c/code\u003e a while back and just didn’t have the time to blog about it. I didn’t consider it too crucial as the functionality is very simple to figure out, the only difficult part is knowledge of the features existence.\u003c/p\u003e\n\u003cp\u003eSome objects make sense as global objects, we can just use the \u003ccode\u003ePreferences\u003c/code\u003e API to store that data directly but then we don’t have the type safety that property objects bring to the table. That’s where the binding of property objects to preferences makes sense. E.g. say we have a global \u003ccode\u003eSettings\u003c/code\u003e property object we can just bind it to preferences using:\u003c/p\u003e","title":"Preferences Binding and getAndSet()"},{"content":"\nI promised 2 new course modules for February and just published the first one. It covers the process of building a Codename One app from the Codename One source code. The whole process is done without using the Codename One plugin or build servers. It uses only open source project code to deliver iOS/Android \u0026amp; desktop binaries!\nYou can check out the full module in the Deep Dive into Mobile Programming course in the academy.\n__ The deep dive course is bundled into the full Build real world full stack mobile apps course for free! Working with the Codename One sources is not for the faint of heart. You can learn a lot from going through the process. However, if your only goal is to avoid the build servers you might find it harder to work with.\nIn fact I personally use the build servers when building apps and testing them. I almost never use offline build or the sources directly. Instead I hack and test things via the include source options. However, learning this is still valuable and I’m aware of a few people who don’t share my opinion on this matter…​\nStill, why would I create a guide for something like this?\nThere are 3 types of individuals I can think of who might benefit from this guide:\nIf you are the type of person who needs to do everything yourself then this is pretty much it\nIf you want to understand the underpinning of Codename One at a deeper level than the more abstract descriptions. Then this is a good first step\nIf you want to feel secure that you can hack Codename One manually if our service changes or becomes unavailable in the future then the mere existence of this guide should help calm some of those concerns\nTo me the third option makes a lot of sense. I think that the existence of this module is probably the biggest value it delivers.\nPerformance Next week I will post a module covering performance tuning, tips and pitfalls. I already wrote a lot of material for this module which is shaping up as an even bigger module. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nTommy Mogaka — February 23, 2018 at 5:31 am (permalink) Tommy Mogaka says:\nHi Shai,\nThanks for making this provision available. It is a brave move and it demonstrates confidence in cn1. I personally am happy to know that the option is available but I still continue to use the build servers but I know of some users who are a bit fastidious when it comes to security requirements. An example is banks. For the purposes of such clients, does the module also include the push messaging servers?\nBest Regards!\nShai Almog — February 24, 2018 at 4:54 am (permalink) Shai Almog says:\nThanks!\nNo the module stops after running on the native IDE’s. The assumption is that if you got that far implementing native push directly won’t be a big challenge. You won’t be able to use our push servers without a subscription obviously so you’d need to write your own push code.\nCosmicDan — August 5, 2018 at 12:50 am (permalink) CosmicDan says:\nWas excited to hear this, but then disappointed to hear it’s behind a $200 payment. It’s a bit of a steep entry requirement for an open-source developer who just wants to look for options on Android and Windows Desktop app development without financially committing to one particular system for experimentation. But I understand, Codename One is a business after all.\nShai Almog — August 5, 2018 at 4:54 am (permalink) Shai Almog says:\nAll the material is available for free, this module just pools it into one location. Using the source code won’t make your life easier in building. You can use the build servers for free which is far easier.\nCosmicDan — August 5, 2018 at 5:04 am (permalink) CosmicDan says:\nApologies, I misread the plan pricing thinking that I couldn’t make desktop apps with the free or cheaper tier. What that seems to be is just native desktop apps, which I don’t have an interest in after all – I am hoping that the CN1 UWP target UI can scale well to larger displays (tablets/laptops).\nShai Almog — August 6, 2018 at 4:20 am (permalink) Shai Almog says:\nNotice that you can build everything including that. There are instructions in the group and it’s pretty obvious how to do it from the code. In terms of license you are allowed to do everything, we have no licensing restrictions unlike some other tools…\nThere is one port whose code isn’t open source and that’s the JavaScript port.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/use-open-source-build-offline/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/use-open-source-build-offline/deep-dive-into-mobile.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI promised 2 new course modules for February and just published the first one. It covers the process of building a Codename One app from the Codename One source code. The whole process is done \u003cstrong\u003ewithout using the Codename One plugin or build servers\u003c/strong\u003e. It uses only open source project code to deliver iOS/Android \u0026amp; desktop binaries!\u003cbr\u003e\nYou can check out the full module in the \u003ca href=\"https://codenameone.teachable.com/p/deep-dive-into-mobile-development-with-codename-one\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDeep Dive into Mobile Programming\u003c/a\u003e course in the academy.\u003c/p\u003e","title":"Use our Open Source Code to Build Codename One Offline"},{"content":"\nA few weeks ago I announced the xcode 9.2 mode and was rather happy that we can take our time with the migration. Unfortunately, that wasn’t meant to be. Apple will require all new submissions to use xcode 9 within the next few months so it makes no sense to keep 7.3 as the default. This weekend we will flip the switch and builds will default to 9.2.\nIt’s earlier than we wanted to but it’s crucial that Codename One 4.0 will work well with xcode 9.2 otherwise developers won’t be able to use versioned build halfway through the 4.0 cycle.\nAs a reminder if you want to still use xcode 7.3 because you are concerned that this change broke something in your code just add the build hint:\nios.xcode_version=7.3\nTo test xcode 9.2 before the update this weekend just use the build hint:\nios.xcode_version=9.2\nFor the most part the change should be seamless at this time. I would suggest that you read the original article where I discuss the refined permissions that are now a part of xcode 9. If you run into issues please check that they happen in 9 and not in 7 and file issues immediately!\nMultitasking Flag To support multi-tasking in iPads where we can have a side by side view of the UI we need to use a xib launch file. Unfortunately we just couldn’t nail this correctly for all the use cases so we had to keep the existing screenshot code in place for now.\n__ Regular iOS multitasking will still work as usual this refers only to the iPad split screen support If you are willing to compromise on some edge case odd behavior for the launch image in exchange for side by side view you can turn this on explicitly by using the ios.multitasking=true build hint. Hopefully we’ll be able to refine the xib behavior and turn this on by default for 5.0.\nPlugin Update \u0026amp; Release Delay With the update of the libs this weekend we’ll add a strong nag to people who haven’t updated their plugins. We need to deploy the new update framework as it allows us to solve some problems in very elegant ways.\nIf you haven’t updated your IDE plugin please do so soon.\nWe are considering delaying the release that is planned for March 6th by a week or even two. This would give us more time to test these two big changes: update framework \u0026amp; the 9.2 migration. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nStefan Eder — February 20, 2018 at 2:04 pm (permalink) Stefan Eder says:\nDoes that mean one could use Swift code, too?\nShai Almog — February 21, 2018 at 5:25 am (permalink) Shai Almog says:\nNot directly.\nThe problem is ARC, Swift requires it but it collides with our GC.\nYou can use swift in a static library and invoke it from a native interface wrapper.\nStefan Eder — February 21, 2018 at 6:20 am (permalink) Stefan Eder says:\nIt would be nice to have an example on how to do this\nShai Almog — February 22, 2018 at 8:41 am (permalink) Shai Almog says:\nDoing this is not intuitive and most of the sample would be in xcode so would step too deep out of the comfort zone. It won’t produce any benefit either in simplicity, maintainability or performance. If you have a large library of swift code you can use it this way but if you have a large library of swift code you probably know how to do it to begin with an don’t need our help…\nStefan Eder — February 23, 2018 at 6:49 am (permalink) Stefan Eder says:\nI know your attitude but that does not help me further. I tried to use Codename One several years and paid for it – and eventually abandoned.\nIn an ideal situation I’d love to support Codename One by providing solutions for everyone but the world is not ideal and my situation is not either.\nI have about four hours a week for Codename One and yet I can not accept that some things just do not work. Of course it would help if, in exceptional cases and only for me, I could make additions and corrections. Preventing that from happening prevents me from using Codename One – that’s how easy it is.\nShai Almog — February 24, 2018 at 4:59 am (permalink) Shai Almog says:\nAs I said before, I’m sorry about that. But there are some things we won’t do even for paying customers. Every cross platform tool has its limitations. You want our tool to be both easy and use the build servers. That’s not possible. It’s a Pandoras box that we won’t open.\nThat has nothing to do with Swift support which is a technical issue related to ARC.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/xcode-9-on-by-default/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/xcode-9-on-by-default/xcode-migration.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA few weeks ago I announced the \u003ca href=\"/blog/xcode-9-mode.html\"\u003excode 9.2 mode\u003c/a\u003e and was rather happy that we can take our time with the migration. Unfortunately, that wasn’t meant to be. Apple will require all new submissions to use xcode 9 within the next few months so it makes no sense to keep 7.3 as the default. This weekend we will flip the switch and builds will default to 9.2.\u003c/p\u003e\n\u003cp\u003eIt’s earlier than we wanted to but it’s crucial that Codename One 4.0 will work well with xcode 9.2 otherwise developers won’t be able to use versioned build halfway through the 4.0 cycle.\u003c/p\u003e","title":"Xcode 9.2 on by Default this Friday"},{"content":"\nWhen it comes to big changes this is pretty huge but surprisingly \u0026ldquo;subtle\u0026rdquo;. This weekend we’ll release a new plugin update that will completely replace the update process of Codename One and a week after that we will start nagging you to update your plugin so we can all be on the same page. This is a HUGE change as we didn’t change anything about the update process since 2012. But the cool thing about it is that you might not notice it…​\nWhen we launched Codename One in 2012 we needed a way to ship updates and fixes faster than the plugin update system. So we built the client lib update system. Then we needed a way to update the designer tool (resource editor), the GUI builder \u0026amp; the skins…​ We also needed a system to update the builtin builder code (CodeNameOneBuildClient.jar so we built a tool for that too).\n__ Notice the uppercase N in CodeNameOneBuildClient.jar. It’s so old even we weren’t sure how to write our own company name correctly…​ Update Framework A big piece of the change is the removal of code within the IDE plugins that tries to do the update for us. Once we remove that code the new Update Framework can effectively fetch up to date versions of the important jars and make sure everything is at the latest. It solves several problems in the old systems:\nDownload once – if you have multiple projects the library will only download once to the .codenameone directory. All the projects will update from local storage\nSkins update automatically – this is hugely important. When we change a theme we need to update it in the skins and if you don’t update the skin you might see a difference between the simulator and the device\nUpdate of settings/designer without IDE plugin update – The IDE plugin update process is slow and tedious. This way we can push out a bug fix for the GUI builder without going through the process of releasing a new plugin version\nFor the most part this framework should be seamless. You should no longer see the \u0026ldquo;downloading\u0026rdquo; message whenever we push an update after your build client is updated. Your system would just poll for a new version daily and update when new updates are available.\nYou can also use the usual method of Codename One Settings → Basic → Update Client Libs which will force an update check. Notice that the UI will look a bit different after this update.\nHow does it Work? You can see the full code here the gist of it is very simple. We create a jar called UpdateCodenameOne.jar under ~/.codenameone (~ represents the users home directory).\nAn update happens by running this tool with a path to a Codename One project e.g.:\njava -jar ~/.codenameone/UpdateCodenameOne.jar path_to_my_codenameone_project E.g.:\njava -jar ~/.codenameone/UpdateCodenameOne.jar ~/dev/AccordionDemo Checking: JavaSE.jar Checking: CodeNameOneBuildClient.jar Checking: CLDC11.jar Checking: CodenameOne.jar Checking: CodenameOne_SRC.jar Checking: designer_1.jar Checking: guibuilder_1.jar Updating the file: /Users/shai/dev/AccordionDemo/JavaSE.jar Updating the file: /Users/shai/dev/AccordionDemo/CodeNameOneBuildClient.jar Updating the file: /Users/shai/dev/AccordionDemo/lib/CLDC11.jar Updating the file: /Users/shai/dev/AccordionDemo/lib/CodenameOne.jar Updated project files Notice that no download happened since the files were up to date. You can also force a check against the server by adding the force argument as such:\njava -jar ~/.codenameone/UpdateCodenameOne.jar path_to_my_codenameone_project The way this works under the hood is thought a Versions.properties within your directory that lists the versions of local files. That way we know what should be updated.\n__ Exclude Versions.properties from Git Under the ~/.codenameone directory we have a more detailed UpdateStatus.properties file that includes versions of the locally downloaded files. Notice you can delete this file and it will be recreated as all the jars get downloaded over again.\nWhat isn’t Covered You will notice 3 big things that aren’t covered in this unified framework:\nWe don’t update cn1libs – I’m not sure if this is something we would like to update automatically\nVersioned builds – there is a lot of complexity in the versioned build system. This might be something we address in the future but for now I wanted to keep the framework simple.\nOffline builds – Offline builds work through manual download and aren’t subjected to this framework\nFinally I don’t expect a big change like this to go well without a hitch. So please accept our apologies for everything that probably will go wrong over the next couple of weeks as we tune this system. Once it will be in place we will deliver fixes and updates faster.\nWe won’t need to deal with as many IDE specific behaviors and we will be able to update the system itself moving forward. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — February 18, 2018 at 11:46 am (permalink) Francesco Galgani says:\nHow do I know when a new update is released?\nFor example, yesterday you published an update and this morning you\npublished another: do I have to check manually the available updates every day or is there a\nway to automate this checking?\nShai Almog — February 19, 2018 at 5:57 am (permalink) Shai Almog says:\nYou don’t know an update is released.\nWhen a build is made in the IDE we run the update tool and it checks for you. It does this check once a day unless it’s running in \u0026ldquo;force\u0026rdquo; mode which happens when you do an update client libs. Normally, this should be seamless.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-update-framework/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-update-framework/new-features-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen it comes to big changes this is pretty huge but surprisingly \u0026ldquo;subtle\u0026rdquo;. This weekend we’ll release a new plugin update that will completely replace the update process of Codename One and a week after that we will start nagging you to update your plugin so we can all be on the same page. This is a HUGE change as we didn’t change anything about the update process since 2012. But the cool thing about it is that you might not notice it…​\u003c/p\u003e","title":"New Update Framework"},{"content":"\nWe recently introduced a new API for interacting with Javascript in Codename One. This new API is part of the BrowserComponent class, and effectively replaces the com.codename1.javascript package, which is now deprecated.\nSo what was wrong with the old API? The old API provided a synchronous wrapper around an inherently asynchronous process, and made extensive use of invokeAndBlock() underneath the covers. This resulted in a very nice API with high-level abstractions that played nicely with a synchronous programming model, but it came with a price-tag in terms of performance, complexity, and predictability. Let’s take a simple example, getting a reference to the \u0026ldquo;window\u0026rdquo; object:\nJSObject window = ctx.get(\u0026quot;window\u0026quot;); This code looks harmless enough, but this is actually quite expensive. It issues a command to the BrowserComponent, and uses invokeAndBlock() to wait for the command to go through and send back a response. invokeAndBlock() is a magical tool that allows you to \u0026ldquo;block\u0026rdquo; without blocking the EDT, but it has its costs, and shouldn’t be overused. Most of the Codename One APIs that use invokeAndBlock() indicate this in their name. E.g. Component.animateLayoutAndWait(). This gives you the expectation that this call could take some time, and helps to alert you to the underlying cost.\nThe problem with the ctx.get(\u0026quot;window\u0026quot;) call is that it looks the same as a call to Map.get(key). There’s no indication that this call is expensive and could take time. One call like this probably isn’t a big deal, but it doesn’t take long before you have dozens or even hundreds of calls like this littered throughout your codebase, and they can be hard to pick out.\nThe New API The new API fully embraces the asynchronous nature of Javascript. It uses callbacks instead of return values, and provides convenience wrappers with the appropriate \u0026ldquo;AndWait()\u0026rdquo; naming convention to allow for synchronous usage. Let’s look at a simple example:\n__ In all of the sample code below, you can assume that variables named bc represent an instance of BrowserComponent. bc.execute( \u0026quot;callback.onSuccess(3+4)\u0026quot;, res -\u0026gt; Log.p(\u0026quot;The result was \u0026quot;+res.getInt()) ); This code should output \u0026ldquo;The result was 7\u0026rdquo; to the console. It is fully asynchronous, so you can include this code anywhere without worrying about it \u0026ldquo;bogging down\u0026rdquo; your code. The full signature of this form of the execute() method is:\npublic void execute(String js, SuccessCallback\u0026lt;JSRef\u0026gt; callback) The first parameter is just a javascript expression. This javascript MUST call either callback.onSuccess(result) or callback.onError(message, errCode) at some point in order for your callback to be called.\nThe second parameter is your callback that is executed from the javascript side, when callback.onSuccess(res) is called. The callback takes a single parameter of type JSRef which is a generic wrapper around a javascript variable. JSRef has accessors to retrieve the value as some of the primitive types. E.g. getBoolean(), getDouble(), getInt(), toString(), and it provides some introspection via the getType() method.\n__ It is worth noting that the callback method can only take a single parameter. If you need to pass multiple parameters, you may consider including them in a single string which you parse in your callback. Synchronous Wrappers As mentioned above, the new API also provides an executeAndWait() wrapper for execute() that will work synchronously. It, as its name suggests, uses invokeAndBlock under the hood so as not to block the EDT while it is waiting.\nE.g.\nJSRef res = bc.executeAndWait(\u0026quot;callback.onSuccess(3+4)\u0026quot;); Log.p(\u0026quot;The result was \u0026quot;+res.Int()); Prints \u0026ldquo;The result was 7\u0026rdquo;.\n__ When using the andWait() variant, it is extremely important that your Javascript calls your callback method at some point – otherwise it will block indefinitely. We provide variants of executeAndWait() that include a timeout in case you want to hedge against this possibility. Multi-use Callbacks The callbacks you pass to execute() and executeAndWait() are single-use callbacks. You can’t, for example, store the callback variable on the javascript side for later use (e.g. to respond to a button click event). If you need a \u0026ldquo;multi-use\u0026rdquo; callback, you should use the addJSCallback() method instead. Its usage looks identical to execute(), the only difference is that the callback will life on after its first use. E.g. Consider the following code:\nbc.execute( \u0026quot;$('#somebutton').click(function(){callback.onSuccess('Button was clicked')})\u0026quot;, res -\u0026gt; Log.p(res.toString()) ); The above example, assumes that jQuery is loaded in the webpage that we are interacting with, and we are adding a click handler to a button with ID \u0026ldquo;somebutton\u0026rdquo;. The click handler calls our callback.\nIf you run this example, the first time the button is clicked, you’ll see \u0026ldquo;Button was clicked\u0026rdquo; printed to the console as expected. However, the 2nd time, you’ll just get an exception. This is because the callback passed to execute() is only single-use.\nWe need to modify this code to use the addJSCallback() method as follows:\nbc.addJSCallback( \u0026quot;$('#somebutton').click(function(){callback.onSuccess('Button was clicked')})\u0026quot;, res -\u0026gt; Log.p(res.toString()) ); Now it will work no matter how many times the button is clicked.\nPassing Parameters to Javascript In many cases, the javascript expressions that you execute will include parameters from your java code. Properly escaping these parameters is tricky at worst, and annoying at best. E.g. If you’re passing a string, you need to make sure that it escapes quotes and new lines properly or it will cause the javascript to have a syntax error. Luckily we provide variants of execute() and addJSCallback() that allow you to pass your parameters and have them automatically escaped.\nFor example, suppose we want to pass a string with text to set in a textarea within the webpage. We can do something like:\nbc.execute( \u0026quot;jQuery('#bio').text(${0}); jQuery('#age').text(${1})\u0026quot;, new Object[]{ \u0026quot;A multi-linen string with \u0026quot;quotes\u0026quot;\u0026quot;, 27 } ); The gist is that you embed placeholders in the javascript expression that are replaced by the corresponding entry in an array of parameters. The ${0} placeholder is replaced by the first item in the parameters array, the ${1} placeholder is replaced by the 2nd, and so on.\nProxy Objects The new API also includes a JSProxy class that encapsulates a Javascript object simplify the getting and setting of properties on Javascript objects – and the calling of their methods. It provides essentially three core methods, along with several variants of each to allow for async or synchronous usages, parameters, and timeouts.\nE.g. We might want to create a proxy for the window.location object so that we can access its properties more easily from Java.\nJSProxy location = bc.createJSProxy(\u0026quot;window.location\u0026quot;); Then we can retrieve its properties using the get() method:\nlocation.get(\u0026quot;href\u0026quot;, res -\u0026gt; Log.p(\u0026quot;location.href=\u0026quot;+res)); Or synchronously:\nJSRef href = location.getAndWait(\u0026quot;href\u0026quot;); Log.p(\u0026quot;location.href=\u0026quot;+href); We can also set its properties:\nlocation.set(\u0026quot;href\u0026quot;, \u0026quot;http://www.google.com\u0026quot;); And call its methods:\nlocation.call(\u0026quot;replace\u0026quot;, new Object[]{\u0026quot;http://www.google.com\u0026quot;}, res -\u0026gt; Log.p(\u0026quot;Return value was \u0026quot;+res) ); Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nRWang — February 18, 2018 at 2:41 pm (permalink) RWang says:\nWith the recent update and deprecation of the com.codename1.javascript package (specifically the JSFunction and JSObject classes), I’d like to know if there are any way to represent a JavaScript Object or functions? For example when I’d like to use the [JSProxy.call](http://JSProxy.call)(…) with a js function as argument, using a String representation doesn’t work as of now, so are there any alternatives?\nshannah78 — February 19, 2018 at 1:38 pm (permalink) shannah78 says:\nI have just added support for this in Git. https://github.com/codename…\nThis will be available in next server update on Friday.\nJust wrap the Javascript literal expression in a JSExpression object. E.g.\n[myProxy.call](http://myProxy.call)(\u0026ldquo;myMethod\u0026rdquo;, new Object[]{\u0026ldquo;a string\u0026rdquo;, new JSExpression(\u0026ldquo;a.javascript.expression()\u0026rdquo;)}, res-\u0026gt;{…})\nZombieLover — March 14, 2018 at 4:35 pm (permalink) ZombieLover says:\nLove this thanks Steve\nZombieLover — March 15, 2018 at 9:09 am (permalink) ZombieLover says:\nFor anyone trying to run a jquery script using addJSCallback you may have to do it after the document has loaded. Otherwise you might be running it before jQuery has been loaded. Example:\nbrowser.addWebEventListener(\u0026#34;onLoad\u0026#34;, new ActionListener() { public void actionPerformed(ActionEvent evt) { browser.addJSCallback( \u0026#34;$(\u0026#39;#someId\u0026#39;).click(function(){callback.onSuccess(\u0026#39;Button was clicked\u0026#39;)})\u0026#34;, res -\u0026gt; System.out.print(res.toString()) ); } }); Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-async-java-javascript-interop-api/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-async-java-javascript-interop-api/html5-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe recently introduced a new API for interacting with Javascript in Codename One. This new API is part of the \u003ca href=\"/javadoc/com/codename1/ui/BrowserComponent/\"\u003eBrowserComponent\u003c/a\u003e class, and effectively replaces the \u003ca href=\"/javadoc/com/codename1/javascript/package-summary/\"\u003ecom.codename1.javascript package\u003c/a\u003e, which is now deprecated.\u003c/p\u003e\n\u003ch2 id=\"so-what-was-wrong-with-the-old-api\"\u003eSo what was wrong with the old API?\u003c/h2\u003e\n\u003cp\u003eThe old API provided a synchronous wrapper around an inherently asynchronous process, and made extensive use of \u003ca href=\"/javadoc/com/codename1/ui/Display/#invokeAndBlock-java.lang.Runnable-\"\u003einvokeAndBlock()\u003c/a\u003e underneath the covers. This resulted in a very nice API with high-level abstractions that played nicely with a synchronous programming model, but it came with a price-tag in terms of performance, complexity, and predictability. Let’s take a simple example, getting a reference to the \u0026ldquo;window\u0026rdquo; object:\u003c/p\u003e","title":"New Async Java-Javascript Interop API"},{"content":"\nOne of the big issues with some new users who picked up Codename One was the lack of up to date device skins. We made several attempts in the past to improve this situation but these ended up as half measures at best. Last week we addressed some of the core problems that made it hard to add new skins and as a result we now have 33 new skins that are far better than anything we had before.\nSpecifically:\nGooglePixel\nGooglePixel2\nGooglePixel2XL\nHTCOneA9\nHTCOneM8\nHuaweiP8\nMicrosoftLumia950\nMotoE\nMotoG\nNexus4\nNexus5X\nNexus6P\nSamsungGalaxyGrandPrime\nSamsungGalaxyNote5\nSamsungGalaxyS3\nSamsungGalaxyS5\nSamsungGalaxyS7\nSamsungGalaxyS8\niPhone5c\niPhone5s\niPhone6s\niPhone6sPlus\niPhone7\niPhone7Plus\niPhone8\niPhone8Plus\niPhoneX\nMicrosoftSurface3\nMicrosoftSurfacePro4\nNexus9\niPadAir2\niPadMini4\niPadPro\nYou will notice some pretty cool skins in that list and unlike before we got a lot of things right. As part of this update we also added the ability to take a screenshot with the skin which looks pretty cool…​\nYou will also notice in this list of skins the Google Pixel XL 2 and iPhone X. These skins show a non-rectangular portion of the screen which was previously problematic.\nFigure 1. iPhone X non-rectangular skin and screenshot that includes said skin\nWhy did it Take so Long? Besides the obvious amount of work we needed to do to get here there were also several problems we had to resolve.\nThe most obvious one was a good source for skin images. This is important as a lot of mockups on the Internet get some things wrong e.g. pixels off in the area of the screen etc. Once that was in place we made a few changes that made the whole process of skinning far easier.\nStatus Bar When we launched Codename One all operating systems had a status bar on the top of the display. This doesn’t sound like a big deal but it was a HUGE pain. It was technically part of the screen but separate because you could take a screenshot with or without the status bar for different use cases.\nHowever, in recent years modern phone UI views the status bar as part of the applications screen real-estate and so it no longer makes sense to have it in the skin. So the new skins ignore that aspect. This keeps them more consistent with the way modern phone OS’s behave.\nPPI – Pixels Per Inch Up until now when you defined a skin file you had to provide a numeric value that indicated the ratio of pixels per millimeter. It wasn’t hard to calculate that value but it was tedious and unintuitive…​\nHowever, almost every device has a well known PPI value that represents its density. Calculating the pixel ratio from the PPI value is pretty easy. So you can now use the ppi key when defining a new skin like I did here in the iPhone X skin properties.\nOddly Shaped Skins The iPhone X skin isn’t just rounded. It has a notch on top that hides a portion of the UI. The Pixel 2 XL skin also includes rounded corners which also obstruct a portion of the screen. That was very challenging.\nThese skins required a fix to some paint bugs that triggered flickering. But they also needed a bigger conceptual fix.\nUp until now we just used a system that marked the area of the screen using black pixels. That worked well and removed the need to measure pixels accurately. However, this wouldn’t work with an oddly shaped screen as the API wouldn’t know how to answer getDisplayHeight() for an iPhone X device. We toyed briefly with the idea of writing some complex heuristics for calculating that but eventually decided this wasn’t a good idea…​\nInstead we added the following fields to the skin.properties file:\nroundScreen=true displayWidth=1125 displayHeight=2436 displayX=85 displayY=77 When roundSkin is turned on we check these following variables to pick up the square coordinates of the screen then draw the skin on top of them. Notice that the screen is always square regardless of the shape of the phone.\nSan Francisco Font In iOS 9 Apple transitioned from the Helvetica Neue font to the San Francisco font. Both look very similar and I for one can’t tell them apart to save my life. But it’s important to keep up so we decided to switch the font as well.\nHowever, unlike previous iterations of the font Apple made the font names somewhat obtuse and inconsistent. So the only way to load the font is by using low level API’s that fetch the default OS font.\nAs a result when our native system asks for Helvetica Neue instead of loading that we get the system default font which will be Helvetica Neue on older OS’s and San Francisco on newer OS’s. That also means that font changes in future iOS updates should be reflected automatically from now on.\nOne caveat is italic which still uses the Helvetica Neue font. The syntax for getting weighted italic fonts was problematic so we left it as it is today.\nHidden Status Bar on Android One of the reasons I gave for the new skins lack of status bar is the trend OS’s have taken to hide the status bar from view. Since iOS 7 developers were expected to deliver an app that runs under the status bar. Our solution for that was including a bit of default padding on the top of the Form in iOS to push the content down.\nAndroid still has a status bar and most apps still use it, you can customize the colors of the Android status bar using the colors.xml as explained here. However, up until now we didn’t support hidden status bars.\nWe just introduced the build hint android.hideStatusBar which you can set to true. This will make the status bar seem transparent which will allow a more consistent UX with your iOS version.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-skins-san-francisco-font/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-skins-san-francisco-font/pixel-perfect.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the big issues with some new users who picked up Codename One was the lack of up to date device skins. We made several attempts in the past to improve this situation but these ended up as half measures at best. Last week we addressed some of the core problems that made it hard to add new skins and as a result we now have 33 new skins that are far better than anything we had before.\u003c/p\u003e","title":"New Skins, San Francisco Font and more"},{"content":"\nI really like the newer Rest API’s Chen added a while back. They are ultimately far more convenient than the ConnectionRequest API’s for most day to day development. In fact I used them almost exclusively in the Uber clone app. As a result of that I added a few useful enhancements and capabilities.\nIf you are not familiar with the API it works roughly like this:\nMap\u0026lt;String, Object\u0026gt; jsonData = Rest. get(myUrl). acceptJson(). getAsJsonMap(); This will request using an HTTP GET method from the url. It will set the accepts header to JSON and parse the response.\nContent Type An important ommission was the content type setting, you could use the header() value to achieve that but content type is an important header and deserves its own method:\nMap\u0026lt;String, Object\u0026gt; jsonData = Rest. post(myUrl). contentType(\u0026quot;application/json\u0026quot;). body(bodyContentAsJSON). acceptJson(). getAsJsonMap(); In this case we submit JSON data in a post request with the application/json content type.\njsonContent Notice that there is duplicate data in the sample above where both acceptJson and the contentType effectively communicate the same idea of using JSON for the protocol (albeit the two sides of the protocol). Since this is a common case it can use the shorthand:\nMap\u0026lt;String, Object\u0026gt; jsonData = Rest. post(myUrl). jsonContent(). body(bodyContentAsJSON). getAsJsonMap(); Asynchronous Callbacks We always had asynchronous callbacks in the API but in the past they were delivered via the interface Callback which has 2 methods. That means we couldn’t leverage the shorthand lambda notation when implementing simple requests. We added two new permutations to the method and removed the Async suffix for them to avoid potential collision.\nE.g. in the past I would have had to write something like this:\nMap\u0026lt;String, Object\u0026gt; jsonData = Rest. post(myUrl). jsonContent(). body(bodyContentAsJSON). getAsJsonMapAsync(new Callback\u0026lt;Response\u0026lt;String\u0026gt;\u0026gt;() { @Override public void onSucess(Response\u0026lt;String\u0026gt; value) { // code here... } @Override public void onError(Object sender, Throwable err, int errorCode, String errorMessage) { // code here... } }); We can now use a terse approach like this:\nMap\u0026lt;String, Object\u0026gt; jsonData = Rest. post(myUrl). jsonContent(). body(bodyContentAsJSON). getAsJsonMap(value -\u0026gt; { // code here... }); You will notice I somewhat glazed over the error handling which will go to the global error handler in this case. You can avoid that by overriding the error handler separately in the second argument to this method (which is optional). Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChibuike Mba — February 10, 2018 at 5:13 pm (permalink) Chibuike Mba says:\nNice one Shai.\nCan I parse the server response directly to my custom object instead of Map. Or do I have to retrieve the data from the Map object and then iterate to populate my own custom objects?\nHave been using my CustomConnectionRequest object to achieve my aim though, but the API code above looks more concise.\nShai Almog — February 11, 2018 at 7:30 am (permalink) Shai Almog says:\nThanks!\nNot directly. We have a get version that returns a byte array so the data will be read into a byte array and you would be able to parse it after.\nMohamed Selim — May 1, 2018 at 2:11 am (permalink) Mohamed Selim says:\nHello Mr Shai,\nI’m a student and i’m working in project, could help me please i didn’t found the link of API Message Codename One and i didn’t know how to put web service \u0026ldquo;reponses by JSON\u0026rdquo; to use it in the form at my application in Codename One? Best Regards.\nShai Almog — May 1, 2018 at 4:29 am (permalink) Shai Almog says:\nHi,\nYou can search the JavaDoc for any API you can’t find https://www.codenameone.com…\nJSON is returned as a Java Map object in this API, you can just use the Map API to get JSON values. You can stop with a debugger and inspect the object to see what’s in it.\nMohamed Selim — May 1, 2018 at 1:20 pm (permalink) Mohamed Selim says:\nThank you sir, i didn’t know to use the webservice \u0026ldquo;CRUD\u0026rdquo; values from symfony to put it in CodenameOne is there any document have a good exemple for it?\nShai Almog — May 2, 2018 at 2:28 pm (permalink) Shai Almog says:\nSorry I’ve never worked with PHP so I have no experience with that and can’t really help. However, Steve wrote about xatafaces and CRUD operations to mysql here: https://www.codenameone.com…\nTafadzwa Moyo — February 27, 2019 at 12:01 pm (permalink) Tafadzwa Moyo says:\nam getting an authentication error 401 after implementing the code below. Where am i getting it wrong\nMap\u0026lt;string, object=\u0026quot;\u0026quot;\u0026gt; shiftTimes = (Map\u0026lt;string, object=\u0026quot;\u0026quot;\u0026gt;) Rest.get(new UrlManager().getShiftTimes()) .basicAuth(urlManager.getAuthname(), manager.getVerifyDriverCode() + id) .acceptJson().getAsJsonMap().getResponseData();\nShai Almog — February 28, 2019 at 3:25 am (permalink) Shai Almog says:\nThat means the web site didn’t accept your basic auth challenge or didn’t allow you to access that particular page. You can use the network monitor which sometimes provides insight into the error message and also into what didn’t work in the request.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-rest-calls/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-rest-calls/new-features-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI really like the \u003ca href=\"/blog/terse-rest-api.html\"\u003enewer Rest API’s\u003c/a\u003e Chen added a while back. They are ultimately far more convenient than the \u003ccode\u003eConnectionRequest\u003c/code\u003e API’s for most day to day development. In fact I used them almost exclusively in the \u003ca href=\"https://codenameone.teachable.com/p/build-real-world-full-stack-mobile-apps-in-java\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eUber clone app\u003c/a\u003e. As a result of that I added a few useful enhancements and capabilities.\u003c/p\u003e\n\u003cp\u003eIf you are not familiar with the API it works roughly like this:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eMap\u0026lt;String, Object\u0026gt; jsonData = Rest.\n            get(myUrl).\n            acceptJson().\n            getAsJsonMap();\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis will request using an HTTP GET method from the url. It will set the accepts header to JSON and parse the response.\u003c/p\u003e","title":"New Rest Calls"},{"content":"\nDevice only bugs are the worse. You need to go through a device build and reproduce/rinse/repeat. Thankfully these bugs are rare but sometimes they just hit you smack in the face. One such problem occurred when I was debugging a transition on Android related to a login form. I would move between a Form where I had the keyboard open to one where it was closed. This created a nasty effect where the keyboard folded leaving a black space and the transition played out about that black space.\nOn the simulator this won’t happen, we can’t realistically simulate the virtual keyboard.\nIt won’t happen on iOS either. Only on Android.\nThe Android port resizes the display during input and that behavior triggers this end result where the display doesn’t have time to recover before the transition starts.\nInitially I thought I can workaround this by invoking:\ntextField.stopEditing(); callSerially(() -\u0026gt; showOtherForm()); But that only helped on some cases, not all. Even the fact that I used callSerially didn’t help as this depends on a native event going through.\nThe solution is to use the new stopEditing(Runnable) API. On most OS’s the runnable will be invoked immediately but on Android it will wait for the screen resize before it invokes the code. So this will work as you would expect:\ntextField.stopEditing(() -\u0026gt; showOtherForm()); Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\n3lix — February 7, 2018 at 2:41 am (permalink) 3lix says:\nSeeking an advice: should on each form I have TextFields, check to see which TextField, if any, has focus calling the hasFocus function and then when navigating to the next form make sure we had stopped editing ?\nShai Almog — February 7, 2018 at 5:04 am (permalink) Shai Almog says:\nI would suggest avoiding that unless you actually see a problem during transition. Normally transitions work but in some special cases this is obvious. In this specific case I had a morph transition from a form with a keyboard to one without.\nNormally if you are transitioning using other transitions or to a form where editing is still open this would work as you would have expected.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-stop-editing/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-stop-editing/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eDevice only bugs are the worse. You need to go through a device build and reproduce/rinse/repeat. Thankfully these bugs are rare but sometimes they just hit you smack in the face. One such problem occurred when I was debugging a transition on Android related to a login form. I would move between a Form where I had the keyboard open to one where it was closed. This created a nasty effect where the keyboard folded leaving a black space and the transition played out about that black space.\u003c/p\u003e","title":"TIP: Stop Editing"},{"content":"\nEvery time we switch a version of xcode in the build servers things go haywire because of minor behavioral changes from Apple. Over the holidays we started a long and painful migration to xcode 9.2 which required an update to the Mac OS versions on our servers. Thankfully this wasn’t as bad as the old xcode 5 to 7.3 migration where the old build code literally stopped working…​\nThis makes things FAR easier, but the migration itself still didn’t work on first try due to changes in the signing process. Over the past week we were able to address those final issues and xcode 9.2 builds are now functional!\n__ Building for xcode 9.2 is still experimental at this time so be sure to test and submit issues! Toggling the Xcode Versions You can toggle the xcode 9.2 build by using the build hint:\nios.xcode_version=9.2\nThe default currently maps to 7.3 but at some point in the future we will probably flip the default. If at that point you would want to try the old version you could use the reverse:\nios.xcode_version=7.3\nNotice that we will make a clear announcement about flipping the default xcode version.\nThings to Notice Currently the splash screen seems problematic. We are working on resolving that.\nPush and local notifications might experience issues when running on xcode 9.2 as there were some changes related to those API’s.\nPermissions iOS has tightened the requirements around API access permissions and now expects description entries for every problematic API. E.g. if your app uses the camera, Apple expects you to include a description explaining why you need camera access.\nThe same holds true for other API’s.\nWhen our simulator encounters usage of those API’s it automatically adds the appropriate build hint containing default description text. This will help you get a build through but you might need to customize that text before submission to Apple.\nCommon permission descriptions you will need are: ios.NSCameraUsageDescription, ios.NSContactsUsageDescription, ios.NSLocationAlwaysUsageDescription, NSLocationUsageDescription, ios.NSMicrophoneUsageDescription, ios.NSPhotoLibraryAddUsageDescription, ios.NSSpeechRecognitionUsageDescription, ios.NSSiriUsageDescription.\nYou will notice they all follow the convention ios.NSXXXUsageDescription. The XXX portion maps to the way Apple represents this permission in the plist file. You can see the full list from Apple here.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/xcode-9-mode/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/xcode-9-mode/xcode-migration.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eEvery time we switch a version of xcode in the build servers things go haywire because of minor behavioral changes from Apple. Over the holidays we started a long and painful migration to xcode 9.2 which required an update to the Mac OS versions on our servers. Thankfully this wasn’t as bad as the old xcode 5 to 7.3 migration where the old build code literally stopped working…​\u003c/p\u003e","title":"Xcode 9.2 Mode"},{"content":"\nPWAs (Progressive Web Apps) are an extremely hot topic right now, and Codename One apps are very well suited to being deployed this way. In case you haven’t been following the PWA buzz, the idea is that it’s a web app that behaves like a native app. When they are first loaded in a user’s browser, they behave like a normal responsive web app, but users can install them to their home screen just like native apps. At which point, they can behave as \u0026ldquo;offline-first\u0026rdquo; apps. Parts of this have been available for quite some time, but the concept of PWA brings a lot of little things under a single umbrella.\nIf this all sounds familiar it’s because the JavaScript port of Codename One was practically built for PWA…​\nDeploying as a Progressive Web App Out of the box, your app is ready to be deployed as a progressive web app (PWA). That means that users can access the app directly in their browser, but once the browser determines that the user is frequenting the app, it will \u0026ldquo;politely\u0026rdquo; prompt the user to install the app on their home screen. Once installed on the home screen, the app will behave just like a native app. It will continue to work while offline, and if the user launches the app, it will open without the browser’s navigation bar. If you were to install the native and PWA versions of your app side by side, you would be hard pressed to find the difference – especially on newer devices.\nBelow is a screenshot from Chrome for Android where the browser is prompting the user to add the app to their home screen.\nFigure 1. Add app to homescreen banner\nIf the app is available as a native app, in the Play store, you can indicate this using the javascript.manifest.related_applications and javascript.manifest.prefer_related_applications build hints. Then, instead of prompting the user to add the web app to their home screen, they’ll be prompted to install the native app from the Play store, as shown below.\nFigure 2. Add native app banner\n__ The PWA standard requires that you host your app on over HTTPS. For testing purposes, it will also work when accessed at a localhost address. You can use the Lighthoust PWA analysis tool to ensure compliance. For more information about Progressive Web Apps see Google’s introduction to the subject.\nCustomizing the App Manifest File At the heart of a progressive web app is the web app manifest. It specifies things like the app’s name, icons, description, preferred orientation, display mode (e.g. whether to display browser navigation or to open with the full screen like a native app), associated native apps, etc.. The Codename One build server will automatically generate a manifest file for your app but you can (and should) customize this file via build hints.\nBuild hints of the form javascript.manifest.XXX will be injected into the app manifest. E.g. To set the app’s description, you could add the build hint:\njavascript.manifest.description=An app for doing cool stuff You can find a full list of available manifest keys here. The build server will automatically generate all of the icons so you don’t need to worry about those. The \u0026ldquo;name\u0026rdquo; and \u0026ldquo;short_name\u0026rdquo; properties will default to the app’s display name, but they can be overridden via the javascript.manifest.name and javascript.manifest.short_name build hints respectively.\n__ The javascript.manifest.related_applications build hint expects a JSON formatted list, just like in the raw manifest file. Related Applications One nice feature (discussed above) of progressive web apps, is the ability to specify related applications in the app manifest. Browsers that support the PWA standard use some heuristics to \u0026ldquo;offer\u0026rdquo; the user to install the associated native app when it is clear that the user is using the app on a regular basis. Use the javascript.manifest.related_applications build hint to specify the location of the native version of your app. E.g.\njavascript.manifest.related_applications=[{\u0026quot;platform\u0026quot;:\u0026quot;play\u0026quot;, \u0026quot;id\u0026quot;:\u0026quot;my.app.id\u0026quot;}]\nYou can declare that the native app is the preferred way to use the app by setting the javascript.manifest.prefer_related_applications build hint to \u0026ldquo;true\u0026rdquo;.\n__ According to the app manifest documentation, this should only be used if the related native apps really do offer something that the web application can’t do. Device/Browser Support for PWAs Chrome and Firefox both support PWAs on desktop and on Android. iOS doesn’t support the PWA standard, however, many aspects of it are supported. E.g. On iOS you can add the app to your home screen, after which time it will appear and behave like a native app – and it will continue to work while offline. However, many other nice features of PWA like \u0026ldquo;Install this app on your home screen\u0026rdquo; banners, push notifications, and invitations to install the native version of the app, are not supported. It is unclear when, or even, whether Apple will ever add full support; but most experts predict that they will join the rest of the civilized world and add PWA support in the near future.\nOn the desktop, Chrome provides an analogous feature to \u0026ldquo;add to your homescreen\u0026rdquo;: \u0026ldquo;Add to shelf\u0026rdquo;. If it looks like the user is using the app on a regular basis, and it isn’t yet installed, it will show a banner at the top of the page asking the user if they want to add to their shelf.\nFigure 3. Add to shelf banner\nClicking the \u0026ldquo;Add button\u0026rdquo; prompts the user for the name they wish the app to appear as:\nFigure 4. Add to shelf prompt\nUpon submission, Chrome will generate a real application (on Mac, it will be a \u0026ldquo;.app\u0026rdquo;, on Windows, an \u0026ldquo;exe\u0026rdquo;, etc..) which the user can double click to open the app directly in the Chrome. And, importantly, the app will still work when the user is offline.\nThe app will also appear in their \u0026ldquo;Shelf\u0026rdquo; which you can always access at chrome://apps, or by opening the \u0026ldquo;Chrome App Launcher\u0026rdquo; app (on OS X this is located in \u0026ldquo;~/Applications/Chrome Apps/Application Launcher\u0026rdquo;).\nFigure 5. Chrome App Launcher\n__ The Chrome App Launcher lists apps installed both via the Chrome Web Store and via the \u0026ldquo;Add to Shelf\u0026rdquo; feature that we discuss here. The features we describe in this article are orthogonal to the Chrome Web Store and will not be affected by its closure. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nZombieLover — March 21, 2018 at 11:29 am (permalink) This is very exciting. Can we know how an app’s local SqLite DB will be impacted by this? When accessed by browser, where will the DB be stored? Will it be persisted for the user’s next visit? Will it be \u0026ldquo;downloaded\u0026rdquo; and stored locally at the app location when the app is installed?\nShai Almog — March 22, 2018 at 6:26 am (permalink) We support SQL in the JavaScript port via web SQL: https://en.wikipedia.org/wi…\nSo it’s stored in the browser. It works for most browsers but it’s a bit problematic because it isn’t a W3C standard. Also some things can’t be implemented there such as shipping the app with a \u0026ldquo;ready made\u0026rdquo; database etc.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/progressive-web-apps/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/progressive-web-apps/new-features-6.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003ePWAs (Progressive Web Apps) are an extremely hot topic right now, and Codename One apps are very well suited to being deployed this way. In case you haven’t been following the PWA buzz, the idea is that it’s a web app that behaves like a native app. When they are first loaded in a user’s browser, they behave like a normal responsive web app, but users can install them to their home screen just like native apps. At which point, they can behave as \u0026ldquo;offline-first\u0026rdquo; apps. Parts of this have been available for quite some time, but the concept of PWA brings a lot of little things under a single umbrella.\u003c/p\u003e","title":"Progressive Web Apps"},{"content":"\nThe other day I sent out an email alert mentioning the Uber clone release and price change for the course on the 30th. I also mentioned upcoming modules in February which caught some attention. I wanted to clarify some things and answer some of the repeat questions I’ve been getting. I also have a lot of updates to make so I’ll include some of those below.\nUber Clone I uploaded 33 lessons into the module by now which you can see in the main course page. I’m almost finished for this part.\nIf there are issues/missing functionality that’s problematic I might revisit this code in the future. However, based on the amount of work I had to put in I’m not sure how likely that would be. I would have to repeat all this work again for the social network app coming in April.\nBy the way, thank you all who visited and hearted my article at hacker noon. It got republished by dzone as well.\nPricing This has been somewhat contentious the last time I wrote about it. We don’t raise prices often. We actually only did it once for the basic subscription a few years back.\nHaving said that. The pricing of the course makes no sense once the Uber module is uploaded. It becomes a far larger course and increases its value. This will repeat once I upload additional apps. It’s unfair to existing users if we charge the same price regardless of value. It also provides a purchase disincentive.\nWe will raise the price to 499USD on the 30th of January and to 599USD in May once the social networking app is up.\nWe will still have an installments plan but it will probably raise prices too rather than stretch the installments further.\nAs you may recall I guaranteed a new app 4 times a year which means 8 new apps where the Uber clone is the first in that series. That doesn’t imply we’ll raise the course price by 800USD. I think that we’ll reach a price that we deem reasonable and stop (or slow down) at that point.\nUpcoming Modules Next month I will publish two new modules into the academy.\nThe first I’m pretty clear about and it’s currently tentatively titled: \u0026ldquo;Working with the Codename One Source code: working without the build servers\u0026rdquo;.\nIt will walk through the process of setting up an environment based mostly on the source code without using the build servers. It will continue where include the source left off by going into device build complexities without the servers.\nI’m still open for suggestions about second module so feel free to comment below. A good suggestion I received was \u0026ldquo;performance\u0026rdquo; which I think I can probably spend hours talking about…​\nXcode 9.2 Update We started the process of migrating to xcode 9.2. The big pain of upgrading servers to the latest version is behind us but builds still don’t go through. If by chance you select xcode 9.2 in the build hints or in the Codename One Settings UI the build will fail with a signing error.\nYou will need to select xcode 7.3 explicitly for now.\nWe will keep you posted on the migration, unfortunately we can’t make this migration 100% seamless as you might need build hints to clarify usage of some API’s that didn’t require these things in older versions of xcode.\nFinally There are a lot of new features and news I hope to get into in February but I’m trying to get some closure so we can get back to the fast development pace. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nLee — November 28, 2018 at 3:26 pm (permalink) Lee says:\nHi, Just bought the book and looking forward to getting started. However, the UberClone.zip file location specified in the book no longer exists and there is no re-direction or explanation page?\n/Lee\nShai Almog — November 28, 2018 at 4:06 pm (permalink) Shai Almog says:\nHi,\nI just verified that the file is there and working. I’m not sure why you aren’t seeing it.\nLee — November 28, 2018 at 4:57 pm (permalink) Lee says:\nSorry – spelling mistake on my part in the URL. This is why I need the source code instead of typing it myself!\nThanks for the speedy response.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/uber-clone-clarifications-xcode-9-2-update/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/uber-clone-clarifications-xcode-9-2-update/build-real-world-full-stack-mobile-apps-in-java.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe other day I sent out an email alert mentioning the Uber clone release and price change for the course on the 30th. I also mentioned upcoming modules in February which caught some attention. I wanted to clarify some things and answer some of the repeat questions I’ve been getting. I also have a lot of updates to make so I’ll include some of those below.\u003c/p\u003e\n\u003ch3 id=\"uber-clone\"\u003eUber Clone\u003c/h3\u003e\n\u003cp\u003eI uploaded 33 lessons into the module by now which you can see in the \u003ca href=\"https://codenameone.teachable.com/p/build-real-world-full-stack-mobile-apps-in-java\" target=\"_blank\" rel=\"noopener noreferrer\"\u003emain course page\u003c/a\u003e. I’m almost finished for this part.\u003c/p\u003e","title":"Uber Clone Clarifications and Xcode 9.2 Update"},{"content":"\nI’ve been so busy I just don’t have time to blog as much as I should. I do hope next month will be better in this regard (more on that below) but right now I have to make an important announcement. There are new chip vulnerabilities I’m sure you heard a lot about specifically Meltdown \u0026amp; Spectre. Thankfully we are at a layer that shouldn’t be impacted by these issues but we need to update our servers and will be doing so over the course of the next few days (possibly more as patches get updated).\nSo you might see some sudden downtime starting today, don’t be alarmed but let us know in case we didn’t notice. You can post to the google group even if our website goes down…​\nThere is some concern about potential impact to the build process speed. We don’t think this should change significantly as the big bottleneck in our build process isn’t CPU speed it’s IO. The kernel is involved in IO but it’s far from the bottleneck of that process.\nNew cn1libs for Objective-C \u0026amp; Code Scanning In other news Steve published two new cn1libs. The first is CN1ObjCBridge which is effectively reflection from Java into the Objective-C platform on iOS.\nInstead of using native interfaces to invoke native code you could use an API that lets you send Objective-C messages (their equivalent of method calls) from Codename One Java code. That’s pretty impressive.\nFor most normal cases I think using native interfaces would still be better but this could fill in a niche for things that could use reflection or better callback functionality.\nIf you want to see a usage example check out his new scandit library which uses the Scandit barcode/QR code scanning API.\nScandit provides much faster barcode/QR code scanning speeds but it comes at a price. You need to pay per seat licensing fees that can be a bit high. The worst part of it is that we can’t redistribute their binaries or use them with cocoapods/gradle. This means we can’t distribute a precompiled cn1lib for this product. However, if you need professional grade bardcode scanning this should work rather well.\n__ We implemented this library based on a request from an enterprise subscriber Push Console We added a lot of new features over the time I’ve taken away from blogging. I’ll write more about those but for now I’ll just mention one new feature. Push simulator.\nIn the simulator you can now open a window that will help you debug push applications. E.g. you can press a button to send a registration success callback where you will get a push key. You can also send a registration error and send a message.\nNotice that there is no message type option as that’s mostly seamless for the client. E.g. if you send a type 3 message it’s really just two separate message.\nType 2 or 1 etc. are all meaningless in the simulator as we only simulate the running application and not background behavior. Still I found it very useful to simulate these messages and was able to debug some nuanced behavior in NetBeans.\nStatus of Uber Module I was hoping that the Uber module would be completely finished by now but it isn’t. I’m pretty close though.\nI’ve done 30 lessons by now and uploaded 23. I’m guessing 40 or 45 lessons should be the final number when I’m done. I thought I’d finish by next Sunday but that’s already pushed back to Tuesday and I’m not sure I can make that deadline either. I’m doing everything I can to finish this before the end of the month as we need to start preparing to the 4.0 release which is already looming.\nThe reasons this is taking so long have a lot to do with the amount of extra work I need to do but they also have a lot to do with how I divide my time. I have some administrative tasks in the company that just keep me from finishing this process.\nRegardless of the above I’m pretty happy with the results so far and I have a lot to say about this once I’m done. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nTommy Mogaka — January 18, 2018 at 10:05 pm (permalink) Tommy Mogaka says:\nHi Shai, great work by Steve on the Scandit cn1lib. I noticed that CodenameOne is not listed in the Scandit Developer page. I saw a bunch of other development platforms there and I thought perhaps you guys could consider getting it listed there to get more traction. Best Regards!\nShai Almog — January 19, 2018 at 5:17 am (permalink) Shai Almog says:\nThanks. We already asked for a listing. I posted this and followed by sending them the details so it will probably take some time for everything to update on their end.\nTheir stuff seems pretty cool with dedicated barcode scanning phone cases etc.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/meltdown-updates/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/meltdown-updates/new-features-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been so busy I just don’t have time to blog as much as I should. I do hope next month will be better in this regard (more on that below) but right now I have to make an important announcement. There are new chip vulnerabilities I’m sure you heard a lot about specifically \u003ca href=\"https://arstechnica.com/gadgets/2018/01/heres-how-and-why-the-spectre-and-meltdown-patches-will-hurt-performance/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eMeltdown \u0026amp; Spectre\u003c/a\u003e. Thankfully we are at a layer that shouldn’t be impacted by these issues but we need to update our servers and will be doing so over the course of the next few days (possibly more as patches get updated).\u003c/p\u003e","title":"Meltdown and Other Updates"},{"content":"\nWe’ve just added support for Travis CI in your Codename One projects. Travis can be set up to automatically test your project (i.e. run unit tests) on a variety of different platforms every time you commit changes to github.\nThere is a wiki page with full documentation of this feature, but the general idea and workflow are:\nEnable Travis CI for your project via Codename One settings\nPush your project (including .travis.yml and .travis directory, which are created for you when you enable Travis) to Github.\nActivate your Project On Travis.\nThen every time you commit changes to Github, travis will run your tests.\nSettings Panel After you’ve activated Travis, the \u0026ldquo;Travis Settings\u0026rdquo; form will look like\n__ On-device continuous integration requires an Enterprise account. Other accounts will see the Android and iOS options disabled. But they can still enable JavaSE. This is a list of the jobs that you can have travis run for you. If you only select \u0026ldquo;JavaSE\u0026rdquo;, then Travis will run your unit tests in the Codename One simulator. Android jobs are run on the appropriate Android emulator, and iOS jobs are run on the appropriate iOS simulator.\nWe will be adding more versions and platforms as time goes on.\nFor full details, see the wiki page.\nAlso check out this screencast where I demonstrate Travis integration on the old GeoViz demo.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/travis-ci-integration/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/travis-ci-integration/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve just added support for Travis CI in your Codename One projects. Travis can be set up to automatically test your project (i.e. run unit tests) on a variety of different platforms every time you commit changes to github.\u003c/p\u003e\n\u003cp\u003eThere is a \u003ca href=\"https://github.com/codenameone/CodenameOne/wiki/Travis-CI-Integration\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ewiki page\u003c/a\u003e with full documentation of this feature, but the general idea and workflow are:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003eEnable Travis CI for your project via Codename One settings\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ePush your project (including .travis.yml and .travis directory, which are created for you when you enable Travis) to Github.\u003c/p\u003e","title":"Travis CI Integration"},{"content":"\nI hope you all had a great time over the holidays, I was working a lot but was able to enjoy the relative quiet of the holiday period to get some stuff done. There are a lot of new features I’d like to update you about and I will over the next few weeks (albeit slower than usual). Despite my best efforts I still didn’t finish the full Uber clone app course but I’m getting REALLY close. There isn’t that much work left to do though and I’m starting to trickle out the module lessons.\nI hope to be done with this before the middle of January but I suck at deadlines…​ I’ll make this up by doing two modules in February and by the fact that the Uber course will have roughly 30 lessons which is a HUGE amount of content.\nI’m already trickling out a few lessons (just published two today). I’ll try to keep this up and push them out at a good rate through the month. As a small teaser check out this screenshot from the simulator (notice that it’s the simulator so the map doesn’t look as good as it does on the device):\nFigure 1. Book ride\nA community member sent me this link which is an overview from an outsourcing company about the cost of building an Uber like application. For the impatient they estimate the amount of total work at 5000 hours costing between 20USD to 150USD per hour. Which means the unrealistic minimum cost of such an app is 100,000USD and a more realistic value would be over the 200,000USD range!\nThat sounds about right, building a full featured complex mobile app with backend server and taking it through the whole process with QA etc. isn’t cheap. I’m sure though that if these guys would have used Codename One the costs would have gone down significantly and would go down further now that they could use this app as a starting point.\nPrice Changes in the Academy When we launched the Codename One Academy we set the price for the Build Real World Full Stack Java Apps course at 399USD and provided some installment options.\nNow that we’ll add the Uber module it doesn’t make sense to keep the same pricing in place so we’ll raise the price to 499 within a couple of weeks. I’ll send out more details about this before we do this but if you want to avoid the price increase now is a good time to upgrade.\n__ If you already purchased the course or buy it before the price hike you have it forever. Future price changes won’t impact you regardless of updates we make to this course We intend to do something like this for every app we add to the course, we should add a social media app around April and that will probably trigger a similar price hike to 599 USD. We will probably cap this at some point though.\nPlugin Release \u0026amp; Updates We did a minor plugin update to 3.8.1 over the last weekend so people would get access to some new features and bug fixes. I have a blog post from Steve pending for next week that was waiting for this plugin update.\nBlogging will still be slow through January as I try to catch up to all the tasks and finish the course. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJérémy MARQUER — January 5, 2018 at 9:37 am (permalink) Sure it didn’t take you 5000 hours for building this uber clone. BUT, you didn’t reinvent the wheel …\nAs they said in article, 5000 hours is estimated for the following services :\n\u0026ldquo;Design / iOS and Android native app development / Backend development / Web development / Project management / Quality assurance\nAccording to our estimates of similar projects, the time it takes to build a taxi-hailing app, including an app for drivers and an app for riders, is somewhere near 5000 hours.\u0026rdquo;\nIt seems you would like to justify your academy price changes …. (maybe I’m wrong ! 🙂\nNevertheless, I’m pretty agree that Codenameone might help to build both android and iOS app. And congrats for this clone 🙂\nMy feeling is that to build a complex application, Codenameone still lacks robustness, for example in the management of threads .\nShai Almog — January 5, 2018 at 9:55 am (permalink) Shai Almog says:\nMy justification for raising the price is the students. It doesn’t make sense that a student who bought a course for 399USD without additional 5 hours of material will pay the same price as the person who buys it after that additional material is there. It creates a negative incentive for the purchase.\nI liked the Uber analysis which is why I linked to their site (with a follow link) despite the fact that they don’t use Codename One. I think a lot of companies like that lowball estimates and give the whole industry a bad name, their estimates seem solid. I think the equivalent app with Codename One would cost 3500-4000 hours as we won’t impact server costs or QA costs. Personally I spent 50-60 hours so far and would probably spend under 100 building my version. The goal is for this to be doable in a week for an experienced programmer. I’m assuming I’m roughly 10x more proficient in Codename One than a typical decent Codename One programmer and I’m not doing everything within the app. All of this information should help someone who is looking to upgrade make an informed judgement call on the value proposition.\nI’d appreciate a more concrete example of what you think we lack in terms of threads?\nI’m assuming you are looking at some of the capabilities from the newer thread API’s introduced in Java 5? These are very problematic to port and mostly useful for heavily threaded server environments. I don’t think they make a lot of sense in real world mobile apps.\nLukman Javalove Idealist Jaji — January 12, 2018 at 6:35 pm (permalink) Lukman Javalove Idealist Jaji says:\nHi Shai\nI am going to sign up for the course at the end of the month. I have a very weird request. Some of us cannot afford the pro subscription but badly need a JavaScript build for one of our apps. Could there be an arrangement for startups like us? We’ve been on basic subscription for over a year.\nShai Almog — January 13, 2018 at 5:54 am (permalink) Shai Almog says:\nHi,\nI’m afraid that would be unfair to the enterprise account holders who pay for this functionality. Notice that the license is very permissive so you can upgrade and cancel. You would have a month to get the JavaScript version working to speed.\nFinancially basic subscribers cover their cost but enterprise and to a lesser degree pro subscribers keep this company running.\nLukman Javalove Idealist Jaji — January 13, 2018 at 10:43 am (permalink) Lukman Javalove Idealist Jaji says:\nSeems fair enough then.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/uber-clone-trickling-down/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/uber-clone-trickling-down/build-real-world-full-stack-mobile-apps-in-java.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI hope you all had a great time over the holidays, I was working a lot but was able to enjoy the relative quiet of the holiday period to get some stuff done. There are a lot of new features I’d like to update you about and I will over the next few weeks (albeit slower than usual). Despite my best efforts I still didn’t finish the full Uber clone app course but I’m getting REALLY close. There isn’t that much work left to do though and I’m starting to trickle out the module lessons.\u003c/p\u003e","title":"Uber Clone Trickling Down"},{"content":"\nHappy holidays, Merry Christmas, happy new year to all. All of us here at Codename One hope you have a lovely vacation if you are taking one. As I mentioned before we are still working but only partially due to the holidays. We still got a lot of things out and have a lot more coming up. I will blog more about it in January. In the meantime, I’ll leave another teaser for my current project…​\nI’ve been working on cloning the Uber UI and functionality focusing on the chief use cases. The app itself isn’t that much work but documenting the process is a huge effort as I’m trying to explain every single step in as much detail as possible. Unfortunately since there is so much there screenshots don’t really convey the amount of material I created so far but that’s what I have to show for it right now…​\nFigure 1. The Uber side menu next to the clone\nYou can see a larger version here.\nI hope I’ll make the end of year deadline to publish the full module but with everything going on around here I might slip into January. I’m still hopeful I can get it out but realistically I’m trying to \u0026ldquo;do it right\u0026rdquo; and that takes time. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\ndavidwaf — December 21, 2017 at 1:13 pm (permalink) awesome!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/updates-happy-new-year/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/updates-happy-new-year/happy-holidays.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eHappy holidays, Merry Christmas, happy new year to all. All of us here at Codename One hope you have a lovely vacation if you are taking one. As I mentioned before we are still working but only partially due to the holidays. We still got a lot of things out and have a lot more coming up. I will blog more about it in January. In the meantime, I’ll leave another teaser for my current project…​\u003c/p\u003e","title":"Updates and Happy New Year"},{"content":"\nI’ve been remarkably busy with the Uber clone application. Cloning Uber proved to be pretty easy but writing the material about it is much harder so I’m taking longer than I anticipated to finish everything. I’m already up to slide 200 and I’ve barely started…​ I think I might end up with more than 1,000 slides in this module!\nI’m pretty optimistic about the results though and hope you will like it too. This did give me a chance to look deeply into the Uber application and I have a lot of insights into the current state of app development. E.g. the similarity between the Uber app on iOS and Android is amazing!\nE.g. this is the iOS version of the login form I showed before:\nFigure 1. iOS Uber Login UI\nThe similarity to the Android version is amazing. In other forms they even use the floating action button and the underline style text field from Android…​ I have a lot more to say about this and will try to collect my thoughts on this after I finish this module.\nIn terms of features we didn’t implement anything new over the past couple of weeks but we did make a few bug fixes and enhancements for under the hood behaviors. E.g. title animation and pull to refresh work better now. Text input in the JavaScript port is also much improved.\nWebsite Server Update We need to migrate the main server hosting this site to a new location so there might be some service interruption this Sunday around 8AM GMT but it should be pretty quick. If you notice an issue after that just reload as server state might have been impacted.\nThis is the second server update that’s user noticeable although there were a few others. I’m assuming Linode who are our main hosting provider is doing some infrastructure work. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbitvest — January 11, 2018 at 9:41 pm (permalink) bitvest says:\nI have build a website http://www.bitvest.com.au/ and now i would like to build a mobile app for this website.\nShai Almog — January 12, 2018 at 7:06 am (permalink) Shai Almog says:\nCheck out this post covering tutorials, documentation and resources available to developers https://www.codenameone.com…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/keeping-busy/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/keeping-busy/build-real-world-full-stack-mobile-apps-in-java.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been remarkably busy with the \u003ca href=\"/blog/uber.html\"\u003eUber clone application\u003c/a\u003e. Cloning Uber proved to be pretty easy but writing the material about it is much harder so I’m taking longer than I anticipated to finish everything. I’m already up to slide 200 and I’ve barely started…​ I think I might end up with more than 1,000 slides in this module!\u003c/p\u003e\n\u003cp\u003eI’m pretty optimistic about the results though and hope you will like it too. This did give me a chance to look deeply into the Uber application and I have a lot of insights into the current state of app development. E.g. the similarity between the Uber app on iOS and Android is amazing!\u003c/p\u003e","title":"Keeping Busy"},{"content":"\nBefore I go into the details a quick announcement, we need to update some of our push servers. We will have a short amount of downtime on Sunday December 3rd around 8AM GMT. This update should be very fast and barely noticeable but it might impact some push message deliverability for a short period.\nSome of us will be on vacation around December but I’ll personally still work during the month. However, I won’t post regular blog updates until mid January as the traffic during the Christmas/new year season is relatively low and I’m afraid some important updates might slip between the cracks. We do plan to push out a plugin update version 3.8.1 during this time as we have some new features and bug fixes pending.\nSteve already did a lot of work on continuous integration/TDD (Test Driven Development) support and Travis CI in particular. We already have a blog post pending but since some of the functionality requires a plugin update we’ll publish that in 2018 when people will actually read the post…​ If you want to get a teaser you can check out this wiki page.\nWe also pushed in a lot of fixes in the past few weeks and a couple of new features…​\nSouth Component One of the common RFE’s in side menu bar is the ability to add a component to the \u0026ldquo;south\u0026rdquo; part of the side menu. Up until now we had various patches and workarounds to allow this but these often required some \u0026ldquo;dubious\u0026rdquo; hacks.\nWe now have a new API that works with the on-top and permanent side menu:\ntoolbar.setComponentToSideMenuSouth(myComponent); This places the component below the side menu bar. Notice that this component controls its entire UIID and is separate from the SideNavigationPanel UIID so if you set that component you might want to place it within a container that has the SideNavigationPanel UIID so it will blend with the rest of the UI.\nUnit Tests in the Core We moved the unit tests for Codename One from Steve’s repo to the Codename One repo. You can see most of the unit test code here we hope to add more extensive tests as we run into regressions and implement new functionality.\nDefault Gap The Label component might have been one of our mistakes when designing Codename One. It embeds too much functionality into a single component with the icon and the text. If I would start Codename One over again I’d separate the image and text functionality and use a layout/container approach.\nCase in point: the gap between the label text and the icon. This defaults to 2 pixels and very few people know how to change it (it’s with the setGap method).\nTwo pixels is ridiculous for most cases and really hard to customize. We can/should fix this in the themes but I’m afraid this might break a lot of \u0026ldquo;working\u0026rdquo; code.\nWe added a theme constant labelGap which is a floating point value you can specify in millimeters that will allow you to determine the default gap for a label. We also added the method Label.setDefaultGap(int) which determines the default gap in pixels.\nI’m conflicted about the right way to \u0026ldquo;fix this\u0026rdquo;:\nSet the default gap to 1mm in the Label class\nSet the theme constant to 1 or 2mm in the native themes\nChange the default template to the project to include Label.setDefaultGap(convertToPixels(1));\nI’m very much inclined to do the 1st option but I’m concerned about compatibility which is why the last option is interesting too. I’m not too crazy about littering our hello world application with hacks though. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — December 1, 2017 at 8:36 pm (permalink) Francesco Galgani says:\nI read the \u0026ldquo;Travis CI Integration\u0026rdquo; by Steve on the wiki page you linked. It’s very interesting, it’s something that I’m looking for. My question are:\n– When will it be available?\n– Are the tests that we can use the ones recorded with the \u0026ldquo;Test Recorder\u0026rdquo; of the Simulator?\n– Can you improve the \u0026ldquo;Test Recorder\u0026rdquo; and produce more documentation, guidelines and/or examples about it?\n– Are the tests against real devices or simulated devices?\n– You ask for enterprise account to test on Android and iOS, so… do you have your own device farm that is for your enterprise users?\n– Can we have a video recording and/or screenshot recording of the app during the tests?\nThank you for the reply.\nShai Almog — December 2, 2017 at 5:10 am (permalink) Shai Almog says:\n– When we do a plugin update which will probably be this month or early January\n– Yes\n– If there are specific things you’d like to improve in the recorder please file an RFE in the issue tracker with detailed suggestion. We currently only have the JavaDocs for the test API’s that you can refer to. I might add a testing module to the online course in the future.\n– By default tests are against our simulator\n– If you have an enterprise account you can build against physical devices and run the tests on a device farm. We don’t manage our own device farm as this can become a HUGE problem well outside of our scope. We can connect to any standard appium device farm and let you run your tests there. We shouldn’t enter that field as device farm providers provide a level of flexibility such as \u0026ldquo;Run the test on device X located on operator network Y with locale Z\u0026rdquo;. That’s a level of specialization we can’t compete with.\n– That’s offered by the device farm providers\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/updates-holidays/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/updates-holidays/new-features-6.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eBefore I go into the details a quick announcement, we need to update some of our push servers. We will have a short amount of downtime on Sunday December 3rd around 8AM GMT. This update should be very fast and barely noticeable but it might impact some push message deliverability for a short period.\u003c/p\u003e\n\u003cp\u003eSome of us will be on vacation around December but I’ll personally still work during the month. However, I won’t post regular blog updates until mid January as the traffic during the Christmas/new year season is relatively low and I’m afraid some important updates might slip between the cracks. We do plan to push out a plugin update version 3.8.1 during this time as we have some new features and bug fixes pending.\u003c/p\u003e","title":"Updates and Holidays"},{"content":"\nWe have loads of demo Codename One apps hosted on Github, however cloning and running a project can be a little tricky because we generally don’t publish the dependent jar files (e.g. CodenameOne.jar) in the Github repository. This helps keep the repository lean, but it adds some steps to the process of cloning and running the project.\nFor use cases like this, you may want to try the Codename One CLI tool, as it provides many useful functions directly on the command line. In this post I’ll demonstrate how you can easily clone a Codename One project from Github and run it in the Codename One simulator using a single line of code.\nConsider the KitchenSink demo. We can clone this repository using the following command\n$ cn1 git-clone https://github.com/codenameone/KitchenSink Cloning into 'KitchenSink'... Installing jars into KitchenSink... Downloading 11606508 bytes Download completed! Project ready at KitchenSink What just happened?\nThe cn1 git-clone command is a thin wrapper around git clone (which implies that you need to have git clone in your PATH). Therefore you can pass it the same parameters as you pass to git clone. After cloning the repository, cn1 git-clone downloads the latest Codename One libs and adds them to the project so that it is ready to roll.\nRunning the Demo\nNow that the project is cloned, we can run the demo in the Codename One simulator by running the \u0026ldquo;run\u0026rdquo; target of the project. E.g.\n$ cd KitchenSink $ ant run Combining it into a Single Line If you are on Mac/Linux, it is easy to use the ‘\u0026amp;\u0026amp;’ operator to combine all this into a single line:\n$ cn1 git-clone https://github.com/codenameone/KitchenSink \u0026amp;\u0026amp; cd KitchenSink \u0026amp;\u0026amp; ant run This clones it, changes to the KitchenSink directory, and runs it.\nFinding Existing Demos You can also use the cn1 list-demos command to find existing Codename One demos on Github that you can clone. E.g.\n$ cn1 list-demos This will produce a list of all of the repositories on Github that are tagged with both the \u0026ldquo;codenameone\u0026rdquo; topic, and the \u0026ldquo;demo\u0026rdquo; topic. The output will look like\nshannah/GeoVizDemo : A demo app using the Codename One GeoViz Library codenameone/KitchenSink : Rewrite of the kitchen sink demo to match design aesthetics of 2016 ... etc.. You can filter the results by adding a parameter.\n$ cn1 list-demos \u0026quot;GeoViz\u0026quot; This will only show demos that also match the GeoViz search. We have only just started tagging our demos so for now there aren’t very many listed there. But the list will grow as time goes on.\n__ cn1 list-demos uses the Github search API, so you can use any filters that you would put into searches on the Github website. Once we see a demo that we want to run, we can pass its full name to cn1 git-clone. E.g.\n$ cn1 git-clone shannah/GeoVizDemo __ This demonstrates that git-clone allows you to omit the \u0026lt;https://github.com\u0026gt; from the repository name, and just provide the full repository name of the form ownername/repositoryname Adding Your Own Demos Adding your own demos so that they will be included in the cn1 list-demos results is easy. If your project is already hosted on Github, you simply need to add the codenameone and demo topics to the repository.\n__ When hosting a project on Github I recommend stripping out all of the jar files just as we do in our demos. You can do this by simply copying the following directives into your .gitignore file The .gitignore contents from the KitchenSink repository\n*.jar nbproject/private/ build/ nbbuild/ dist/ lib/CodenameOne_SRC.zip *.p12 *.mobileprovision A shortcut would also be to use cn1 git-init instead of git init when you initialize the repository.\nAppendix: Installing the CLI Tool Thus far, I’ve skipped the step of actually installing the CLI tool. It is distributed using npm, which is included when you install NodeJS, which has a simple installer for Windows, Linux, and Mac.\nInstalling Globally\nInstalling globally on Windows (Requires Admin permissions)\nnpm install -g codenameone-cli Installing globally on Mac/Linux\nsudo npm install -g codenameone-cli Installing Locally\nIf you don’t have admin permissions, or you just want to install it in the current directory, you can omit the -g flag. Then installation becomes\nInstalling locally\nnpm install codenameone-cli This will install the command at ./node_modules/.bin/cn1\nScreencast I’ve create a short screencast demonstrating the use of the cn1 git-clone command. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nNick Koirala — November 29, 2017 at 3:36 am (permalink) Nick Koirala says:\nNice one. Makes the demo projects much more accessible.\nMohammed Kamal — November 12, 2019 at 2:56 pm (permalink) Mohammed Kamal says:\nSteve, excellent, just done this now .. better late than never! Many thanks for that, saved me lots of times.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/git-clone-and-run-project-from-cli/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/git-clone-and-run-project-from-cli/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe have loads of demo Codename One apps hosted on Github, however cloning and running a project can be a little tricky because we generally don’t publish the dependent jar files (e.g. \u003ccode\u003eCodenameOne.jar\u003c/code\u003e) in the Github repository. This helps keep the repository lean, but it adds some steps to the process of cloning and running the project.\u003c/p\u003e\n\u003cp\u003eFor use cases like this, you may want to try the \u003ca href=\"https://www.npmjs.com/package/codenameone-cli\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCodename One CLI tool\u003c/a\u003e, as it provides many useful functions directly on the command line. In this post I’ll demonstrate how you can easily clone a Codename One project from Github and run it in the Codename One simulator using a single line of code.\u003c/p\u003e","title":"Clone and Run Codename One Demos In Single Line of Code"},{"content":"\nI’ve been working on creating a clone of the Uber app for our upcoming update of the Build Real World Full Stack Mobile Apps in Java course. There is a lot to go through there but the basics are surprisingly easy.\nE.g. this is the login form for the native Uber app on my Android device next to my clone mock code also on the same Android device…​ See if you can spot which one is mine. You can see a high resolution version of the image here:\nFigure 1. Images of the native Android Uber app and my clone code\nNotice that I didn’t even go for \u0026ldquo;pixel perfect\u0026rdquo; as that would mean the code would be a bit more complicated and I want the code to be simple. One of the things I like about Uber is how similar the app looks on iOS and Android. That validates a lot of what we have been saying all along: you need your own branding. Not Apples or Googles. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nLukman Javalove Idealist Jaji — November 21, 2017 at 1:01 pm (permalink) Nice. There is some kind of dropShadow effect on the logo on the Uber icon which is not in the clone. Nice one though\nShai Almog — November 21, 2017 at 1:07 pm (permalink) Shai Almog says:\nYes. I was conflicted about adding that. I could have created that shadow in the logo itself but I was a bit lazy.\nDoing it in code would have made it a bit complicated so I left it out for now. I’ll probably add it though.\nOn iOS the background rotates in a pretty cool way (looks almost identical otherwise). I thought about doing that effect as well but if I do it I must have a drop shadow as it becomes more apparent with the rotation.\nmaxii123 — November 21, 2017 at 1:15 pm (permalink) maxii123 says:\nThis is a joke right? You’re really crowing about copying a static page?\nShai Almog — November 21, 2017 at 1:22 pm (permalink) Shai Almog says:\nNo. The full app with the full functionality will be out within a month. Including the map, animations etc.\nRoss Taylor — November 21, 2017 at 3:28 pm (permalink) Ross Taylor says:\nVery nice. I like the CN1 clone better tbh. The inclusion of a drop shadow effect on logo would make it even better. Just a question, are you able to make the font size the same as the original or is this deliberately done to make it a bit bigger? I like the slightly bigger font here though.\nSimphiwe Twala — November 21, 2017 at 4:05 pm (permalink) Simphiwe Twala says:\nWow this will help me complete my uber clone. This is really cool stuff\nManuel Tijerino — November 22, 2017 at 12:09 am (permalink) Manuel Tijerino says:\nNice Job Shai !\n3lix — April 8, 2018 at 2:00 am (permalink) 3lix says:\nHi, where can I get the apk from ? Would like to load it on my phone. Thanks.\nShai Almog — April 8, 2018 at 5:55 am (permalink) Shai Almog says:\nIt’s not available. Since we use the Uber UI this might violate Uber IP if we shipped it in any form. A tutorial is fair use as we don’t do any reverse engineering or anything like that. But shipping binaries would be a problem.\nIt won’t work anyway as it needs to connect to a server and we aren’t hosting one publicly right now.\nThe source of both server \u0026amp; client is available in the course https://codenameone.teachab…\nPhilip Welch — June 13, 2018 at 12:01 am (permalink) Philip Welch says:\nIn the example clone app and the course, do you do any offline syncing? i.e. user changes data locally, if there’s no mobile phone data connection you save to a local database first and then sync when you get a connection again? Similarly how do you sync with data on the server – do you refresh all data or do you support some kind of incremental syncing?\nShai Almog — June 13, 2018 at 6:23 am (permalink) Shai Almog says:\nThere isn’t a real local database but there isn’t a need either. Details about the app user are cached so that should work fine. In case of a disconnect we try to reconnect the websocket.\nMaps are literally native Google Maps. They cache and handle their own data so there is not much to do there. Once the ride was agreed upon the network is only used to send location updates so the server can track the ride for its records. This could be enhanced so if there is a disconnect the data is sent later but I didn’t address that. I don’t think it would be hard to implement.\nUber is technically a pretty simple app in terms of data since most of the data is just webservices e.g. places searches, reverse geocode etc.\nFrancisco Claudio Araujo Palme — August 5, 2018 at 6:00 pm (permalink) Francisco Claudio Araujo Palme says:\nHello Shai\nIn the course, is there a class about building a dashboard/admin like website or server?\nShai Almog — August 6, 2018 at 4:18 am (permalink) Shai Almog says:\nHi,\nno. It wouldn’t teach anything of interest here. The goal of this tool is to teach how to build a full app. Not a production ready app. There is a server and building an admin console or app on top of it should be pretty easy. The course does cover building separate apps for driver/passenger so there is discussion of authority isolation and different apps/features on one server.\nGareth Murfin — August 4, 2020 at 5:07 pm (permalink) Gareth Murfin says:\nLooks awesome! Can you tell me if payment is already coded? And what does it use? Braintree again?\nShai Almog — August 5, 2020 at 2:35 am (permalink) Shai Almog says:\nIt uses braintree\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/uber/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/uber/build-real-world-full-stack-mobile-apps-in-java.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been working on creating a clone of the Uber app for our upcoming update of the \u003ca href=\"http://codenameone.teachable.com/courses/build-real-world-full-stack-mobile-apps-in-java/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eBuild Real World Full Stack Mobile Apps in Java\u003c/a\u003e course. There is a lot to go through there but the basics are surprisingly easy.\u003c/p\u003e\n\u003cp\u003eE.g. this is the login form for the native Uber app on my Android device next to my clone mock code also on the same Android device…​ See if you can spot which one is mine. You can see a high resolution version of the image \u003ca href=\"/blog/uber/side-by-side-high-res.png\"\u003ehere\u003c/a\u003e:\u003c/p\u003e","title":"Uber vs. Clone – Spot the difference"},{"content":"\nWe are thrilled to announce the release of Codename One 3.8. Codename One is an open source \u0026ldquo;Write Once Run Anywhere\u0026rdquo; mobile solution for Java developers!\nThis new release significantly refines the native look and feel of Codename One, it brings the GUI builder to a new level with styling support. It finally adds Mac OS appstore distribution support which means all the major appstores are now supported targets for Codename One applications.\nCodename One is the only platform that…​\nHas Write Once Run Anywhere with no special hardware requirements and 100% code reuse\nCompiles Java or Kotlin into native code for iOS, UWP (Universal Windows Platform), Android \u0026amp; even JavaScript\nIs Open Source \u0026amp; Free for commercial use with an enterprise grade commercial support\nIs Easy to use with 100% portable Drag \u0026amp; Drop GUI builder\nHas Full access to underlying native OS capabilities using the native OS programming language (e.g. Objective-C) without compromising portability\nHas full control over every pixel on the screen! Just override paint and draw or use a glass pane to draw anywhere…​\nLets you use native widgets (views) and mix them with Codename One components within the same hierarchy (heavyweight/lightweight mixing)\nTo learn more about Codename One check out the about page you can download it for free right now.\nAs part of the release we significantly refined our developer guide which is now also available in print form on Amazon. Notice that this guide is available for free here \u0026amp; in pdf format. This developer guide is a community effort which you can contribute to as explained here.\nHighlights of this Release The top 5 features of this release are covered in this short video, check out further details below…​\nImproved Native Look \u0026amp; Feel – We changed the core look of buttons, labels, text components, ripple effect and more. The goal is to make Codename One applications indistinguishable from native OS apps out of the box Figure 1. Before: Codename One 3.7 text Input (on Android)\nFigure 2. After: Codename One 3.8 text Input (on Android)\nKotlin Support – Kotlin is now officially supported by Codename One and works out of the box\nOn Top Side Menu – The on top side menu adapts the side menu UI to render on-top of the application instead of below but it’s really a complete rewrite of the old SideMenuBar which was implemented in a problematic way. The new on-top mode works better with native peers such as maps and can be extended more easily\nGUI Builder Styling Support – There are a lot of enhancements and refinements in the new GUI builder one of the big ticket features is the new style UI which allows you to style an element without leaving the GUI builder\nMac OS Appstore Support – We now support building signed Mac OS apps which means we now support all the major vendor appstores. We already support iOS/Android stores and Windows/Microsoft’s store (via the UWP port). The Mac appstore was the last major vendor whose store we didn’t support out of the box\nSignal Handling \u0026amp; Fast UTF in ParparVM – ParparVM is our open source iOS VM. It now handles low level OS signals to catch illegal access and convert it to Java exceptions. This means performance is slightly better but more importantly: you can catch errors even when they originate from native code. We also made significant improvements to the UTF-8 decoding logic which should make apps that rely on localized data faster and more memory efficient\nTheme Enhancements – We added many new capabilities into the Codename One themes specifically: Fractional padding/margin, Rounded border, Underline borders \u0026amp; more\nTable Sorting – You can now sort a table by clicking on the column header\nThere are many other features both big and small. Check out our blog and the github project history.\nLowlights As we always do with a release we’d like to shine a spotlight on the things this version could do better and the things the next version can improve. Overall we are thrilled with this release but here are a few things we can do better:\nOn device debugging – this was planned before for 3.7 but didn’t make it. We have a running proof of concept but that also highlights the amount of work needed to bring this to production grade. We didn’t think it will make it for 3.8 and I’m not optimistic about 4.0 with our current workload. We think this will be a great enhancement but right now we think theming is more important\nImproved default themes \u0026amp; material design – we made huge strides in this area but we are still way behind and our demos still don’t reflect the progress we made. Hopefully by the time 4.0 rolls around we’ll be in a different place entirely\nTheme \u0026amp; Localization – Steve added some better theming to the new GUI builder. We think we can improve on this further and generally improve theming. Localization is something that regressed a bit from the old GUI builder which allowed for great automatic localization. We need something more \u0026ldquo;seamless\u0026rdquo; in this department\nOnwards to 4.0 We have way more time for the 4.0 release so we can probably fit in more things than we did in 3.8. One of the difficulties in 3.8 is that a lot of the time between 3.7 and 3.8 was spent in summer months that are less productive. We fully expect 4.0 to be far richer in terms of features.\nBy the time 4.0 rolls around we should have two new major demos/tutorials in the Codename One Academy.\nThe Uber style application\nA social network style application\nWe’ve already laid some ground work for the Uber style app and we plan to push it out before the end of the year. This continues the 3 major trends we are trying to drive:\nBetter design\nBetter docs\nMore \u0026ldquo;ready made templates\u0026rdquo;\nAnother big focus which we’ll see in 4.0 is quality and continuous integration. Our QA process is now open as part of our continuous integration support. We are now running automated tests of all our commits on device farms which should make future versions of Codename One far more stable.\nWe Need your Help We got a record number of community pull requests during the 3.8 timeline, that is fantastic!\nIf you think we are doing a good job and appreciate our help please help us by:\nSpreading the word\nEdit our docs\nEdit our sources and submit bug fixes\nOr just sign up for enterprise accounts which literally keep the lights on here…​ If your company can afford it please take the time and upgrade to enterprise, this will allow us to work on the things that are important for your company!\nThanks for reading this far and if you have any thoughts/suggestions of any kind please let us know! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDalvik — November 14, 2017 at 2:33 pm (permalink) Great video, loved the narration…\nI really liked the new look and feel changes at least based on the screenshots, I need to adapt some of my code/themes to use this. I’m personally pretty excited about a better TDD workflow. I found this a bit hard to do up to now.\nFrancesco Galgani — November 15, 2017 at 1:58 pm (permalink) What’s code you used to generate the \u0026ldquo;Figure 2. After: Codename One 3.8 text Input (on Android)\u0026rdquo;? Is it an Instant UI generated using Properties?\nJames — November 16, 2017 at 4:18 am (permalink) James says:\nIs there a plugin update for Eclipse? When I run Check For Updates, it lists a 3.8 update but then fails to install and says the repository can’t be found. If I look in Eclipse Marketplace, I see 3.7 as the latest version.\nShai Almog — November 16, 2017 at 5:28 am (permalink) Shai Almog says:\nThat code is discussed here: https://www.codenameone.com…\nIt’s also in the new developer guide update.\nShai Almog — November 16, 2017 at 5:29 am (permalink) Shai Almog says:\nThanks I do need to update the eclipse marketplace listing. It should work for the update. What’s your update URL? What’s the error? What’s your eclipse version?\nJames — November 18, 2017 at 5:21 am (permalink) James says:\nI’m using Eclipse Version: Oxygen.1a (4.7.1a), Build id: M20171009-0410. The error I get is shown below. I went to the Marketplace and saw 3.8 listed and found a button there that said Update. I’m now updated to 3.8.0.\nAn error occurred while collecting items to be installed\nsession context was:(profile=SDKProfile, phase=org.eclipse.equinox.internal.p2.engine.phases.Collect, operand=, action=).\nNo repository found containing: osgi.bundle,CodenameOnePlugin,3.8.0\nNo repository found containing: org.eclipse.update.feature,CodenameOneFeature,3.8.0\nShai Almog — November 18, 2017 at 5:34 am (permalink) Shai Almog says:\nOdd. I have Oxygen installed and I installed via the marketplace too. It worked as expected for me. Are you behind a proxy by any chance?\nIf you try to install manually by using the update site: https://www.codenameone.com… does it work?\nDo you maybe have an older Codename One update site imported from an older version of eclipse?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-3-8-live/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-3-8-live/codenameone-3-8.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are thrilled to announce the release of \u003ca href=\"https://www.codenameone.com/\"\u003eCodename One\u003c/a\u003e 3.8. Codename One is an open source \u0026ldquo;Write Once Run Anywhere\u0026rdquo; mobile solution for Java developers!\u003cbr\u003e\nThis new release significantly refines the native look and feel of Codename One, it brings the GUI builder to a new level with styling support. It finally adds Mac OS appstore distribution support which means all the major appstores are now supported targets for Codename One applications.\u003c/p\u003e","title":"Codename One 3.8 is Live"},{"content":"\nI published this video a while back but it was longer and a bit confusing (over 40 minutes). Since some developers watch it before getting into Codename One I thought it would be in order to streamline it into a more manageable length and transcribe the content like I did with the newer videos. I also cleaned it up a bit and the result is below.\nYou can also read the full transcript within this blog post and use the captions that are a part of the video.\nTranscript In this video I’m going to explain \u0026ldquo;what is Codename One\u0026rdquo; but I’m going to take the scenic route…​ I’m going to go through the full history of our platform and I’m going to explain the underlying technology. How it works. What makes it different from other tools at least at a high level. If you want a 3 minute hello world video this isn’t it, go to the download section of Codename One dot com and check out the 3 minute videos there. Here I try to go deeper.\nLet’s start with the historic timeline of Codename One.\nFirst there was LWUIT, Chen started this project at Sun Microsystems back in 2006-2007 with the goal of write once run anywhere that actually works for mobile phones. Back then there were only J2ME \u0026amp; RIM platforms and device fragmentation was a major problem. The standards were implemented poorly by the various vendors and they were very hard to use. So Chen took inspiration from Swing which was the leading GUI API on the desktop and adapted those concepts to mobile.\nLWUIT was open sourced by Sun at JavaOne 2008. It became a huge success and was the top open source mobile project from Sun Microsystems but as LWUIT succeeded JavaME was dying. We had ports of LWUIT running on Android, RIM and the iPhone but we couldn’t support or publish them. This was due to company bureaucracy that didn’t improve as Oracle purchased Sun Microsystems.\nIn late 2011 we quit Sun and formed Codename One. We made a clean break from LWUIT by moving to a different package space and remodeling a lot of the API’s with a focus on smartphones. We ported everything to iOS, Android and other platforms. The big change was a change in concept. LWUIT was mostly a UI kit. Codename One was a completely inclusive environment that includes everything from the IDE plugin to the virtual machine, GUI builder and all the surrounding API’s. Codename One had a far larger and more ambitious scope than LWUIT.\nThis proved successful at least on a technical level as more than 100M apps were installed on devices relatively quickly and on a very diverse set of device types.\nAs the platform matured we expanded the scope of Codename One further and today we target not just Android \u0026amp; iOS. We target Universal Windows Platform which is the Microsoft standard for unified apps on Arm \u0026amp; intel. We target JavaScript which allows you to compile the Java applications into a JavaScript application including threads and everything so it can run in the browser. We even support desktop development which started as a curiosity due to user requirements and has picked up so well we use it ourselves. Recently we added Kotlin support and are adding new features on a weekly basis.\nSo I gave all of that background but still didn’t get to \u0026ldquo;what the hell is it?\u0026rdquo;. The problem is that it’s so big and hard to explain so lets break it into 6 pieces and I’ll go over each one of these pieces in great detail soon.\nFirst: It’s a virtual machine for all devices. The virtual machine is the environment that lets Java run on the device in a portable way.\nIt’s an API for all devices. The Application Programming Interface provides us with functionality that is distilled commonality from the various devices.\nIt’s an IDE plugin. In fact this is the only piece of Codename One you actually need. By installing the IDE plugin we automatically deliver everything else on the list\nIt’s a set of tools from device simulators to theme designer, GUI builder etc. Those are delivered within the plugin but deserve their own bullet as they are technically the same regardless of the IDE you use.\nThe cloud based system is the most confusing part. No, you don’t need the cloud to run a Codename One app. The resulting app is native. However, to build iOS apps you need a Mac and xcode which is Apples development tool. To build a Windows UWP application you need a Windows machine and Visual Studio which is Microsofts development tool. Well, we have Macs and Windows and Linux machines in the cloud. We seamlessly translate your Java bytecode to native projects and compile them using the official tools such as xcode then return the binary directly to you so you can install it on your phone or upload it to apple, Microsoft, google etc. Cool right?\nHere’s a fun fact. When we started pitching the company to investors we just stuck Codename One in the slides as a placeholder and investors liked it. We later on came up with the \u0026ldquo;idea\u0026rdquo; that these 6 different pieces constitute \u0026ldquo;one\u0026rdquo; product for \u0026ldquo;one code base\u0026rdquo; and that made sense as a company name.\nBut first lets start with the more in depth explanation of our VM’s. We currently have 3 virtual machines that we work with. Android has it’s own native Java support and we just use that. For desktop we use standard Java too. iOS doesn’t have a virtual machine and doesn’t allow JIT compilation which is a common practice in most virtual machines. Furthermore, historic attempts to build iOS virtual machines ran into issues of size and into problems with Apples frequent changes to their development toolchain. Our open source Parpar VM solves this problem by avoiding compilation. It translates Java bytecode to C which is one of the officially supported languages in iOS and much faster than Objective-C or Swift. We can then compile this C code using Apples compiler which guarantees that every change Apple makes will be easy to adapt to.\nThis isn’t just a \u0026ldquo;theoretical claim\u0026rdquo;. Since we released our VM Apple migrated from 32 bit to 64 bit and added support for bitcode compilation. All of these worked out of the box with ParparVM with no change from us. Even native developers struggled with some of those changes which were mostly seamless to Codename One developers.\nParparVM is very performant and can reach C levels of performance in some cases. It also produces a very small binary clocking under 5mb for applications which is very small for an iOS app. Similar attempts at JVM’s often produce binaries that exceed the 100mb limit… One of the cool things you can do with ParparVM is run the code using Apples xcode and debug or profile on the device. This is a very powerful way to discover things about the application and work with native OS code.\nThe UWP port uses iKVM which is a project that brought Java bytecode support to .net. Initially this project didn’t work with UWP but we worked with community members to update iKVM and published our iKVM fork as open source. This again means that we use native .net support when building windows applications.\nThe web port uses a 3rd party VM called TeaVM. This VM is very efficient at translating bytecode to JavaScript and can produce very small binaries when compared to similar technologies. We stripped out support for some JVM classes and as a result apps can be loaded with no cache within seconds. The VM supports threads by breaking down the code in very creative ways which keeps the code very efficient.\nThe Codename One Application Programming Interface is a single set of API’s that abstracts common device functionality you would expect to have on a mobile phone. This includes everything from widgets to camera, media, files, networking etc.\nThe trick with the API is our internal porting layer which is very clearly defined and relatively thin. That means 97% of Codename One’s code is in Java and this makes it more consistent to developers across platforms.\nThe user interface uses a lightweight UI approach which is a common term used to define Swing widgets. you might recall that Codename One was heavily inspired by Swing…\nLightweight UI means Codename One draws most of its widgets itself and uses the native platform mostly as a canvas and event handling environment. I’ll discuss this more in depth later on…\nThe API tries to be simple and unified so it does the \u0026ldquo;right thing\u0026rdquo; when possible. We can do that because the API is statically linked. That means that when an app is compiled our API becomes a part of the application. This means that if we change the API it will never impact apps in production. This isn’t true for native OS API’s who need to change very carefully so they won’t break applications that might rely on edge case functionality.\nCodename One ships plugins for the 3 top Java IDE’s specifically IntelliJ, Eclipse and NetBeans.\nThe plugin literally includes everything that’s a part of Codename One. Since the build happens in the cloud servers you don’t need to install native OS tools or anything like that.\nEssentially the plugins are relatively \u0026ldquo;stupid\u0026rdquo; as they mostly invoke Ant and our tools such as the simulator etc. This is a good thing. I use NetBeans as I’m used to it from my years at Sun. However, almost everything I do here is identical if you do it in Eclipse or IntelliJ.\nRecently we started making them even \u0026ldquo;dumber\u0026rdquo; by moving the settings from the IDE specific settings UI to the Codename One Settings tool which is common between all 3 IDE’s. This allowed us to move much faster.\nThe tools include 4 major groups. The first is the group of build tools which is really the ant script you have in the project and some extensions for that.\nThe device simulator includes skins representing various device types that you can download dynamically. It also includes a lot of additional functionality to test device behavior such as network monitor, performance analyzer, component inspector etc.\nThe resource editor also known as the Codename One Designer is our workhorse tool dating back to the days of LWUIT. It allows you to theme the application, localize it, manage builtin images and even included the old GUI builder of Codename One.\nThe new GUI builder is far more powerful and more closely matches common Java GUI builders in terms of functionality and technology.\nI’ve discussed the cloud build before but it’s important enough to recap. We have Macs, Windows and Linux machines that do the build for you. This is more than just having the build platforms. Setting up the native environments and all the prerequisites for a proper build is a nightmare. The cloud build servers essentially mask this whole process completely. Notice that we have an offline build feature that allows you to skip the cloud build but we don’t recommend that. It’s mostly for government or highly regulated industries where the word cloud is a synonym to \u0026ldquo;no management approval\u0026rdquo;. In those cases offline build becomes a lesser of two evils.\nThe cloud is mostly abstracted, you just right click the project and send a build. Everything else is seamless thanks to the tie in between the build tools and the build severs.\nYou don’t need to install anything other than the plugin. Not for Android or iOS. You can work with Mac, Windows or Linux and everything should \u0026ldquo;just work\u0026rdquo;.\nThis is a huge contributor to the seamlessness and simplicity of Codename One that allows you to get started \u0026ldquo;right away\u0026rdquo;.\nCodename One’s UI uses a lightweight UI approach which is a common term used to define Swing widgets.\nAs I mentioned before Codename One draws most of its widgets itself and uses the native platform mostly as a canvas and event handling environment.\nLightweight frameworks are very common especially in Java where Swing and JavaFX are both lightweight. QT is another example of a lightweight framework. Heavyweight frameworks include SWT and AWT from the Java side of the fence and other common tools such as Xamarin, Appcelerator etc.\nAs I mentioned before lightweight frameworks draw their own widgets. A native framework needs to have a native widget for every API. That might not sound like a big deal but platforms have very nuanced differences in threads, events etc. This means very nuanced bugs on the heavyweight framework side. In fact many heavyweight frameworks don’t define themselves as write once run anywhere tools since that is so hard to accomplish with this architecture.\nA lightweight architecture is really complex internally. Codename One is a hugely complex API developed for over a decade. Heavyweight API’s tend to be smaller and thinner wrappers around the native OS code. For the developer that means running more into OS differences since the framework doesn’t really hide them from you.\nLayout, theming, translation and localization are all really hard to do in a portable way. Heavyweight frameworks make you copy data to native OS structures and formats. They make you maintain images in the native OS locations which is radically different between iOS and Android. In lightweight framework this is all portable.\nThe tools of lightweight frameworks are generally all inclusive which is usually not the case for heavyweight frameworks. This isn’t always true for all cases but it’s a very common concept. This becomes obvious with hardware requirements where heavyweight frameworks require a Mac for iOS development. That isn’t true for Codename One. The cloud build works thanks to the lightweight architecture as the simulator can have better fidelity.\nSo lets compare concrete advantages of lightweight vs. heavyweight.\nLightweight allows for extreme portability where what you see in the desktop simulator becomes a closer facsimile of what you will see in the device.\nIt also gives you far more control as most of the code is written in Java you can override almost any behavior in a very portable way. So lightweight is far more customizable. The flip side is that heavyweight can be more performant in some cases. That’s debatable as performance is a very complex beast. I find that caching is by far the most important performance optimization and it’s also very portable. Usually code that is slow on Android will be slow on iOS so a smart optimization will work well for a lightweight framework.\nThat essentially means you get a more consistent result overall. Bugs are very portable too and so a fix in iOS will often fix an issue for the Android version as well. The heavyweight widget approach will have better consistency with the native OS. For instance in a Samsung customized device the buttons might match Samsungs styling more closely. I’m not sure that’s an advantage. When I program my button to have a specific color I want it to keep that color and behavior. I don’t want a device manufacturer or OS vendor to change the look of my application after the fact.\nIn general lightweight frameworks are MUCH easier to use as they are simpler. In some cases native code in the heavyweight approach is easier but this isn’t as true with Codename One where heavyweight widgets can be integrated with lightweight widgets… Codename One is still a lightweight framework but if you need a complex heavyweight widget such as Google Maps you can just embed it into a Codename One application and it will work across platforms consistently!\nWhich brings us to this. Codename One supports native interfaces, that allows you to invoke native code from Java and that native code can create an Android view or iOS UIView etc which you can just add into the component hierarchy.\nOne of the cool things we allow is z-ordering of native widgets which means you can add a google map and add lightweight components that reside on top of that map such as components representing cars, landmarks etc.\nThe Codename One lightweight API is VERY performant. E.g in iOS it is implemented on top of Open GL.\nThe lightweight API is VERY customizable, you can literally override the paint behavior of every component or place a drawing region and just draw on top of everything…\nThanks for baring with me. I hope this was helpful and informative. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nmarksluser — January 1, 2021 at 11:24 pm (permalink) marksluser says:\nGreat blog post.\nVery in-depth and description of how codename one works. I like the comparison of lightweight/heavyweight widgets and how those approaches affect the entire development process. Its also great that Codename One can still run a native widget. I also like Codename Ones approach to developing and building on the iOS platform, its a pain.\nI come from a desktop Java swing background and I have been looking at developing 2 different applications:\n-an desktop file/database exploring app (I first considered Eclipse SWT)\n-an mobile social media app (I am considering React Native)\nI looks like I could develop both of these in Codename One and still get performat access to the local file system and other native apis like the camera.\nOne question, can I build an application in Codename One that will run as a desktop app in Linux GTK+ ? I only saw MacOs and Windows listed as native desktop apps.\nThank you,\n-Mark\nShai Almog — January 2, 2021 at 5:54 am (permalink) Shai Almog says:\nWe don’t have a standard build dedicated to that although it’s technically trivial.\nYou can generate a JAR file relatively easily which will work for \u0026ldquo;other\u0026rdquo; desktop platforms. Packaging for Linux is a bit more challenging since there are so many potential targets, dependencies etc.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-what-is-codename-one/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-what-is-codename-one/learn-codenameone-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI published this video a while back but it was longer and a bit confusing (over 40 minutes). Since some developers watch it before getting into Codename One I thought it would be in order to streamline it into a more manageable length and transcribe the content like I did with the newer videos. I also cleaned it up a bit and the result is below.\u003c/p\u003e\n\u003cp\u003eYou can also read the full transcript within this blog post and use the captions that are a part of the video.\u003c/p\u003e","title":"Tutorial – What is Codename One"},{"content":"\nSteve has been pretty busy. We have new support for Mac Appstore builds as part of our desktop build process. That means you can build a signed Mac desktop app with Codename One which required a bit of work with previous releases. He also adapted our automated tests for Codename One so they would run on device farms and test against major versions of Android.\nMac Builds In order to use these changes you’ll need to install the latest release candidate for Codename One which includes an updated version of Codename One Settings. Once you do that check out this new section of the developer guide that covers the process of building and signing the Mac app.\nMac OS is locked down to some degree and if you ship an app outside of the app store you might run into problems. With this you can get the same benefit as you would get with itunes for iOS app sales on the Mac desktop. Since we already support UWP shipping through the Microsoft Windows Store is already possible.\nDevice Farm Testing One of the more important features we are still lacking is device farm testing. We have support for auto-tests and quite a few other capabilities but running tests automatically for all devices using a cloud based device farm is something we just never got around to do.\nApparently we’re already there, when we commit a change to Codename One or a pull request it will now test that change on the simulator as well as on multiple versions of Android out of the box. The complexity of adding automated iOS tests is due to the complexity of the fact that we are testing an \u0026ldquo;unpublished\u0026rdquo; version of Codename One but this should be relatively easy to accomplish for your apps.\nSteve also added a status badge to the project that highlights when all the tests pass in green so you know if something is failing just by looking at our github project page.\nWe hope to add automated iOS tests for better stability of Codename One but as I mentioned before this isn’t trivial.\nDevice Farms and Your Projects We already discussed CI support for your project but not the full TDD process. Now that we have a bit more experience with these device farms we hope to leverage that experience to make TDD trivial in Codename One.\nThis is hugely important, when you build multiple applications TDD allows you to change code rapidly without concern that you might run into a regression. This is hugely important in the volatile world of mobile development where new mobile OS’s/devices come out on a daily basis. Codename One does a lot of the heavy lifting here but no technology is perfect. With this approach you can instantly test on devices that you don’t have in your possession and instantly get a notice if a commit of your broke something.\nThat’s pretty cool…​\nWe’ll hopefully post a more in-depth tutorial on this within the next couple of months. Notice that this will require the synchronous build functionality of the enterprise accounts. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — November 11, 2017 at 11:52 pm (permalink) Francesco Galgani says:\nAt the moment, is any automated test on a Codename One app possible? In other words, is the test-driven development possible?\nShai Almog — November 12, 2017 at 5:19 am (permalink) Shai Almog says:\nSure. You have a test recorder built into the simulator and you can run automated tests with the simulator. You can send device builds with the test code in the enterprise subscription and get the binaries to run on your device. The one feature that was missing was the \u0026ldquo;run them automatically for you on the device\u0026rdquo;. That feature is coming soon after the 3.8 release.\nFrancesco Galgani — November 14, 2017 at 1:47 am (permalink) Francesco Galgani says:\nThank you. My problem is that in the developer guide I found very few information (in the section 13.6 \u0026ldquo;Device Testing Framework/Unit Testing\u0026rdquo;, pages 412-413) and in the Codename One website I found only a very short tutorial of two minutes: https://www.codenameone.com…\nI didn’t find any more information. I read the API and I also tried a pull request: https://github.com/codename…\nHowever, in my research of information the test capability is quite undocumented. I didn’t find any documentation about how to run a test on a real device. The API is not very well documented. I didn’t find any mention of the test recorder in the Codename One Academy courses, I discovered it because this blog post. So… are there more information elsewhere? Can you add a better video-tutorial soon? Thank you\nShai Almog — November 14, 2017 at 4:59 am (permalink) Shai Almog says:\nWe will focus more on TDD and CI with 4.0 and already have some work pending right after the release.\nIn the developer guide there is a section on continuous integration but we intend to do more and also release projects that already include the full set of scripts to work with existing CI solutions and appium (on device testing farms). This will be out relatively soon and we’ll post blog updates as this is published.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/mac-appstore-builds-device-farms/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/mac-appstore-builds-device-farms/mac.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSteve has been pretty busy. We have new support for Mac Appstore builds as part of our desktop build process. That means you can build a signed Mac desktop app with Codename One which required a bit of work with previous releases. He also adapted our automated tests for Codename One so they would run on device farms and test against major versions of Android.\u003c/p\u003e\n\u003ch3 id=\"mac-builds\"\u003eMac Builds\u003c/h3\u003e\n\u003cp\u003eIn order to use these changes you’ll need to install the latest release candidate for Codename One which includes an updated version of Codename One Settings. Once you do that check out \u003ca href=\"/manual/appendix-mac.html\"\u003ethis new section\u003c/a\u003e of the developer guide that covers the process of building and signing the Mac app.\u003c/p\u003e","title":"Mac Appstore Builds \u0026 Device Farms"},{"content":"\nCodename One 3.8 should land one week from now and from later today we are effectively in code freeze. Please update to the release candidate of 3.8 tomorrow morning to help us track some last minute bugs and regressions. As is usually our process we will release updates as necessary with code reviews and next week we won’t have the usual set of releases as we’ll take some time off.\nWe will branch to the 3.8 branch in our repository and every change to the branch will be cherry picked individually.\nDuring this week of code freeze we’ll try to update the documentation and prepare everything for the release. There are many important features in this release but as is our approach in recent releases the emphasis is strongly on refinement. If you run into any issue please file the issue ASAP so we can move quickly and update the release if necessary.\nUpcoming Milestones As you might recall we announced a switch to major version milestones which means the next release is 4.0. Here are the coming releases:\n4.0 – Scheduled for March 6th 2018\n5.0 – Scheduled for July 17th 2018\n6.0 – Scheduled for November 14 2018\nYou can track these milestones and the related tasks in our github project here. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — November 7, 2017 at 11:21 am (permalink) Francesco Galgani says:\nSo I suppose that the manual (developer guide) for the 3.8 release will be ready soon.\nCan you publish it not only on Amazon, but also in other book resellers, please? I have problems with Amazon.\nShai Almog — November 8, 2017 at 6:47 am (permalink) Shai Almog says:\nYes we will push out the 3.8 manual hopefully next week.\nWe won’t publish it elsewhere since the book is a print on demand book (POD) so Amazon literally does the printing of the book. Submitting to POD is a bit of a painful process so I don’t think we’ll go through other POD shops as well.\nThe PDF is still available and would be in sync with the book so if Amazon isn’t an option you can always print that as a last resort. It’s not ideal but can work.\nayad_alssady — February 20, 2018 at 4:34 pm (permalink) ayad_alssady says:\nplease want to help me in the example how to add a second hand to a widget analog clock application can you give me the code for it\nShai Almog — February 21, 2018 at 5:27 am (permalink) Shai Almog says:\nI don’t understand how this relates to this post?\nIt’s the same as the minutes hand only faster. I don’t understand the difficulty?\nayad_alssady — February 21, 2018 at 7:35 am (permalink) ayad_alssady says:\nI mean this second hand in the widget in android studio\nhttps://uploads.disquscdn.c…\nShai Almog — February 22, 2018 at 8:43 am (permalink) Shai Almog says:\nI understood that. I don’t understand what’s the problem with our sample code: https://www.codenameone.com…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codefreeze-for-3-8/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codefreeze-for-3-8/codenameone-3-8.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One 3.8 should land one week from now and from later today we are effectively in code freeze. Please update to the release candidate of 3.8 tomorrow morning to help us track some last minute bugs and regressions. As is usually our process we will release updates as necessary with code reviews and next week we won’t have the usual set of releases as we’ll take some time off.\u003c/p\u003e","title":"Codefreeze for 3.8"},{"content":"\nWe had a lot of posts covering images, multi-image and density. It’s one of the more challenging concepts to explain to developers coming from a desktop development background. Density is a simple concept to explain but the implications of it are sometimes counter-intuitive e.g. which device has higher density: Your phone or your 4k TV?\nThe answer is your phone and I explain why in the video.\nI also discuss the need to adapt UI’s for tablets to make better use of the available space although I don’t go deep into that subject. It might be worth covering that in a separate video, I discuss this in the academy though…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-working-with-images-densities/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-working-with-images-densities/learn-codenameone-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe had a lot of posts covering images, multi-image and density. It’s one of the more challenging concepts to explain to developers coming from a desktop development background. Density is a simple concept to explain but the implications of it are sometimes counter-intuitive e.g. which device has higher density: Your phone or your 4k TV?\u003c/p\u003e\n\u003cp\u003eThe answer is your phone and I explain why in the video.\u003c/p\u003e\n\u003cp\u003eI also discuss the need to adapt UI’s for tablets to make better use of the available space although I don’t go deep into that subject. It might be worth covering that in a separate video, I discuss this in the \u003ca href=\"http://codenameone.teachable.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eacademy\u003c/a\u003e though…​\u003c/p\u003e","title":"Tutorial – Working with Images and Densities"},{"content":"\nLast week we discussed the first part of working with text components and left some big tasks for this week. This week we’ll try to address the remaining issues with text input and make it easier to construct UI’s. This is crucial as we’ll be going into code freeze soon and we need enough time to iron out the issues in the text input.\nLast week I ended the post with this set of tasks:\nThe floating hint API is bad – we will need a new API to represent text field and label together both for iOS and Android\nWe will need a solution for the special case characters or icons that remain when typing and aren’t there as a hint. There are several tricks we can do but I need to give this some thought especially how they will work with something like a floating hint\nWe need to handle error messages in a standard way\nAll of these can be solved by adding a new component type that will replace the problematic FloatingHint hack. One of the mistakes we made with Codename One was following the conventions of Swing where the label and component are separate. However, this isn’t really the case and theming can have a deep impact on this. E.g. the label on Android should be above the text field and float into place while the label in iOS should be next to it.\nThis means we need a new API that will encapsulate the text component and the label next to it. This new API should be consistent, elegant and most importantly: \u0026ldquo;seamless\u0026rdquo;…​\nTextComponent \u0026amp; TextModeLayout Let’s start with the end of last weeks post:\nFigure 1. Final result\nBack then I wrote that using the FloatingHint as such:\nTableLayout tl = new TableLayout(3, 2); Form f = new Form(\u0026quot;Pixel Perfect\u0026quot;, tl); TextField title = new TextField(\u0026quot;\u0026quot;, \u0026quot;Title\u0026quot;); TextField price = new TextField(\u0026quot;\u0026quot;, \u0026quot;Price\u0026quot;); TextField location = new TextField(\u0026quot;\u0026quot;, \u0026quot;Location\u0026quot;); TextArea description = new TextArea(\u0026quot;\u0026quot;); description.setHint(\u0026quot;Description\u0026quot;); f.add(tl.createConstraint().horizontalSpan(2), new FloatingHint(title)); f.add(tl.createConstraint().widthPercentage(30), new FloatingHint(price)); f.add(tl.createConstraint().widthPercentage(70), new FloatingHint(location)); f.add(tl.createConstraint().horizontalSpan(2), new FloatingHint(description)); f.show(); Besides being verbose this looked bad on iOS:\nFigure 2. Not horrible but not exactly \u0026ldquo;iOS\u0026rdquo;\nSo we need something better…​ This code produces the exact same look on Android (more on that soon) but it does that while producing a good looking result on iOS too:\nTextModeLayout tl = new TextModeLayout(3, 2); Form f = new Form(\u0026quot;Pixel Perfect\u0026quot;, tl); TextComponent title = new TextComponent().label(\u0026quot;Title\u0026quot;); TextComponent price = new TextComponent().label(\u0026quot;Price\u0026quot;); TextComponent location = new TextComponent().label(\u0026quot;Location\u0026quot;); TextComponent description = new TextComponent().label(\u0026quot;Description\u0026quot;).multiline(true); f.add(tl.createConstraint().horizontalSpan(2), title); f.add(tl.createConstraint().widthPercentage(30), price); f.add(tl.createConstraint().widthPercentage(70), location); f.add(tl.createConstraint().horizontalSpan(2), description); f.setEditOnShow(title.getField()); f.show(); Figure 3. An iOS native \u0026ldquo;feel\u0026rdquo; with the exact same code\nWhy a New Layout? As you can see from the code and samples above there is a lot going on under the hood. On Android we want a layout that’s similar to TableLayout so we can \u0026ldquo;pack\u0026rdquo; the entries. On iOS we want a box layout Y type of layout but we also want the labels/text to align properly…​\nThe new TextModeLayout isn’t really a layout as much as it is a delegate. When running in the Android mode (which we refer to as the \u0026ldquo;on top\u0026rdquo; mode) the layout is almost an exact synonym of TableLayout and in fact delegates to an underlying table layout. In fact there is a public final table instance within the layout that you \u0026ldquo;can\u0026rdquo; refer to directly…​\nThere is one small difference between the TextModeLayout and the underlying TableLayout and that’s our choice to default to align entries to TOP with this mode. It’s important for error handling which I’ll cover below.\nWhen working in the non-android environment we use a BoxLayout on the Y axis as the basis. There is one thing we do here that’s different from a default box layout and that’s grouping. Grouping allows the labels to align by setting them to the same width, internally it just invokes Component.setSameWidth(). Since text components hide the labels there is a special group method there that can be used. However, this is implicit with the TextModeLayout which is pretty cool.\nTextComponent The text component uses a builder approach to set various values e.g.:\nTextComponent t = new TextComponent(). text(\u0026quot;This appears in the text field\u0026quot;). hint(\u0026quot;This is the hint\u0026quot;). label(\u0026quot;This is the label\u0026quot;). multiline(true); I think the code is pretty self explanatory and more convenient than typical setters/getters. It automatically handles the floating hint style of animation but does that more smoothly using layout \u0026amp; style animation instead of the outdated morph animation.\nWe also added some pretty spiffy new features to address the points above…​\nError Handling I’ve added support to the validator class for text component and it should \u0026ldquo;just work\u0026rdquo;. But the cool thing is that it uses the material design convention for error handling!\nSo if we change the sample above to use the validator class:\nTextModeLayout tl = new TextModeLayout(3, 2); Form f = new Form(\u0026quot;Pixel Perfect\u0026quot;, tl); TextComponent title = new TextComponent().label(\u0026quot;Title\u0026quot;); TextComponent price = new TextComponent().label(\u0026quot;Price\u0026quot;); TextComponent location = new TextComponent().label(\u0026quot;Location\u0026quot;); TextComponent description = new TextComponent().label(\u0026quot;Description\u0026quot;).multiline(true); Validator val = new Validator(); val.addConstraint(title, new LengthConstraint(2)); val.addConstraint(price, new NumericConstraint(true)); f.add(tl.createConstraint().horizontalSpan(2), title); f.add(tl.createConstraint().widthPercentage(30), price); f.add(tl.createConstraint().widthPercentage(70), location); f.add(tl.createConstraint().horizontalSpan(2), description); f.setEditOnShow(title.getField()); f.show(); You would see something that looks like this on Android:\nFigure 4. Error handling when the text is blank\nFigure 5. Error handling when there is some input (notice red title label)\nFigure 6. On iOS the situation hasn’t changed much yet\nThe underlying system is the errorMessage method which you can chain like the other methods on TextComponent as such:\nTextComponent tc = new TextComponent(). label(\u0026quot;Input Required\u0026quot;). errorMessage(\u0026quot;Input is essential in this field\u0026quot;); InputComponent \u0026amp; PickerComponent To keep things simple I focused on the the TextComponent but after the initial commit we decided to move to a more flexible system where other component types could be laid out in a similar way to maintain consistency with Android/iOS.\nTo keep the code common and generic we use the InputComponent abstract base class and derive the other classes from that. PickerComponent is currently the only other option. We considered options such as CheckBox or OnOffSwitch but both are problematic in some ways so we’d like to give them a bit more thought.\nA picker can work with our existing sample using code like this:\nTextModeLayout tl = new TextModeLayout(3, 2); Form f = new Form(\u0026quot;Pixel Perfect\u0026quot;, tl); TextComponent title = new TextComponent().label(\u0026quot;Title\u0026quot;); TextComponent price = new TextComponent().label(\u0026quot;Price\u0026quot;); TextComponent location = new TextComponent().label(\u0026quot;Location\u0026quot;); PickerComponent date = PickerComponent.createDate(new Date()).label(\u0026quot;Date\u0026quot;); TextComponent description = new TextComponent().label(\u0026quot;Description\u0026quot;).multiline(true); Validator val = new Validator(); val.addConstraint(title, new LengthConstraint(2)); val.addConstraint(price, new NumericConstraint(true)); f.add(tl.createConstraint().widthPercentage(60), title); f.add(tl.createConstraint().widthPercentage(40), date); f.add(location); f.add(price); f.add(tl.createConstraint().horizontalSpan(2), description); f.setEditOnShow(title.getField()); f.show(); This produces the following which looks pretty standard:\nFigure 7. Picker component taking place in iOS\nFigure 8. And in Android\nAs I mentioned this is pretty obvious once we got through everything else. The one tiny caveat is that we don’t construct the picker component using new PickerComponent() instead we use create methods such as PickerComponent.createDate(new Date()). The reason for that is that we have many types of pickers and it wouldn’t make sense to have one constructor.\nUnderlying Theme Constants These varying looks are implemented via a combination of layouts, theme constants and UIID’s. The most important UIID’s are: TextComponent, FloatingHint \u0026amp; TextHint.\nThere are several theme constants related that can manipulate some pieces of this functionality:\ntextComponentErrorColor a hex RGB color which defaults to null in which case this has no effect. When defined this will change the color of the border and label to the given color to match the material design styling. This implements the red border underline in cases of error and the label text color change\ntextComponentOnTopBool toggles the on top mode which makes things look like they do on Android. This defaults to true on Android and false on other OS’s. This can also be manipulated via the onTopMode(boolean) method in InputComponent however the layout will only use the theme constant\ntextComponentAnimBool toggles the animation mode which again can be manipulated by a method in InputComponent. If you want to keep the UI static without the floating hint effect set this to false. Notice this defaults to true only on Android\ntextComponentFieldUIID sets the UIID of the text field to something other than TextField this is useful for platforms such as iOS where the look of the text field is different within the text component. This allows us to make the background of the text field transparent when it’s within the TextComponent and make it different from the regular text field\nFinal Word We went through a lot to get to this point but there is quite a bit more that we need to address:\nOther component types – we need better support for things such as on-off switches etc.\nWe didn’t implement the material design feature of icon or symbol on the side of a text field, it’s something we might want to address in a future update. I’m not sure how this will play nicely with the animation\nThere are some cool features and iOS refinements we’d like to add, e.g. on iOS icons are common next to the labels and error handling there should be better\nThe properties instant UI code should migrate to this as soon as possible, right now it’s not practical since we don’t have checkbox/on-off support but once those are in place this is something we should support\nOverall I hope the work speaks for itself and that soon we’ll be able to say that our UI matches and hopefully exceeds the refinement of OS native code.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/pixel-perfect-text-input-part-2/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/pixel-perfect-text-input-part-2/pixel-perfect.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eLast week we discussed the \u003ca href=\"/blog/pixel-perfect-text-input.html\"\u003efirst part of working with text components\u003c/a\u003e and left some big tasks for this week. This week we’ll try to address the remaining issues with text input and make it easier to construct UI’s. This is crucial as we’ll be going into code freeze soon and we need enough time to iron out the issues in the text input.\u003c/p\u003e\n\u003cp\u003eLast week I ended the post with this set of tasks:\u003c/p\u003e","title":"Pixel Perfect – Text Input (Part 2)"},{"content":"\nWe will enter code freeze for Codename One 3.8 next week and have a lot of things to clear off the table in order to get there!\nThe first order of business is that there will be no Codename One 3.9…​ Instead we will go right to 4.0 and switch to major version number update scheme only.\nThis will align us better with industry standards. We spent ages in 3.x and far less in 1.x or 2.x numbering. That doesn’t make sense. It’s hard to tell what feature is big enough for a \u0026ldquo;major version number update\u0026rdquo; and it doesn’t indicate as much with the fast pace of releases. So switching to major version numbers in terms of milestones will simplify and give a better indication of the work we put in.\nWe will enter code freeze next week on the 7th of November with release of 3.8 scheduled for the 14th.\nEclipse Oxygen Issue Some eclipse users with the latest version of Oxygen (4.7.1a) have complained about an issue with the simulator. This seems to be a bug or change in the latest version of eclipse that we are trying to nail down.\nThere is a workaround mentioned in the stackoverflow answer which should be pretty easy to follow. However, if this doesn’t work as expected you might want to use an older version of eclipse until this is fixed. We support versions from Neon 2 and up.\nOn Top Sidemenu We switched this this on by default this weekend and already found a regression that eluded us before with the overflow menu. This is now fixed in the GIT but there might be more issues, hopefully we’ll be able to resolve everything before the code freeze so please check your code and report back to us ASAP if you encounter issues!\nAutomated Tests While we have some internal tests for Codename One most of them are ad-hoc and not exactly organized. Steve setup the groundwork with a new automated test repository that is now also bound to our travis CI setup in github.\nThis means you can add a test case together with a bug report or pull request. This could help tremendously in improving the long term stability of Codename One!\ncallSeriallyOnIdle One of the features that we added and totally slipped under the radar is the new callSeriallyOnIdle method which essentially works exactly like callSerially but doesn’t perform its work until the device is idling. If you have multiple entries in this call it will serialize them and won’t do them all at once.\nThe main use case is for tasks that might be CPU intensive but should be done on the EDT. This allows you to postpone such a task for a moment where the EDT will sleep anyway. A good example is processing images for scrolling. You would want the scrolling to still be smooth with the placeholder images and have the processing only when the user isn’t active.\nThis feature is a drop-in replacement for callSerially and in the next update will be available in the CN class too as well as Display.\nCaching cn1lib \u0026amp; SMS Activation Improvements Yaakov added a cn1lib for caching objects as JSON representations or as he put it in his description:\nThis CodenameOne library enables apps to easily cache data downloaded from the app server (or any other source) in the device’s file system. Cached data is saved in JSON format, one file per object type. Caching data can potentially improve the app’s performance and responsivity, cut down on cell data usage, extend battery life, and enable ‘offline mode’.\nDiamond fixed an NPE in both of the cn1libs for SMS activation so if you use one of them I suggest updating the library to the latest to avoid that.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-milestones-features/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-milestones-features/codenameone-3-8.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe will enter code freeze for Codename One 3.8 next week and have a lot of things to clear off the table in order to get there!\u003cbr\u003e\nThe first order of business is that there will be no Codename One 3.9…​ Instead we will go right to 4.0 and switch to major version number update scheme only.\u003c/p\u003e\n\u003cp\u003eThis will align us better with industry standards. We spent ages in 3.x and far less in 1.x or 2.x numbering. That doesn’t make sense. It’s hard to tell what feature is big enough for a \u0026ldquo;major version number update\u0026rdquo; and it doesn’t indicate as much with the fast pace of releases. So switching to major version numbers in terms of milestones will simplify and give a better indication of the work we put in.\u003c/p\u003e","title":"New Milestones and Features"},{"content":"\nSome of our how do I videos are so old it’s embarrassing…​ This is especially true for some core concepts videos as they were some of the first ones we made. The worst part is that these are probably the most important videos we have as they are viewed by developers completely new to Codename One. We had two videos covering creations of lists and both of them used com.codename1.ui.List with the old GUI builder!\nThat’s embarrassing…​ Especially considering this.\nSo I’ve created a new video that’s more up to date. I discuss lists as a concept but I really describe box layout Y and the InfiniteContainer class. It’s a big improvement over the old videos. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nTommy Mogaka — October 26, 2017 at 2:09 pm (permalink) Tommy Mogaka says:\nHi Shai, thanks for this. Is it possible on the list created using the above method to have LongPress detection capability? If not, how can this be added to the list items of the list itself?\nShai Almog — October 27, 2017 at 4:31 am (permalink) Shai Almog says:\nHi,\nsure. You can add any component to the \u0026ldquo;list\u0026rdquo; and you can subclass any component to override longPointerPress\nTommy Mogaka — October 27, 2017 at 11:48 am (permalink) Tommy Mogaka says:\nThank Shai, one more question on lists.\nAfter scrolling and pressing an item that navigates you away from a list(e.g. to another form or page), how do you get back to a list to previously displayed list? In my case, the form usually in another class. Is it achievable and what can I do to my code to add this \u0026ldquo;remember last position\u0026rdquo; feature onto a list? The use case is when you have a long list and you need to go back and forth without having to keep scrolling from the top to get back to where you had last clicked.\nShai Almog — October 28, 2017 at 4:54 am (permalink) Shai Almog says:\nIf the same form instance is used when you get back it should still be scrolled to that same position. If not you can just call requestFocus() in the show listener event.\nFrancesco Galgani — November 4, 2017 at 4:03 pm (permalink) Francesco Galgani says:\nIt’s useful. Thank you. For my better understanding, I would ask to you the transcript and the code, like in the Codename One Academy lessons… or, can you add this video to the Academy, so I can access to the transcript and to the source code?\nThank you.\nShai Almog — November 5, 2017 at 5:05 am (permalink) Shai Almog says:\nThanks. All of my new videos on youtube have subtitles which you can turn on using the CC button. You can also see the full transcript of this and other videos in the how do I page for each of them here https://www.codenameone.com…\nמֶרֶס יָֽשָׁבְעָם — February 2, 2020 at 3:27 am (permalink) מֶרֶס יָֽשָׁבְעָם says:\nReally good explanation. Thanks Shai, one thing I appreciate of your explanations is the fact that you consider the way to improve also the way to get things look nice, always at the programmer point of view.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-creating-lists/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-creating-lists/learn-codenameone-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSome of our \u003ca href=\"/how-do-i.html\"\u003ehow do I videos\u003c/a\u003e are so old it’s embarrassing…​ This is especially true for some core concepts videos as they were some of the first ones we made. The worst part is that these are probably the most important videos we have as they are viewed by developers completely new to Codename One. We had two videos covering creations of lists and both of them used \u003ccode\u003ecom.codename1.ui.List\u003c/code\u003e with the old GUI builder!\u003c/p\u003e","title":"Tutorial – Creating Lists"},{"content":"\nI started working on this post back in August and so much happened in between I just had to scrap the whole thing and start over again…​ I’ve discussed buttons before and now it’s time for TextField \u0026amp; TextArea. But before we go into that lets take a moment to talk about the problems that arose from the last installment of pixel perfect.\nI made a lot of changes to Codename One but there was one particularly painful change: caps text. This proved to be a far more controversial change than I had intended and I had an interesting debate with Nick. I’d appreciate participation in the thread there or here. The gist of the debate is how can we change functionality people rely on without disrupting working code. I honestly didn’t think the caps text change was a big change or would cause the problems it did. However, having said that it’s really hard to rollout a feature without disrupting developers occasionally.\nIMO one of the best ways around it is if more people used the source when working with Codename One:\nYou would see problematic things before they make it to the build servers\nYou would be able to patch/fix issues at least locally\nDebugging into the code would be easier for you\nSo please use the source and help us all make a better product!\nOn Top Sidemenu Update One of the things that did get some scrutiny over the past few weeks is the on-top side menu that caused quite a few regressions. We now have an up to date version of this code which should work nicely with the on-top side menu so if all goes according to plan we’ll flip the switch over this weekend.\nAs a reminder, we will transition from the original Toolbar sidemenu implementation to a completely new approach that solves a lot of the issues with the old side menu and looks closer to modern native side menus by residing on top of the UI. You can toggle this side menu on/off by invoking Toolbar.setOnTopSideMenu(true); in your init(Object) method (you should use false to turn it off).\nText Components on Android The material design guideline includes several modes and states for text fields but generally this image represents the desired native look reasonably well:\nFigure 1. Native Android text fields\nOne thing that isn’t clear from the screenshot is the floating label which is now becoming standard in Android. I think we’ll probably need a better abstraction for that one…​ Right now a similar UI in Codename One looks like this:\nFigure 2. The before shot\nThe current code for doing this looks like this:\nTableLayout tl = new TableLayout(3, 2); Form f = new Form(\u0026quot;Pixel Perfect\u0026quot;, tl); TextField title = new TextField(\u0026quot;\u0026quot;, \u0026quot;Title\u0026quot;); TextField price = new TextField(\u0026quot;\u0026quot;, \u0026quot;Price\u0026quot;); TextField location = new TextField(\u0026quot;\u0026quot;, \u0026quot;Location\u0026quot;); TextArea description = new TextArea(\u0026quot;\u0026quot;); description.setHint(\u0026quot;Description\u0026quot;); f.add(tl.createConstraint().horizontalSpan(2), new FloatingHint(title)); f.add(tl.createConstraint().widthPercentage(30), new FloatingHint(price)); f.add(tl.createConstraint().widthPercentage(70), new FloatingHint(location)); f.add(tl.createConstraint().horizontalSpan(2), new FloatingHint(description)); f.show(); What’s Wrong There are several problems when we look at the screenshots side by side:\nNo margin\nText field border is in Android 4.x style instead of the material design line style\nFont color is wrong for the title label and the color of the bottom line (both should match)\nThe font is wrong both in the title label and the text\nFloating hint makes sense in Android but we might need to rethink it for iOS\nPrice has a special case $ symbol prefix that has the color of the title label\nBesides those things that are obvious from the screenshots here are a few other things that might be a problem:\nFocus color behavior is incorrect – in native code the color of the title text and underline change on focus but not the color of the text itself\nError message labels should appear below in red\nHint text looks different from native hint text\nAs before I’ll try going through this list and I’ll try fixing these so the look will be more native.\nMargin \u0026amp; Border These are probably the easiest fixes to do with the exception of the colors. After making a few changes to the margin and the border and applying that to the theme we can now see this:\nFigure 3. After applying margin and underline border change\nThese were both pretty easy to fix in the designer tool, I just edited the Android native theme and changed the styling for the border and margin. I also needed a style for FloatingHint which matches the label on top. It needs to match the margin of the text field now.\nColors One of the problem in the simulator screenshot process is that it hides the currently editing text, in the picture below it isn’t clear that the text we are editing is black while the line is blue and the label on top is also blue.\nFigure 4. The editing line and label have the same color\nRight now we don’t have any way to define a standard color palette in the theme. So I can’t pick a color constant and need to pick a specific color for the border to work with. This is something we should probably address in the theme toolchain but it’s not a trivial fix and requires some thought. In general I’d like to define a color scheme and automatically generate the native Android colors.xml etc. to create a more uniform UX.\nIn terms of focus I had to do a bit more work. I added a new method to Component shouldRenderSelection() which can be overriden to indicate whether selection is shown. Normally in touch devices the selected state only appears when touching the screen so this is essential for this case.\nFonts The fonts are also a pretty easy change. I used the native regular at first but then comparing it to the native UI it seems that the light version of the font is closer to the design.\nFigure 5. Better sized roboto font\nI also styled the FloatingHint text with a smaller version of the same font and adapted the TextHint to use the same font with a gray color.\nWhat’s Next All of these changes should be up in the next update and might disrupt existing code. As I mentioned before this is expected as we move the product forward. In the next installment I’ll try to address the remaining issues and hopefully fine tune some of the behaviors:\nThe floating hint API is bad – we will need a new API to represent text field and label together both for iOS and Android\nWe will need a solution for the special case characters or icons that remain when typing and aren’t there as a hint. There are several tricks we can do but I need to give this some thought especially how they will work with something like a floating hint\nWe need to handle error messages in a standard way\nI hope to address all of those quicker than I got around to doing this installment…​ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\n3lix — February 11, 2018 at 2:19 am (permalink) Is there a way I can get the same code above to produce the Android style on IOS using the TextComponent?\nShai Almog — February 11, 2018 at 7:32 am (permalink) Are you referring to this API or the improved one from part 2: https://www.codenameone.com…\nGenerally you can get this to work by styling the text and defining the theme constants in your theme to make it look like the Android version. After working with the Uber app one of my conclusions is that we need a Material theme that’s cross platform. I’m not sure when I’ll get around to do that but I think it’s generally a good idea to offer that as one of the options. I have some thoughts on this that I still need to define as there are some edge cases.\n3lix — February 11, 2018 at 5:22 pm (permalink) I meant the API from part 2. I just noticed the newly added theme constants! Thanks\n+1 for cross platform Material theme.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/pixel-perfect-text-input/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/pixel-perfect-text-input/pixel-perfect.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI started working on this post back in August and so much happened in between I just had to scrap the whole thing and start over again…​ I’ve discussed buttons before and now it’s time for \u003ccode\u003eTextField\u003c/code\u003e \u0026amp; \u003ccode\u003eTextArea\u003c/code\u003e. But before we go into that lets take a moment to talk about the problems that arose from the \u003ca href=\"/blog/pixel-perfect-material-buttons-part-2.html\"\u003elast installment of pixel perfect\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eI made a lot of changes to Codename One but there was one particularly painful change: caps text. This proved to be a far more controversial change than I had intended and I had an \u003ca href=\"http://disq.us/p/1l8b041\" target=\"_blank\" rel=\"noopener noreferrer\"\u003einteresting debate with Nick\u003c/a\u003e. I’d appreciate participation in the thread there or here. The gist of the debate is how can we change functionality people rely on without disrupting working code. I honestly didn’t think the caps text change was a big change or would cause the problems it did. However, having said that it’s really hard to rollout a feature without disrupting developers occasionally.\u003c/p\u003e","title":"Pixel Perfect – Text Input"},{"content":"\n__ The information in this blog post is slighly out of date. Check out the newer blog post that covers positioning components on the map. I’ve recently added a segment to the online course covering the native maps. This segment is a part of a larger trend towards the upcoming Uber demo which we will release before the end of the year. As part of that work I did some initial \u0026ldquo;half baked\u0026rdquo; work on a map layout manager.\nThe motivation was to position components on top of the map in an effective way, I hacked this a bit and mixed some logic from the map and the layout thus breaking some of the separation but it’s still a pretty cool demo…​\nThe main thing to learn here is just how easy it is to build your own layout manager, don’t shy away from doing that if you need more control. The case for maps is great because we want to position components based on longitude/latitude values and this works perfectly with the layout manager semantics.\nThis is the layout manager I created, you’ll notice the code is really simple:\npublic class MapLayout extends Layout implements MapListener { private static final String COORD_KEY = \u0026quot;$coord\u0026quot;; private MapContainer map; private Container actual; public MapLayout(MapContainer map, Container actual) { this.map = map; this.actual = actual; map.addMapListener(this); } @Override public void addLayoutComponent(Object value, Component comp, Container c) { comp.putClientProperty(COORD_KEY, (Coord)value); } @Override public boolean isConstraintTracking() { return true; } @Override public Object getComponentConstraint(Component comp) { return comp.getClientProperty(COORD_KEY); } @Override public boolean isOverlapSupported() { return true; } @Override public void layoutContainer(Container parent) { for(Component current : parent) { Coord crd = (Coord)current.getClientProperty(COORD_KEY); Point p = map.getScreenCoordinate(crd); current.setSize(current.getPreferredSize()); current.setX(p.getX() - current.getWidth() / 2); current.setY(p.getY() - current.getHeight()); } } @Override public Dimension getPreferredSize(Container parent) { return new Dimension(100, 100); } @Override public void mapPositionUpdated(Component source, int zoom, Coord center) { actual.setShouldCalcPreferredSize(true); actual.revalidate(); } } I can use it like this:\nForm mapDemo = new Form(\u0026quot;Maps\u0026quot;, new LayeredLayout()); mapDemo.getToolbar().addMaterialCommandToSideMenu(\u0026quot;Hi\u0026quot;, FontImage.MATERIAL_3D_ROTATION, e -\u0026gt; {}); if(BrowserComponent.isNativeBrowserSupported()) { MapContainer mc = new MapContainer(JS_API_KEY); mapDemo.add(mc); Container markers = new Container(); markers.setLayout(new MapLayout(mc, markers)); mapDemo.add(markers); Coord moscone = new Coord(37.7831, -122.401558); Button mosconeButton = new Button(\u0026quot;\u0026quot;); FontImage.setMaterialIcon(mosconeButton, FontImage.MATERIAL_PLACE); markers.add(moscone, mosconeButton); mc.zoom(moscone, 5); } else { // iOS Screenshot process... mapDemo.add(new Label(\u0026quot;Loading, please wait....\u0026quot;)); } mapDemo.show(); Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-map-layout-manager/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-map-layout-manager/tip.jpg\"\u003e\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eThe information in this blog post is slighly out of date. Check out the \u003ca href=\"/blog/map-component-positioning-revisited.html\"\u003enewer blog post\u003c/a\u003e that covers positioning components on the map.\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eI’ve recently added a segment to the \u003ca href=\"https://codenameone.teachable.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eonline course\u003c/a\u003e covering the native maps. This segment is a part of a larger trend towards the upcoming Uber demo which we will release before the end of the year. As part of that work I did some initial \u0026ldquo;half baked\u0026rdquo; work on a map layout manager.\u003c/p\u003e","title":"TIP: Map Layout Manager"},{"content":"\nBackgrounds include a lot of nuance, especially the part covering the priorities which I start with in the tutorial below. Because of that this is one of the longer how do I videos I’ve done in a while as there is just so much to cover. I still had to cut a lot of stuff away and focus almost entirely on the designer tool.\nStyling in code isn’t covered at all in the video. I think most developers who would prefer hand coding would probably feel more comfortable learning from the developer guide which covers all of that already. I also didn’t cover the CSS support although there is some discussion of that in the academy.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-background-images-borders-gradients/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-background-images-borders-gradients/learn-codenameone-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eBackgrounds include a lot of nuance, especially the part covering the priorities which I start with in the tutorial below. Because of that this is one of the longer \u003ca href=\"/how-do-i.html\"\u003ehow do I videos\u003c/a\u003e I’ve done in a while as there is just so much to cover. I still had to cut a lot of stuff away and focus almost entirely on the designer tool.\u003c/p\u003e\n\u003cp\u003eStyling in code isn’t covered at all in the video. I think most developers who would prefer hand coding would probably feel more comfortable learning from the developer guide which covers all of that already. I also didn’t cover the CSS support although there is some discussion of that in \u003ca href=\"https://codenameone.teachable.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ethe academy\u003c/a\u003e.\u003c/p\u003e","title":"Tutorial – Background, Images, Borders and Gradients"},{"content":"\nLast week scrolling broke and we had a few relatively complex regressions. This can be traced back to a change we did to the getComponentAt(x, y) method, this change in itself fixed a problematic bug but triggered far worse bugs and we just had to revert the whole thing…​\nSo why did we even do a change to a method that’s so deep in the code and so risky?\nThe logic behind that is to prevent situations like this. getComponentAt(x, y) is a remarkably important method which is used all over the place to implement touch interface logic. Unfortunately, as one of those methods that evolved it became \u0026ldquo;unwieldy\u0026rdquo; and because it’s so deep we tried to avoid changing it…​\nDon’t touch it! It works!\n— Hacker Culture\nThese types of methods exist in every project and they form code rot around them. That’s why we try to avoid that mentality and try to improve on the things that are working. Sometimes in cases such as this, we fail. But more often than not we succeed and that is truly important.\nWhy this Method? As I mentioned before getComponentAt(x, y) is used internally all over the place. The benefit of code reuse goes well beyond basic aesthetics and code reduction. It guarantees better test coverage, increased stability and performance as the compiler \u0026amp; optimizations can do much more.\nHowever, that also means a method can become a point of hacks that impact everyone. So now that we reverted the change we’ll need to go over every use case and surgically remove the usage of this method so we can understand why these regressions happened and hopefully make the code more sensible.\nUnfortunately, this delays our planned migration to the on-top side menu which we were hoping to do this week. Right now the menu just doesn’t work properly with peer components which was the exact fix we aimed at here.\nWhat does that Mean? It means we might not be able to finish everything we wanted for the 3.8 release and need to move even more things to 3.9. Accessibility is something I specifically wanted to deliver for 3.8 but it’s a non-trivial feature so it probably won’t make it with our existing commitments.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/dont-touch-that-code/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/dont-touch-that-code/generic-java-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eLast week scrolling broke and we had a few relatively complex regressions. This can be traced back to a change we did to the \u003ccode\u003egetComponentAt(x, y)\u003c/code\u003e method, this change in itself fixed a problematic bug but triggered far worse bugs and we just had to revert the whole thing…​\u003c/p\u003e\n\u003cp\u003eSo why did we even do a change to a method that’s so deep in the code and so risky?\u003c/p\u003e","title":"Don't Touch That Code"},{"content":"\nOne of the less familiar features of Java is the mess of weak/soft/phantom references. This is a confusing mess and it’s compounded by the fact that other languages (such as the reference counting Swift/Objective-C) have used these terms with a different meaning. To simplify this weak references in a garbage collected language allows you to keep a pointer (reference) to an object that won’t force it to stay in RAM.\nThis can be made clearer by this sample:\nclass MyObject { private Object otherObjectInCache; // ... rest of code } Lets imagine that otherObjectInCache is an object that’s expensive to load e.g. an image. As long as MyObject is in RAM the otherObjectInCache won’t be removed from RAM and this might take up a lot of memory that could be used elsewhere…​\nThe thing is we don’t know. We might have a lot of RAM but we might not, this varies based on the device and checking OS memory is problematic in multi-tasking OS’s and GC languages. What we really want is:\nIf we have extra RAM we want to keep the object in memory\nIf we run out of RAM we are happy to just reload the object as needed\nA weak reference allows you to keep a reference to an object that can still be removed by the GC if it needs the RAM. Standard Java code for weak references looks like this:\nimport java.lang.ref.WeakReference; class MyObject { private WeakReference otherObjectInCache; public void codeThatNeedsObject() { if(otherObjectInCache != null) { Object cachedData = otherObjectInCache.get(); if(cachedData != null) { // use cachedData return; } } // object was gc'd Object cachedData = loadObject(); // store the object in the weak reference otherObjectInCache = new WeakReference(cachedData); } // ... rest of code } Notice that once the cachedData variable is not null we have a hard reference in RAM so that object won’t be GC’d until hard references are gone.\nThis works rather well in Codename One and elsewhere but there is an even better option: SoftReference. Weak references are GC’d relatively aggressively but this isn’t as true for SoftReference. Unfortunately not all target OS’s of Codename One support SoftReference so we can’t support the official JDK version of that. That’s why we have a slightly different API that you should probably use:\nstatic import com.codename1.ui.CN.*; class MyObject { private Object otherObjectInCache; public void codeThatNeedsObject() { if(otherObjectInCache != null) { Object cachedData = extractHardRef(otherObjectInCache); if(cachedData != null) { // use cachedData return; } } // object was gc'd Object cachedData = loadObject(); // store the object in the weak reference otherObjectInCache = createSoftWeakRef(cachedData); } // ... rest of code } __ This relies on a change to the CN class that will be a part of next weeks update, right now you can use the Display class which provides this functionality Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMartin Grajcar — November 4, 2018 at 4:38 pm (permalink) Martin Grajcar says:\nAfter reading this, I was rather confused (Why no generics? Where are the methods? Why Object?). After downloading the sources and using grep -r, I found Display#createSoftWeakRef, so it has got better. Then I’ve found WeakHashMap, which is probably what we should use most of the time, right?\nShai Almog — November 5, 2018 at 5:25 am (permalink) Shai Almog says:\nThe static API in CN mentioned a bit lower in the post is a newer version of the API in Display. The original API predated generification of the code base so it stayed that way. Might be worth updating for generics at some point.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-weak-references/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-weak-references/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the less familiar features of Java is the mess of weak/soft/phantom references. This is a confusing mess and it’s compounded by the fact that other languages (such as the reference counting Swift/Objective-C) have used these terms with a different meaning. To simplify this weak references in a garbage collected language allows you to keep a pointer (reference) to an object that won’t force it to stay in RAM.\u003c/p\u003e","title":"TIP: Use Weak References"},{"content":"\nVersioned builds are one of the more confusing features of Codename One mostly because the word \u0026ldquo;version\u0026rdquo; is so overloaded with meaning. The feature itself is remarkably simple as explained in this video tutorial.\nVersioned builds allow you to build against a fixed point release version of Codename One, that means that if we break something in the build servers you can still work against the last major version that we released.\nThis is also useful in cases where you want to see if something failed recently and also for getting consistent build results so you can update Codename One versions at your own pace. There is a limit to how far back we can support. The mobile world moves very fast so keeping support for older versions of Codename One is just impractical in the long term. However, this allows you to slow down the fast pace of progress a little bit.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-versioned-builds-repeatable-builds/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-versioned-builds-repeatable-builds/learn-codenameone-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eVersioned builds are one of the more confusing features of Codename One mostly because the word \u0026ldquo;version\u0026rdquo; is so overloaded with meaning. The feature itself is remarkably simple as explained in this video tutorial.\u003cbr\u003e\nVersioned builds allow you to build against a fixed point release version of Codename One, that means that if we break something in the build servers you can still work against the last major version that we released.\u003c/p\u003e","title":"Tutorial – Versioned Builds/Repeatable Builds"},{"content":"\nI did a lot of work on the developer guide PDF making it more suitable to print, as part of this work I submitted the guide to Amazons KDP which means you can now order a physical book of the developer guide. I reduced the page count significantly for lower cost and image size requirements. As a result the book is much smaller but contains the exact same information in a denser package.\nYou can order the book on Amazon, make sure you select the print edition.\nMedia Controls \u0026amp; Stability Steve did a lot of work on media over the past week and it should be more stable/consistent across platforms. One of the big changes is support for native video controls which up until now was platform specific. Starting with the next update you would be able to hint to the player whether you want native playback controls or not by using this code to show the native controls:\nsomeMedia.setVariable(Media.VARIABLE_NATIVE_CONTRLOLS_EMBEDDED, true); You can use false to hide them.\nOn Top Sidemenu Update \u0026amp; Regressions We’ve put a lot of effort into refining the on-top sidemenu which is already showing a lot of promise. Unfortunately one of the changes we made caused a regression to the general functionality of Codename One. We’ve posted a fix and might push an earlier update to the libs before Friday to workaround this issue.\nThe on-top side menu is still off by default and will remain that way with the coming update due to these regressions. We still think it’s important to turn this on by default with enough time for the 3.8 release so this feature becomes stable.\nSo far the on-top side menu is a huge improvement especially in UI’s that contain native peers such as Maps where this feature is invaluable. The regular side menu causes a noticeable flicker which doesn’t happen with the on-top variety. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — October 18, 2017 at 10:28 am (permalink) Francesco Galgani says:\nAt the moment, the developer guide pdf has 576 pages. Is this the reduced version?\nhttps://www.codenameone.com…\nI prefer to print by myself the book, because the shipping cost from USA to my country is very expensive (a lot more than the book itself).\nShai Almog — October 19, 2017 at 5:56 am (permalink) Shai Almog says:\nYes it’s the reduced size. The original was just under 1000 pages…\nPersonally I prefer the feel of a professionally printed/bound book over A4’s. Either way we don’t make a profit over the book (it’s just printing costs) so feel free to print it yourself.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/media-controls-print-developer-guide/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/media-controls-print-developer-guide/new-features-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI did a lot of work on the developer guide PDF making it more suitable to print, as part of this work I submitted the guide to Amazons KDP which means you can now order a physical book of the developer guide. I reduced the page count significantly for lower cost and image size requirements. As a result the book is much smaller but contains the exact same information in a denser package.\u003c/p\u003e","title":"Media Controls and Print Developer Guide"},{"content":"\nA few weeks back maaartinus asked on stack overflow whether we can get lombok working with Codename One. After a short back and forth it seems that this was as easy as I’d hoped and he was able to get it working without a change.\nPersonally, I like our approach of property objects more but that’s obviously a matter of taste. Lombok works by processing the bytecode after compilation to convert annotations to terse code. E.g. this Java code using Lombok:\n@Getter @Setter @NonNull private List\u0026lt;Person\u0026gt; members; Would be similar to this regular Java code:\nprivate List\u0026lt;Person\u0026gt; members; public Family(final List\u0026lt;Person\u0026gt; members) { if (members == null) throw new java.lang.NullPointerException(\u0026quot;members\u0026quot;); this.members = members; } public List\u0026lt;Person\u0026gt; getMembers() { return members; } public void setMembers(final List\u0026lt;Person\u0026gt; members) { if (members == null) throw new java.lang.NullPointerException(\u0026quot;members\u0026quot;); this.members = members; } __ I took the code sample above from here That’s pretty nice and it has some other features that hide some of the verbosity of Java.\nAs mentioned in the answer adding Lombok to a Codename One application is pretty easy:\nJust add the lombok.jar to the build path which you can find in the project settings for the native IDE\nIn the build.xml replace compiler=\u0026quot;modern\u0026quot; with compiler=\u0026quot;extJavac\u0026quot;\nAdd the path to lombok.jar to the classpath in the build.xml (this might not be necessary in NetBeans)\nDoing this for Other Things Lombok is just one of a huge set of bytecode manipulation tools that work statically. I’m sure there are many other tools like that in the wild that would \u0026ldquo;just work\u0026rdquo; and we never got around to test them.\nIf you have a pet tool in your toolbox check it out and see if it works with Codename One. You might be surprised. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMartin Grajcar — November 9, 2018 at 2:05 am (permalink) Martin Grajcar says:\nYou’re wrong concerning how Lombok works. It does AST manipulation rather than bytecode manipulation. That’s a black magic necessary as without the stuff generated by Lombok, the code won’t usually compile (and you’d get no bytecode to play with). But this is just a detail, the important thing is that it’s job is done in the compiler.\nShai Almog — November 9, 2018 at 6:48 am (permalink) Shai Almog says:\nI should have phrased it differently. It manipulates the bytecode statically which is the point that matters to us. I don’t really care about the underlying implementation and had no interest in it.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-using-lombok-other-tools/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-using-lombok-other-tools/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA few weeks back \u003ca href=\"https://stackoverflow.com/users/581205/maaartinus\" target=\"_blank\" rel=\"noopener noreferrer\"\u003emaaartinus\u003c/a\u003e \u003ca href=\"https://stackoverflow.com/questions/46125982/using-codenameone-with-lombok-in-eclipse\" target=\"_blank\" rel=\"noopener noreferrer\"\u003easked\u003c/a\u003e on stack overflow whether we can get \u003ca href=\"https://projectlombok.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003elombok\u003c/a\u003e working with Codename One. After a short back and forth it seems that this was as easy as I’d hoped and he was able to get it working without a change.\u003c/p\u003e\n\u003cp\u003ePersonally, I like our approach of \u003ca href=\"/how-do-i/how-do-i-use-properties-to-speed-development/\"\u003eproperty objects\u003c/a\u003e more but that’s obviously a matter of taste. Lombok works by processing the bytecode after compilation to convert annotations to terse code. E.g. this Java code using Lombok:\u003c/p\u003e","title":"TIP: Using Lombok and Other tools"},{"content":"\nCodename One has ports for Mac, Windows \u0026amp; even for the browser. These are often confused and the introduction of the UWP port which also includes some overlap only made matters worse. Each one of these ports covers a segment that the other ports don’t.\nIn this tutorial I try to separate the various ports \u0026amp; explain when each one of them should be used. I also dispel common misconceptions about these ports. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — November 5, 2017 at 10:50 am (permalink) Francesco Galgani says:\nWhere are some working examples of the javascript port of some apps?\nPlease also note the the link \u0026ldquo;Developer guide section covering the JavaScript port\u0026rdquo; in the page \u0026ldquo;How Do I – Use the Desktop and JavaScript Ports\u0026rdquo; is broken (the word \u0026ldquo;manual\u0026rdquo; in the URL is duplicated).\nShai Almog — November 6, 2017 at 2:31 pm (permalink) Shai Almog says:\nThanks! We’ll fix the links.\nYou can look at the demos in the demo section. Each one of them has a JavaScript link among the links in the bottom.\nFrancesco Galgani — November 7, 2017 at 8:03 pm (permalink) Francesco Galgani says:\nI’m thinking to upgrade my account to Enterprise because I really interested in the javascript port. My idea is to develop from scratch an app for smartphone and tablet and a web site using the same code: is it possible? Your demos have some problems…\nIn my opinion, the user experience needs to be improved, because the user expects to have an hand cursor on clickable elements, but this doesn’t happen. Is it possible?\nPlease note that the PropertyCross demo doesn’t work properly: open the js port and on search write \u0026ldquo;London\u0026rdquo;, and then click on Go. You will have a \u0026ldquo;Searching…\u0026rdquo; form with an infinitive loop, but nothing more, no results (tested on Chrome and Firefox on Linux and Windows). More over, the Poker demo js port doesn’t work at all: try to open it, you will get a white page (tested on Chrome and Firefox on Linux).\nI didn’t tested all the demos, maybe they need a check. At the moment my first impression is not the best, but I hope that all the problems are resolvable.\nShai Almog — November 8, 2017 at 5:12 am (permalink) Shai Almog says:\nWe support cursor behavior in the current version of Codename One (I think it was added for 3.7) but we don’t implicitly change the mouse cursor. This should work on JavaScript and in the simulator see https://www.codenameone.com…\nI just tried the pocker demo and it worked for me, it took a few seconds to load so maybe some hiccup happened during download on your end?\nProperty cross seems to freeze when accessing the network, we might have an issue in our webserver as we need to proxy server calls to workaround the \u0026ldquo;same origin\u0026rdquo; restriction. We’ll have to look into that.\nFrancesco Galgani — November 12, 2017 at 12:04 am (permalink) Francesco Galgani says:\nThank you for the Mouse Cursor tip.\nI cannot open the Poker demo on my computer, I tried different browsers.\nThis is the console output of the Poker demo (js port) on my updated version of Google Chrome:\nfontmetrics.js:69 [Deprecation] ‘window.webkitStorageInfo’ is deprecated. Please use ‘navigator.webkitTemporaryStorage’ or ‘navigator.webkitPersistentStorage’ instead.\n(anonymous) @ fontmetrics.js:69\n(index):1 Uncaught (in promise) DOMException: The requested version (1) is less than the existing version (2).\nTString.java:147 Uncaught (in promise) TypeError: Cannot read property ‘J9’ of null\nat C (TString.java:147)\nat $rt_ustr (classes.js:4)\nat ThB (classes.js:4666)\nat PJ (TLogger.java:60)\nat JEB (TLogger.java:130)\nat Y0 (HTML5Implementation.java:2390)\nat Gy (Storage.java:171)\nat BeB (Preferences.java:43)\nat YRC (Preferences.java:233)\nat Nj (CodenameOneImplementation.java:211)\nShai Almog — November 12, 2017 at 5:17 am (permalink) Shai Almog says:\nThanks for the headsup. I think there might have been a change in chrome that we already adapted the code to but didn’t refresh this demo (I use firefox and it works on it). I just sent a new build and it works, we’ll update the demo a bit later but you can check out a live preview here: https://codename-one.appspo…\nNotice that like all Codename One build links this will expire in a couple of days.\nFrancesco Galgani — November 12, 2017 at 12:53 pm (permalink) Francesco Galgani says:\nVery good news: the live preview you linked works correctly 🙂\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-desktop-javascript-ports/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-desktop-javascript-ports/learn-codenameone-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One has ports for Mac, Windows \u0026amp; even for the browser. These are often confused and the introduction of the UWP port which also includes some overlap only made matters worse. Each one of these ports covers a segment that the other ports don’t.\u003c/p\u003e\n\u003ch2 id=\"in-this-tutorial-i-try-to-separate-the-various-ports--explain-when-each-one-of-them-should-be-used-i-also-dispel-common-misconceptions-about-these-ports\"\u003eIn this tutorial I try to separate the various ports \u0026amp; explain when each one of them should be used. I also dispel common misconceptions about these ports.\u003c/h2\u003e\n\u003ch2 id=\"archived-comments\"\u003eArchived Comments\u003c/h2\u003e\n\u003cp\u003e\u003cem\u003eThis post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\u003c/em\u003e\u003c/p\u003e","title":"Tutorial – Desktop and JavaScript Ports"},{"content":"\nI’ve added two modules recently to the deep dive course in the academy. These are a part of a trends together with the SMS activation posts I’ve done over the past couple of weeks. These are all preparations for the upcoming Uber demo that will launch before the end of the year.\nSo the first module I added is a security module which I think I mentioned before, the one I added just last week explains the process of working with native maps and the various types of maps we have in Codename One. It goes all the way from basic to drawing stuff on top of the map and building for the various devices (including plot twists like build failures…​).\nAs you can see this is all part of a bigger plot so if you didn’t signup for the academy now is the time to ask your boss…​\nComscore Diamond built and submitted a new comscore analytics cn1lib to replace the older version built by Fabricio.\nI didn’t use Comscore much but if you need better insight into your users than the one provided by google analytics this is a good place to start. It’s also a very interesting library since the integration wasn’t trivial and you can learn some nuances from the build hints used.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/security-map-tutorial-comscore/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/security-map-tutorial-comscore/deep-dive-into-mobile.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve added two modules recently to the \u003ca href=\"https://codenameone.teachable.com/p/deep-dive-into-mobile-development-with-codename-one\" target=\"_blank\" rel=\"noopener noreferrer\"\u003edeep dive course\u003c/a\u003e in \u003ca href=\"https://codenameone.teachable.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ethe academy\u003c/a\u003e. These are a part of a trends together with the SMS activation posts I’ve done over the past couple of weeks. These are all preparations for the upcoming Uber demo that will \u003ca href=\"https://codenameone.teachable.com/p/build-real-world-full-stack-mobile-apps-in-java\" target=\"_blank\" rel=\"noopener noreferrer\"\u003elaunch before the end of the year\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eSo the first module I added is a security module which I think I mentioned before, the one I added just last week explains the process of working with native maps and the various types of maps we have in Codename One. It goes all the way from basic to drawing stuff on top of the map and building for the various devices (including plot twists like build failures…​).\u003c/p\u003e","title":"Security, Map Tutorial and ComScore"},{"content":"\nI wrote two posts about the SMS activation process. In the first I discussed using the Twilio API via REST and in the second I discussed the native interfaces for SMS interception we can use in Android. Now it’s time to put this all together and create a single API that’s fluid. It should include the full UI process but be flexible enough to let you design your own experience.\nThe Builder I wanted to create a UI experience that’s pretty typical and standard while hiding a lot of nuance. My first intuition was to just derive Form and build the UI. But that’s not a good approach.\nWhen you derive a component you expose the entire API of the base class onward, that creates a confusing UI API so I decided to expose a builder API which looks something like this:\nTwilioSMS smsAPI = TwilioSMS.create(accountSID, authToken, fromPhone); ActivationForm.create(\u0026quot;Signup\u0026quot;). show(s -\u0026gt; Log.p(s), smsAPI); There are several things going on here. I wrapped the code from the SMS rest calls in an API called TwilioSMS. This allows me to hide the details of sending an SMS from the ActivationForm UI class. You will notice I create an instance of this class using the create method which accepts the title of the form. I then have a show method which calls us back with the phone number when activation succeeds…​\nSince this is a builder pattern you can customize all sorts of things:\nActivationForm.create(\u0026quot;Signup\u0026quot;). codeDigits(5). // number of digits in the activation code sent via SMS enterNumberLabel(string). // text of the label above the number input includeFab(true). // true if a fab should be shown, by default a fab button will appear in Android only includeTitleBarNext(true). // true if a next arrow should appear in the title, by default this would appear in non-Android platforms show(s -\u0026gt; Log.p(s), smsAPI); The neat thing is that you can’t do all sorts of things you aren’t supposed to do as the ActivationForm class derives from Object and has a private constructor.\nThe UI for the activation form shows a form on top of the current form with a number entry UI.\nFigure 1. The SMS activation UI/UX\nFigure 2. When clicking on the country code you are prompted with a list of countries\nObtaining the list of Countries I got the list of flags and countries from https://mledoze.github.io/countries/\nI converted the flags SVG’s to PNG’s and added them all to the flags.res file. This is more efficient than opening multiple pngs from the system. I considered using the SVG files with our transcoder but decided against it due to the immaturity and possible performance issues of the tool. Flags are sensitive things and a bug in the transcoder might mean we do something offensive.\nI couldn’t skip the flags as they provide a visual element that changes the perception of the UI completely.\nI considered shipping the app with the JSON data file but it includes a lot of information I don’t need and weighs 500kb. So I wrote a quick app that just printed out the data as arrays and I pasted them into the source file. This is an important step as the list might change and we’d need to go thru it again…​ This is how I parsed the JSON, I just ran this in the simulator and pasted the output into the Java source file:\nprivate static final CaseInsensitiveOrder cio = new CaseInsensitiveOrder(); class Country implements Comparable\u0026lt;Country\u0026gt; { public final String name; public final String code; public final String flag; public final String isoCode2; public final String isoCode3; public Country(String name, String code, String flag, String isoCode2, String isoCode3) { this.name = name; this.code = code; this.flag = flag; this.isoCode2 = isoCode2; this.isoCode3 = isoCode3; } @Override public int compareTo(Country o) { return cio.compare(name, o.name); } } ArrayList\u0026lt;Country\u0026gt; con = new ArrayList\u0026lt;\u0026gt;(); try { JSONParser p = new JSONParser(); Map\u0026lt;String, Object\u0026gt; dat = p.parseJSON(new InputStreamReader(getResourceAsStream(\u0026quot;/countries.json\u0026quot;))); __**(1)** List\u0026lt;Map\u0026lt;String, Object\u0026gt;\u0026gt; l = (List\u0026lt;Map\u0026lt;String, Object\u0026gt;\u0026gt;)dat.get(\u0026quot;root\u0026quot;); for(Map\u0026lt;String, Object\u0026gt; m : l) { __**(2)** List ll = ((List)m.get(\u0026quot;callingCode\u0026quot;)); if(ll != null \u0026amp;\u0026amp; ll.size() \u0026gt; 0) { String name = (String)((Map)m.get(\u0026quot;name\u0026quot;)).get(\u0026quot;common\u0026quot;); String callingCode = (String)ll.get(0); String code = (String)m.get(\u0026quot;cioc\u0026quot;); String flag = null; if(code != null \u0026amp;\u0026amp; code.length() \u0026gt; 0) { flag = code.toLowerCase(); } String isoCode2 = (String)m.get(\u0026quot;cca2\u0026quot;); String isoCode3 = (String)m.get(\u0026quot;cca3\u0026quot;); con.add(new Country(name, callingCode, flag, isoCode2, isoCode3)); __**(3)** } } } catch(IOException err) { Log.e(err); } Collections.sort(con); __**(4)** System.out.println(\u0026quot;private static final String[] COUNTRY_NAMES = {\u0026quot;); for(Country c : con) { __**(5)** System.out.println(\u0026quot; \u0026quot;\u0026quot; + c.name + \u0026quot;\u0026quot;,\u0026quot;); } System.out.println(\u0026quot;};\u0026quot;); System.out.println(\u0026quot;private static final String[] COUNTRY_CODES= {\u0026quot;); for(Country c : con) { System.out.println(\u0026quot; \u0026quot;\u0026quot; + c.code + \u0026quot;\u0026quot;,\u0026quot;); } System.out.println(\u0026quot;};\u0026quot;); System.out.println(\u0026quot;private static final String[] COUNTRY_FLAGS = {\u0026quot;); for(Country c : con) { if(c.flag == null) { System.out.println(\u0026quot; null,\u0026quot;); } else { System.out.println(\u0026quot; \u0026quot;\u0026quot; + c.flag + \u0026quot;\u0026quot;,\u0026quot;); } } System.out.println(\u0026quot;};\u0026quot;); System.out.println(\u0026quot;private static final String[] COUNTRY_ISO2 = {\u0026quot;); for(Country c : con) { System.out.println(\u0026quot; \u0026quot;\u0026quot; + c.isoCode2 + \u0026quot;\u0026quot;,\u0026quot;); } System.out.println(\u0026quot;};\u0026quot;); System.out.println(\u0026quot;private static final String[] COUNTRY_ISO3 = {\u0026quot;); for(Country c : con) { System.out.println(\u0026quot; \u0026quot;\u0026quot; + c.isoCode3 + \u0026quot;\u0026quot;,\u0026quot;); } System.out.println(\u0026quot;};\u0026quot;); Most of that code is pretty simple:\n__1 I load the JSON file from the resources __2 I loop over the entries within the JSON file one by one __3 I construct a Country object based on the entry data __4 Country is sortable thanks to the Comparable interface so I can just sort the list __5 Now I can just create the 5 String arrays I want Yes, I know I could have kept the Country object and worked with that instead of 5 String arrays…​ I might change to that in the future.\nPackaging it into a CN1LIB Diamond surprised me a couple of weeks ago when he packaged my last post as a cn1lib. I think that’s great if what you need is interception of SMS messages.\nThis cn1lib is pretty different in its goals. I wanted to solve a very specific and restricted use case of validating a user with an SMS. So while we have some things in common with our cn1libs the basic premise is pretty far apart and it shows.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-activation-ui-builder-pattern/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-activation-ui-builder-pattern/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI wrote \u003ca href=\"/blog/tip-send-device-activation-sms-via-twilio.html\"\u003etwo posts\u003c/a\u003e about the \u003ca href=\"/blog/tip-intercept-incoming-sms-on-android.html\"\u003eSMS activation process\u003c/a\u003e. In the first I discussed using the Twilio API via REST and in the second I discussed the native interfaces for SMS interception we can use in Android. Now it’s time to put this all together and create a single API that’s fluid. It should include the full UI process but be flexible enough to let you design your own experience.\u003c/p\u003e","title":"TIP: Activation UI and the Builder Pattern"},{"content":"\nOffline build is a pretty complex topic which is why we opted for the online build process in Codename One. It allows for simple install/build and doesn’t require a Mac. However, if you work for a bank or a government agency using a cloud solution is sometimes an insurmountable roadblock. That’s why we introduced the offline build option to replace our old private cloud option.\nIt isn’t ideal, building offline essentially forfeits some of the key advantages of Codename One and surprisingly slows down the build process (our servers are really fast). But when developers need to choose between this and the other available options there is still some appeal. In this tutorial I scratch the surface of offline build and also explain its unique licensing status. Unlike the standard Codename One services, this is an offline service so it will keep building even without a license. This is especially important for enterprises that need safety moving forward and a guarantee they will be able to build their apps in the future.\nIt also allows far more stability when compared to server builds as you can pick a specific offline builder and just keep historical copies.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-offline-build/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-offline-build/learn-codenameone-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOffline build is a pretty complex topic which is why we opted for the online build process in Codename One. It allows for simple install/build and doesn’t require a Mac. However, if you work for a bank or a government agency using a cloud solution is sometimes an insurmountable roadblock. That’s why we introduced the offline build option to replace our old private cloud option.\u003c/p\u003e\n\u003cp\u003eIt isn’t ideal, building offline essentially forfeits some of the key advantages of Codename One and surprisingly slows down the build process (our servers are really fast). But when developers need to choose between this and the other available options there is still some appeal. In this tutorial I scratch the surface of offline build and also explain its unique licensing status. Unlike the standard Codename One services, this is an offline service so it will keep building even without a license. This is especially important for enterprises that need safety moving forward and a guarantee they will be able to build their apps in the future.\u003c/p\u003e","title":"Tutorial – Offline Build"},{"content":"\nIt’s been a busy week with 3.7.3 released and a lot of new things. Diamond made several PR’s over the past couple of weeks but one interesting PR is an \u0026ldquo;always on top\u0026rdquo; feature for the simulator which is exactly what it sounds…​\nThis is very useful for me personally as it will allow me to film coding while showing the simulator floating on top (thanks Diamond!) but it should be super useful for everyone. You can inspect the code/debugging values while the simulator floats on top. You can activate it using the simulator menu option.\nStyle Parser Styles are a pretty complex and deeply ingrained subject in Codename One. It’s really hard to extend or modify this without breaking everything…​\nSteve recently ventured on the surface and offered a new way in thru a String based style syntax that is a hybrid of CSS and Codename One logic. Don’t confuse this with the CSS plugin. The CSS plugin works statically during compile time and Codename One is \u0026ldquo;unaware\u0026rdquo; of its existence. The resulting file in the CSS file is a regular CSS file.\nThis new style mode is builtin to Codename One and overrides styles defined in the theme. This is useful for the GUI builder where you might want to customize the appearance of a component without venturing into the theme and creating a new UIID.\nYou can use this from code and might find some pretty cool hacks for it but this was built mostly to facilitate styling directly from the GUI builder. This can be used in the new GUI builder UI in the 3rd tab where you can now customize styles for components directly:\nFigure 1. Style customization from within the GUI builder\nThis is a new feature so some things might now work for the 3.7.3 release. Please let us know in the issue tracker\n__ In the current version there is a bug that might require you to close and reopen the UI for the styling to work As a sidenote the new GUI builder and autolayout mode have improved significantly since 3.7.2 and are far more pleasurable to use!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/always-on-top-style-parser/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/always-on-top-style-parser/new-features-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIt’s been a busy week with 3.7.3 released and a lot of new things. \u003ca href=\"https://github.com/diamondobama\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDiamond\u003c/a\u003e made several \u003ca href=\"https://github.com/codenameone/CodenameOne/pulls\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ePR’s\u003c/a\u003e over the past couple of weeks but one interesting PR is an \u0026ldquo;always on top\u0026rdquo; feature for the simulator which is exactly what it sounds…​\u003c/p\u003e\n\u003cp\u003eThis is very useful for me personally as it will allow me to film coding while showing the simulator floating on top (thanks Diamond!) but it should be super useful for everyone. You can inspect the code/debugging values while the simulator floats on top. You can activate it using the simulator menu option.\u003c/p\u003e","title":"Always on Top and Style Parser"},{"content":"\nLast week I talked about using SMS to activate your application which is a pretty powerful way to verify a user account. I left a couple of things out though. One of those things is the ability to grab the incoming SMS automatically. This is only possible on Android but it’s pretty cool for the users as it saves on the pain of typing the activation text.\nBroadcast Receiver In order to grab an incoming SMS we need a broadcast receiver which is a standalone Android class that receives a specific event type. This is often confusing to developers who sometimes derive the impl class from broadcast receiver…​ That’s a mistake…​\nThe trick is you can just place any native Android class into the native/android directory. It will get compiled with the rest of the native code and \u0026ldquo;just works\u0026rdquo;. So I placed this class under native/android/com/codename1/sms/intercept:\npackage com.codename1.sms.intercept; import android.content.*; import android.os.Bundle; import android.telephony.*; import com.codename1.io.Log; public class SMSListener extends BroadcastReceiver { @Override public void onReceive(Context cntxt, Intent intent) { // based on code from https://stackoverflow.com/questions/39526138/broadcast-receiver-for-receive-sms-is-not-working-when-declared-in-manifeststat if(intent.getAction().equals(\u0026quot;android.provider.Telephony.SMS_RECEIVED\u0026quot;)) { Bundle bundle = intent.getExtras(); SmsMessage[] msgs = null; if (bundle != null){ try{ Object[] pdus = (Object[]) bundle.get(\u0026quot;pdus\u0026quot;); msgs = new SmsMessage[pdus.length]; for(int i=0; i\u0026lt;msgs.length; i++){ msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]); String msgBody = msgs[i].getMessageBody(); SMSCallback.smsReceived(msgBody); } } catch(Exception e) { Log.e(e); SMSCallback.smsReceiveError(e); } } } } } The code above is pretty standard native Android code, it’s just a callback in which most of the logic is similar to the native Android code mentioned in this stackoverflow question.\nBut there is still more we need to do. In order to implement this natively we need to register the permission and the receiver in the manifest.xml file as explained in that question. This is how their native manifest looked:\n\u0026lt;?xml version=\u0026quot;1.0\u0026quot; encoding=\u0026quot;utf-8\u0026quot;?\u0026gt; \u0026lt;manifest xmlns_android=\u0026quot;http://schemas.android.com/apk/res/android\u0026quot; package=\u0026quot;com.bulsy.smstalk1\u0026quot;\u0026gt; \u0026lt;uses-permission android_name=\u0026quot;android.permission.RECEIVE_SMS\u0026quot; /\u0026gt; \u0026lt;uses-permission android_name=\u0026quot;android.permission.READ_SMS\u0026quot; /\u0026gt; \u0026lt;uses-permission android_name=\u0026quot;android.permission.SEND_SMS\u0026quot;/\u0026gt; \u0026lt;uses-permission android_name=\u0026quot;android.permission.READ_CONTACTS\u0026quot; /\u0026gt; \u0026lt;application android_allowBackup=\u0026quot;true\u0026quot; android_icon=\u0026quot;@mipmap/ic_launcher\u0026quot; android_label=\u0026quot;@string/app_name\u0026quot; android_supportsRtl=\u0026quot;true\u0026quot; android_theme=\u0026quot;@style/AppTheme\u0026quot;\u0026gt; \u0026lt;activity android_name=\u0026quot;.MainActivity\u0026quot;\u0026gt; \u0026lt;intent-filter\u0026gt; \u0026lt;action android_name=\u0026quot;android.intent.action.MAIN\u0026quot; /\u0026gt; \u0026lt;category android_name=\u0026quot;android.intent.category.LAUNCHER\u0026quot; /\u0026gt; \u0026lt;/intent-filter\u0026gt; \u0026lt;/activity\u0026gt; \u0026lt;receiver android_name=\u0026quot;com.bulsy.smstalk1.SmsListener\u0026quot; android_enabled=\u0026quot;true\u0026quot; android_permission=\u0026quot;android.permission.BROADCAST_SMS\u0026quot; android_exported=\u0026quot;true\u0026quot;\u0026gt; \u0026lt;intent-filter android_priority=\u0026quot;2147483647\u0026quot;\u0026gt;//this doesnt work \u0026lt;category android_name=\u0026quot;android.intent.category.DEFAULT\u0026quot; /\u0026gt; \u0026lt;action android_name=\u0026quot;android.provider.Telephony.SMS_RECEIVED\u0026quot; /\u0026gt; \u0026lt;/intent-filter\u0026gt; \u0026lt;/receiver\u0026gt; \u0026lt;/application\u0026gt; \u0026lt;/manifest\u0026gt; We only need the broadcast permission XML and the permission XML. Both are doable via the build hints. The former is pretty easy:\nandroid.xpermissions=\u0026lt;uses-permission android_name=\u0026quot;android.permission.RECEIVE_SMS\u0026quot; /\u0026gt; The latter isn’t much harder, notice I took multiple lines and made them into a single line for convenience:\nandroid.xapplication=\u0026lt;receiver android_name=\u0026quot;com.codename1.sms.intercept.SMSListener\u0026quot; android_enabled=\u0026quot;true\u0026quot; android_permission=\u0026quot;android.permission.BROADCAST_SMS\u0026quot; android_exported=\u0026quot;true\u0026quot;\u0026gt; \u0026lt;intent-filter android_priority=\u0026quot;2147483647\u0026quot;\u0026gt;\u0026lt;category android_name=\u0026quot;android.intent.category.DEFAULT\u0026quot; /\u0026gt; \u0026lt;action android_name=\u0026quot;android.provider.Telephony.SMS_RECEIVED\u0026quot; /\u0026gt; \u0026lt;/intent-filter\u0026gt; \u0026lt;/receiver\u0026gt; Here it is formatted nicely:\n\u0026lt;receiver android_name=\u0026quot;com.codename1.sms.intercept.SMSListener\u0026quot; android_enabled=\u0026quot;true\u0026quot; android_permission=\u0026quot;android.permission.BROADCAST_SMS\u0026quot; android_exported=\u0026quot;true\u0026quot;\u0026gt; \u0026lt;intent-filter android_priority=\u0026quot;2147483647\u0026quot;\u0026gt; \u0026lt;category android_name=\u0026quot;android.intent.category.DEFAULT\u0026quot; /\u0026gt; \u0026lt;action android_name=\u0026quot;android.provider.Telephony.SMS_RECEIVED\u0026quot; /\u0026gt; \u0026lt;/intent-filter\u0026gt; \u0026lt;/receiver\u0026gt; Listening \u0026amp; Permissions You will notice that these don’t include the actual binding or permission prompts you would expect for something like this. To do this we need a native interface.\nThe native sample in stack overflow bound the listener in the activity but here we want the app code to decide when we should bind the listening:\npublic interface NativeSMSInterceptor extends NativeInterface { public void bindSMSListener(); public void unbindSMSListener(); } That’s easy!\nNotice that isSupported() returns false for all other OS’s so we won’t need to ask whether this is \u0026ldquo;Android\u0026rdquo; we can just use isSupported().\nThe implementation is pretty easy too:\npackage com.codename1.sms.intercept; import android.Manifest; import android.content.IntentFilter; import com.codename1.impl.android.AndroidNativeUtil; public class NativeSMSInterceptorImpl { private SMSListener smsListener; public void bindSMSListener() { if(AndroidNativeUtil.checkForPermission(Manifest.permission.RECEIVE_SMS, \u0026quot;We can automatically enter the SMS code for you\u0026quot;)) { __**(1)** smsListener = new SMSListener(); IntentFilter filter = new IntentFilter(); filter.addAction(\u0026quot;android.provider.Telephony.SMS_RECEIVED\u0026quot;); AndroidNativeUtil.getActivity().registerReceiver(smsListener, filter); __**(2)** } } public void unbindSMSListener() { AndroidNativeUtil.getActivity().unregisterReceiver(smsListener); } public boolean isSupported() { return true; } } __1 This will trigger the permission prompt on Android 6 and newer. Even though the permission is declared in XML this isn’t enough for 6+. Notice that even when you run on Android 6 you still need to declare permissions in XML! __2 Here we actually bind the listener, this allows us to grab one SMS and not listen in on every SMS coming thru Callbacks Up until now the code wasn’t very usable so lets abstract it a bit. But first we need to implement the callback class to which SMS’s and errors are sent from the code above:\npackage com.codename1.sms.intercept; __**(1)** import com.codename1.util.FailureCallback; import com.codename1.util.SuccessCallback; import static com.codename1.ui.CN.*; /** * This is an internal class, it's package protect to hide that */ class SMSCallback { static SuccessCallback\u0026lt;String\u0026gt; onSuccess; static FailureCallback onFail; public static void smsReceived(String sms) { if(onSuccess != null) { SuccessCallback\u0026lt;String\u0026gt; s = onSuccess; onSuccess = null; onFail = null; SMSInterceptor.unbindListener(); callSerially(() -\u0026gt; s.onSucess(sms)); __**(2)** } } public static void smsReceiveError(Exception err) { if(onFail != null) { FailureCallback f = onFail; onFail = null; SMSInterceptor.unbindListener(); onSuccess = null; callSerially(() -\u0026gt; f.onError(null, err, 1, err.toString())); } else { if(onSuccess != null) { SMSInterceptor.unbindListener(); onSuccess = null; } } } } __1 Notice that the package is the same as the native code and the other classes. This allows the callback class to be package protected so it isn’t exposed via the API (the class doesn’t have the public modifier) __2 We wrap the callback in call serially to match the Codename One convention of using the EDT by default. The call will probably arrive on the Android native thread so it makes sense to normalize it and not expose the Android native thread to the user code A simple API The final piece of the puzzle is a simple API that can wrap the whole thing up and also hide the fact that this is Android specific. We’ll get into the full API in the last installment but for now this is the user level API that hides the native interface. Using a class like this is generally good practice as it allows us flexibility with the actual underlying native interface.\npackage com.codename1.sms.intercept; import com.codename1.system.NativeLookup; import com.codename1.util.FailureCallback; import com.codename1.util.SuccessCallback; /** * This is a high level abstraction of the native classes and callbacks rolled into one. */ public class SMSInterceptor { private static NativeSMSInterceptor nativeImpl; private static NativeSMSInterceptor get() { if(nativeImpl == null) { nativeImpl = NativeLookup.create(NativeSMSInterceptor.class); if(!nativeImpl.isSupported()) { nativeImpl = null; } } return nativeImpl; } public static boolean isSupported() { return get() != null; } public static void grabNextSMS(SuccessCallback\u0026lt;String\u0026gt; onSuccess) { SMSCallback.onSuccess = onSuccess; get().bindSMSListener(); } static void unbindListener() { get().unbindSMSListener(); } } Next Time Next time I will wrap this all up with the user experience and package everything into an easy to use cn1lib.\nSome of the things I touched here might be a bit \u0026ldquo;hairy\u0026rdquo; in terms of native interface usage so if something isn’t clear just ask in the comments. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDiamond — September 20, 2017 at 1:43 pm (permalink) Diamond says:\nI’ve wrapped up the code into a cn1lib here: https://github.com/diamondd…\nDiamond — September 21, 2017 at 7:11 am (permalink) Diamond says:\nI have no experience with c# code, but could this be implemented for Windows phones too? I found a lead here: https://msdn.microsoft.com/…\nShai Almog — September 21, 2017 at 8:05 am (permalink) Shai Almog says:\nI doubt that will work. It’s a pretty old document. You need to look for things that are relevant for UWP.\nDiamond — September 21, 2017 at 8:28 am (permalink) Diamond says:\nThis looks promising https://github.com/Microsof…\nDiamond — September 21, 2017 at 8:43 am (permalink) Diamond says:\nThe full sms API can be found here https://docs.microsoft.com/…\nGeorge Kent — September 21, 2017 at 9:00 am (permalink) George Kent says:\nHow stable and accurate is your UWP port. Is it ready for production on all your features mentioned in your dev guide?\nShai Almog — September 21, 2017 at 10:25 am (permalink) Shai Almog says:\nThat could work but I wouldn’t spend time on that. Notice it says that the sample will only work on unlocked devices and \u0026ldquo;will not pass WACK\u0026rdquo;. I’m not sure about this but I recall that if you use specific Windows features your app can’t be sold in China\nShai Almog — September 21, 2017 at 10:30 am (permalink) Shai Almog says:\nIt’s used in production. All is a tall order. It’s newer than the Android and iOS ports and not even remotely as popular so it doesn’t see nearly as much testing.\nRashedul Hasan — August 11, 2018 at 9:29 pm (permalink) Rashedul Hasan says:\nHi Shai, thanks for the article but how do i put the java class \u0026ldquo;SMSListener\u0026rdquo; inside \u0026ldquo;native/android\u0026rdquo; directory? a bit confused!\nShai Almog — August 12, 2018 at 4:37 am (permalink) Shai Almog says:\nHi,\nsee this video on native interfaces. It should explain it clearly https://www.codenameone.com…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-intercept-incoming-sms-on-android/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-intercept-incoming-sms-on-android/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eLast week I talked about \u003ca href=\"/blog/tip-send-device-activation-sms-via-twilio.html\"\u003eusing SMS to activate your application\u003c/a\u003e which is a pretty powerful way to verify a user account. I left a couple of things out though. One of those things is the ability to grab the incoming SMS automatically. This is only possible on Android but it’s pretty cool for the users as it saves on the pain of typing the activation text.\u003c/p\u003e\n\u003ch3 id=\"broadcast-receiver\"\u003eBroadcast Receiver\u003c/h3\u003e\n\u003cp\u003eIn order to grab an incoming SMS we need a broadcast receiver which is a standalone Android class that receives a specific event type. This is often confusing to developers who sometimes derive the impl class from broadcast receiver…​ That’s a mistake…​\u003c/p\u003e","title":"TIP: Intercept Incoming SMS on Android"},{"content":"\nContinuing the trend I revisited the old crash protection video in the \u0026ldquo;how do I\u0026rdquo; section and updated it with current information and details. The old video still featured an old flag that should be avoided…​\nThe new video is relatively short and simple as the feature isn’t very complex, I hope to produce several more of these and bolster the video section further.\nOn a different subject I also neglected to mention the new security related module in the Codename One Academy courses. I’ll drop additional videos there later in the month. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — September 23, 2017 at 10:27 pm (permalink) Francesco Galgani says:\nThank you for the two new lessons about security. Is it possible to receive an e-mail every time that you add a new lesson in the Codename One Academy?\nFrancesco Galgani — October 18, 2017 at 10:21 am (permalink) Francesco Galgani says:\n(This is the second time that I try to submit this comment)\nAbout crash protection and error reporting, I have two questions:\n1. Is there a code that automatically catches (and reports by e-mail) all exceptions in all threads, not only in the EDT?\n2. In the manual, section \u0026ldquo;Logging \u0026amp; Crash Protection\u0026rdquo;, at the page: https://www.codenameone.com… , there are the following two lines of code: I don’t understood if it makes sense use them in conjunction with Log.bindCrashProtection(true)\nLog.setReportingLevel(Log.REPORTING_DEBUG);\nDefaultCrashReporter.init(true, 2);\nThank you for any clarification.\nShai Almog — October 19, 2017 at 5:50 am (permalink) Shai Almog says:\nSorry I missed that. No there is no standard way to do that without bothering everyone unfortunately. I will however post with updates to the blog occasionally.\nShai Almog — October 19, 2017 at 5:54 am (permalink) Shai Almog says:\nA comment goes directly to moderation if you include a link which disqus sometimes thinks are just strings with dots e.g. a stack trace is \u0026ldquo;links\u0026rdquo;.\n1. If you use the bind method this will happen implicitly and also send an email for other threads. I think I mentioned that in the video. I’d recommend using Display.startThread() instead of new Thread() to guarantee that.\n2. The crash reporter sends an email every couple of minutes with the content of the log. It’s an approach we have phased out as we catch errors more effectively now thanks to the new changes in the iOS VM.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-crash-protection/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-crash-protection/learn-codenameone-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eContinuing the trend I revisited the old crash protection video in the \u0026ldquo;how do I\u0026rdquo; section and updated it with current information and details. The old video still featured an old flag that should be avoided…​\u003cbr\u003e\nThe new video is relatively short and simple as the feature isn’t very complex, I hope to produce several more of these and bolster the video section further.\u003c/p\u003e\n\u003ch2 id=\"on-a-different-subject-i-also-neglected-to-mention-the-new-security-related-module-in-the-codename-one-academy-courses-ill-drop-additional-videos-there-later-in-the-month\"\u003eOn a different subject I also neglected to mention the new security related module in the \u003ca href=\"https://codenameone.teachable.com/p/build-real-world-full-stack-mobile-apps-in-java\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCodename One Academy courses\u003c/a\u003e. I’ll drop additional videos there later in the month.\u003c/h2\u003e\n\u003ch2 id=\"archived-comments\"\u003eArchived Comments\u003c/h2\u003e\n\u003cp\u003e\u003cem\u003eThis post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\u003c/em\u003e\u003c/p\u003e","title":"Tutorial – Crash Protection"},{"content":"\nI already have half a post on text components but I’ve put that on hold for now as I’ve been working on the on-top side menu to supersede the existing side menu bar implementation. I’ve made some fixes for it over the week, I wanted to make it the default for Codename One apps but it still isn’t \u0026ldquo;perfect\u0026rdquo;. We will make it the default within the next couple of weeks so please test it after this weeks update and let us know ASAP if you spot any issues!\nAfter the latest round of work the side menu now resides on top of the entire form and not just over the content pane. I was able to address some issues in the form layer implementation and it should work properly now. I also fixed some pretty hairy issues with events and even a rather insane issue with invokeAndBlock.\nTo give you a sense of how this looks this is the old side menu in the kitchen sink demo:\nFigure 1. The old side menu in the kitchen sink\nIf we add the call Toolbar.setOnTopSideMenu(true) to the init(Object) callback after this weekend update we should see this:\nFigure 2. The new on-top side menu in the kitchen sink\nThere is a lot of nuance involved in this new mode, e.g. the underlying form grows gradually darker as you drag on top of it etc.\nFlipping the Switch We’ll flip this to be the default mode within a couple of weeks unless something big happens. At that point if you have dependencies on the old behavior and would like to restore that you would need to explicitly invoke Toolbar.setOnTopSideMenu(false) in the init(Object) method.\nAs we discussed in the past we want to avoid the \u0026ldquo;legacy pitfall\u0026rdquo; many frameworks fall into. In this pitfall frameworks try to be \u0026ldquo;overly compatible\u0026rdquo; with nuanced behaviors which means users don’t adopt the newer/better functionality that’s available to them.\nWith this we hope to resolve some of the open issues in the existing side menu implementation.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/pixel-perfect-on-top-menu/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/pixel-perfect-on-top-menu/pixel-perfect.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI already have half a post on text components but I’ve put that on hold for now as I’ve been working on the \u003ca href=\"/blog/sidemenu-on-top.html\"\u003eon-top side menu\u003c/a\u003e to supersede the existing side menu bar implementation. I’ve made some fixes for it over the week, I wanted to make it the default for Codename One apps but it still isn’t \u0026ldquo;perfect\u0026rdquo;. We will make it the default within the next couple of weeks so please test it after this weeks update and let us know ASAP if you spot any issues!\u003c/p\u003e","title":"Pixel Perfect – On Top Menu"},{"content":"\nA very common question we get from developers is \u0026ldquo;how do I get the devices phone number\u0026rdquo;. The answer is \u0026ldquo;you can’t really and you shouldn’t\u0026rdquo;. To clarify, this is possible on Android but would require a scary set of permissions. It’s blocked on iOS completely though so you’d need a different solution anyway…​\nIf you look at apps like Uber, whatsapp etc. they all use SMS activation. They just ask you to type your number and activate your phone via SMS. Usually this SMS is sent from the server side but for simplicity lets discuss how this can be done entirely from your app.\n__ You should send the SMS from the server for security reasons as the Twillo keys will never appear in the client side For simplicities sake I’ll break this into several different pieces and the first of which is the REST request to the Twilio API to send the message. This is pretty trivial, you would need to signup to Twilio and have the following 3 variable values:\nString accountSID = \u0026quot;----------------\u0026quot;; String authToken = \u0026quot;---------------\u0026quot;; String fromPhone = \u0026quot;your Twilio phone number here\u0026quot;; __ You can open a trial Twilio account and it just tags all of your SMS’s. Notice you would need to use a US based number if you don’t want to pay I can also generate a 4 digit value variable pretty easily using something like this:\nRandom r = new Random(); String val = \u0026quot;\u0026quot; + r.nextInt(10000); while(val.length() \u0026lt; 4) { val = \u0026quot;0\u0026quot; + val; } We can now send val as an SMS to the end user. Once this is in place sending an SMS via REST is just a matter of using the new REST callback API:\nResponse\u0026lt;Map\u0026gt; result = Rest.post(\u0026quot;https://api.twilio.com/2010-04-01/Accounts/\u0026quot; + accountSID + \u0026quot;/Messages.json\u0026quot;). queryParam(\u0026quot;To\u0026quot;, destinationPhone). queryParam(\u0026quot;From\u0026quot;, fromPhone). queryParam(\u0026quot;Body\u0026quot;, val). header(\u0026quot;Authorization\u0026quot;, \u0026quot;Basic \u0026quot; + Base64.encodeNoNewline((accountSID + \u0026quot;:\u0026quot; + authToken).getBytes())). getAsJsonMap(); Notice that there is currently a bug with the builtin basic authentication in the REST API, it will be fixed for the next version where you could write this instead:\nResponse\u0026lt;Map\u0026gt; result = Rest.post(\u0026quot;https://api.twilio.com/2010-04-01/Accounts/\u0026quot; + accountSID + \u0026quot;/Messages.json\u0026quot;). queryParam(\u0026quot;To\u0026quot;, destinationPhone). queryParam(\u0026quot;From\u0026quot;, fromPhone). queryParam(\u0026quot;Body\u0026quot;, val). basicAuth(accountSID, authToken)). getAsJsonMap(); What we do here is actually pretty trivial, we open a connection the the api messages URL. We add arguments to the body of the post request and define the basic authentication data.\nThe result is in JSON form we mostly ignore it since it isn’t that important but it might be useful for error handling. This is a sample response (redacted keys):\n{ \u0026quot;sid\u0026quot;: \u0026quot;[sid value]\u0026quot;, \u0026quot;date_created\u0026quot;: \u0026quot;Sat, 09 Sep 2017 19:47:30 +0000\u0026quot;, \u0026quot;date_updated\u0026quot;: \u0026quot;Sat, 09 Sep 2017 19:47:30 +0000\u0026quot;, \u0026quot;date_sent\u0026quot;: null, \u0026quot;account_sid\u0026quot;: \u0026quot;[sid value]\u0026quot;, \u0026quot;to\u0026quot;: \u0026quot;[to phone number]\u0026quot;, \u0026quot;from\u0026quot;: \u0026quot;[from phone number]\u0026quot;, \u0026quot;messaging_service_sid\u0026quot;: null, \u0026quot;body\u0026quot;: \u0026quot;Sent from your Twilio trial account - 2222\u0026quot;, \u0026quot;status\u0026quot;: \u0026quot;queued\u0026quot;, \u0026quot;num_segments\u0026quot;: \u0026quot;1\u0026quot;, \u0026quot;num_media\u0026quot;: \u0026quot;0\u0026quot;, \u0026quot;direction\u0026quot;: \u0026quot;outbound-api\u0026quot;, \u0026quot;api_version\u0026quot;: \u0026quot;2010-04-01\u0026quot;, \u0026quot;price\u0026quot;: null, \u0026quot;price_unit\u0026quot;: \u0026quot;USD\u0026quot;, \u0026quot;error_code\u0026quot;: null, \u0026quot;error_message\u0026quot;: null, \u0026quot;uri\u0026quot;: \u0026quot;/2010-04-01/Accounts/[sid value]/Messages/SMe802d86b9f2246989c7c66e74b2d84ef.json\u0026quot;, \u0026quot;subresource_uris\u0026quot;: { \u0026quot;media\u0026quot;: \u0026quot;/2010-04-01/Accounts/[sid value]/Messages/[message value]/Media.json\u0026quot; } } Notice the error message entry which is null meaning there was no error, if there was an error we’d have a message there or an error code that isn’t in the 200-210 range.\nThis should display an error message to the user if there was a problem sending the SMS:\nif(result.getResponseData() != null) { String error = (String)result.getResponseData().get(\u0026quot;error_message\u0026quot;); if(error != null) { ToastBar.showErrorMessage(error); } } else { ToastBar.showErrorMessage(\u0026quot;Error sending SMS: \u0026quot; + result.getResponseCode()); } Next Time Next time I’ll talk about doing the actual activation process and maybe discuss some of the more ambitious behaviors such as SMS interception. Ideally this is something that should fit into a cn1lib which might be something I’ll cover moving forward. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nGareth Murfin — October 5, 2018 at 8:23 pm (permalink) Gareth Murfin says:\nAwesome, I would LOVE a twilio library for cn1,to abstract away from their HELL.. ! using it right now on android, what a mess….\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-send-device-activation-sms-via-twilio/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-send-device-activation-sms-via-twilio/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA very common question we get from developers is \u0026ldquo;how do I get the devices phone number\u0026rdquo;. The answer is \u0026ldquo;you can’t really and you shouldn’t\u0026rdquo;. To clarify, this is possible on Android but would require a scary set of permissions. It’s blocked on iOS completely though so you’d need a different solution anyway…​\u003cbr\u003e\nIf you look at apps like Uber, whatsapp etc. they all use SMS activation. They just ask you to type your number and activate your phone via SMS. Usually this SMS is sent from the server side but for simplicity lets discuss how this can be done entirely from your app.\u003c/p\u003e","title":"TIP: Send Device Activation SMS via Twilio"},{"content":"\nI redid the include source tutorial which was really old by now and included some outdated \u0026ldquo;facts\u0026rdquo; while missing key information. Include source allows us to get the native OS project source code on build, this allows us to debug and profile on the devices.\nNew Codename One users often mix up native interfaces and include source. You shouldn’t change the code generated with \u0026ldquo;include source\u0026rdquo;. It’s for debugging purposes only. If you need to write native code just use native interfaces to do so, you can then use include source and the native debugger to debug your native interfaces.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-include-source/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-include-source/learn-codenameone-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI redid the include source tutorial which was really old by now and included some outdated \u0026ldquo;facts\u0026rdquo; while missing key information. Include source allows us to get the native OS project source code on build, this allows us to debug and profile on the devices.\u003c/p\u003e\n\u003cp\u003eNew Codename One users often mix up \u003ca href=\"/how-do-i---access-native-device-functionality-invoke-native-interfaces.html\"\u003enative interfaces\u003c/a\u003e and include source. You shouldn’t change the code generated with \u0026ldquo;include source\u0026rdquo;. It’s for debugging purposes only. If you need to write native code just use native interfaces to do so, you can then use include source and the native debugger to debug your native interfaces.\u003c/p\u003e","title":"Tutorial – Include Source"},{"content":"\nA common trick for gaining traction is localization to multiple languages, Codename One makes that very simple as we explained here. However, unless you are fluent in multiple languages you will need some help to localize broadly.\nThere are multiple paid services that address this need. There are a couple of pitfalls you can fall into when using such services.\nThe first pitfall is trying to get them to work with Codename One, most such services wouldn’t be familiar with Codename One. We support an export feature in the Codename One designer:\nFigure 1. Export localization files\nWhen you use that feature you can select the export format.\nFigure 2. Localization files supported formats\nA common pitfall is picking properties or CSV which are supported by most localization providers. They work and can be imported later. However, some localization providers have bugs related to a poor understanding of these formats e.g. properties doesn’t allow encoded text and requires the usage of the u notation but most providers don’t understand that and don’t escape = or : correctly.\nThe best approach is an Android Strings file. It’s XML which is very well understood/defined. Pretty much every localization tool supports it due to the popularity of Android so using it for import/export should work seamlessly. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nsalah Alhaddabi — September 6, 2017 at 6:05 am (permalink) Thanks a lot Shai. Even during your leave you try to blog.\nThanks a lot for all your help!!!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-outsource-app-translations/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-outsource-app-translations/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA common trick for gaining traction is localization to multiple languages, Codename One makes that very simple as we explained \u003ca href=\"/how-do-i---localizetranslate-my-application-apply-i18nl10n-internationalizationlocalization-to-my-app.html\"\u003ehere\u003c/a\u003e. However, unless you are fluent in multiple languages you will need some help to localize broadly.\u003c/p\u003e\n\u003cp\u003eThere are multiple paid services that address this need. There are a couple of pitfalls you can fall into when using such services.\u003c/p\u003e\n\u003cp\u003eThe first pitfall is trying to get them to work with Codename One, most such services wouldn’t be familiar with Codename One. We support an export feature in the Codename One designer:\u003c/p\u003e","title":"TIP: Outsource App Translations"},{"content":"\nI haven’t blogged as much in the past month and as a result I have a big pile of updates from all over. This is going to be a big list so I’ll start with a few pull requests that were submitted by Diamond and Durank. If you see something broken or something that could be better in Codename One just fix it like they did!\nNew Material Icons \u0026amp; Multi Selection Calendar In this pull request Diamond added two separate features:\nMaterial Icons The PR includes 49 new google material design icons, our material design font and constants were made a while back and we didn’t update them with changes from Google. Diamond updated both the font and the constants which now include new icons such as MATERIAL_DELETE_FOREVER \u0026amp; MATERIAL_DO_NOT_DISTURB_ON.\nYou can check out the full list of added icons in the source of the PR.\nCalendar Multi Selection If you haven’t used the calendar class it’s a pretty old class in Codename One. It was one of the original LWUIT classes, I think it even predated my time in LWUIT (it’s THAT old). The age of this specific API is pretty obvious when looking at it but people still find it useful for very specific use cases.\nPeople have enhanced this class in the past but as far as I know Diamond is the first person to commit the code back which is pretty great and might make other developers follow suit.\nThe core of the change is a new method in Calendar called setMultipleSelectionEnabled(boolean) which toggles the calendar to multi selection mode. He also added a CalendarMultipleDay UIID to style this selection mode differently.\nConvenience methods for BorderLayout In this pull request Diamond added a few new methods to the BorderLayout class. Specifically:\npublic static BorderLayout center(); public static BorderLayout absolute(); public static BorderLayout totalBelow(); These are essentially synonyms to the equivalent constants e.g. instead of writing new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER) you can now write BorderLayout.center() which is both shorter and is better for compile time checks (since CENTER_BEHAVIOR_CENTER is an int).\nHe also added:\npublic static Container centerCenterEastWest(Component center, Component east, Component west); public static Container centerTotalBelowEastWest(Component center, Component east, Component west); public static Container centerTotalBelow(Component center); Which are shorthand variants of enclose that allow us to package two or three components together in a horizontal border layout or just enclose with a total below border layout.\n__ In the total below mode the center component takes up the entire screens and the sides are automatically placed on top of it thus creating a layered effect Accordion Listener There is currently no listener event bound to the accordion expansion. This might be useful for various UI’s and is addressed in this pull request from Durank.\nWe now have new methods in Accordion specifically:\npublic void addOnClickItemListener(ActionListener a); public void removeOnClickItemListener(ActionListener a); QR Code Creation rwanghk created a new cn1lib that creates QR codes. We already have a couple of cn1libs for reading QR codes but this is the first one that allows you to generate a QR code from your data.\nGeofencing Improvements Steve committed a big set of improvements to the geofencing functionality. First and foremost is the new GeofenceManager class that abstracts many of the pain points of geofencing. E.g. platform-specific limitations on the number of simultaneous geofence regions that can be monitored.\nThe geofencing documentation is now improved and mentions platform-specific limitations, and clarified the units of some parameters. There is also some support for LocalNotifications in the simulator which should make debugging these applications far easier. The simulator will also display warnings when geofences are added with radiuses that may be smaller than the minimum on device.\nNow, when the app is paused, LocalNotifications will show up in the system tray.\nFor additional convenience in measuring distance Steve added getDistanceTo() methods to both Geofence and Location. He also added createDistanceComparator() methods to Geofence and Location to make it easier to sort locations and regions by distance from a reference point or region. This is used by GeofenceManager to return a list of current geofences sorted by distance from the current location.\nEnd of ThreadSafeDatabase We introduced ThreadSafeDatabase last release and we’re deprecating it today. This sucks but since the API is mostly compatible changing back shouldn’t be hard.\nWe tried to get ThreadSafeDatabase but eventually decided that the approach it took just isn’t workable across platforms. We ran into too many oddities even in the simulator with no decent explanation for the failures we encountered. Eventually, this left us no choice as ThreadSafeDatabase left us in a position that was even less stable.\nHowever, we did integrate an improvement to the SQLite implementation on iOS which should make it more robust for multi-thread access. This isn’t ideal and we can’t guarantee thread safety but hopefully at least some of the portability issues would be resolved due to that change.\nBuild Timeouts Over the past week one of our bug fixes in the iOS VM triggered longer builds that caused timeouts especially with release builds. We hope to resolve this issue over this weekend update and get builds working again.\nHowever, during this process it has come to my attention that some developers have such timeout failures and haven’t complained about them or kept up with us. We had assumed the issue was resolved for most developers with the exception of one special case but it seems that this assumption might have been flawed.\nSo for the record: we don’t track your failed builds…​ We have too many builds going thru the servers to see who’s build failed and we don’t have direct access to the build logs. We just don’t know if you are getting errors so please report them.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-features-pull-requests/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-features-pull-requests/new-features-6.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI haven’t blogged as much in the past month and as a result I have a big pile of updates from all over. This is going to be a big list so I’ll start with a few pull requests that were submitted by \u003ca href=\"https://github.com/diamondobama\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDiamond\u003c/a\u003e and \u003ca href=\"https://github.com/DurankGts\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDurank\u003c/a\u003e. If you see something broken or something that could be better in Codename One just \u003ca href=\"/blog/how-to-use-the-codename-one-sources.html\"\u003efix it like they did\u003c/a\u003e!\u003c/p\u003e\n\u003ch3 id=\"new-material-icons--multi-selection-calendar\"\u003eNew Material Icons \u0026amp; Multi Selection Calendar\u003c/h3\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/codenameone/CodenameOne/pull/2194\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eIn this pull request\u003c/a\u003e Diamond added two separate features:\u003c/p\u003e","title":"New Features and Pull Requests"},{"content":"\nThe Michael Jackson documentary, \u0026ldquo;This is It\u0026rdquo;, included a behind-the-scenes look at Michael Jackson’s preparation for his final tour, that tragically would never happen. In one scene, he has an exchange with the keyboard player that goes roughly as follows:\nMichael Jackson (to keyboard player) : That isn’t right\nKeyboard player : How do you want it? I can do it anyway you want it.\nMichael Jackson : Just make it sound like on my CD.\nI recall laughing at that time, thinking yeah \u0026ldquo;just like the CD\u0026rdquo;. What the keyboard player had been doing sounded like the CD to me, but apparently to Michael, it was off.\nObviously my untrained ear didn’t know what to look for. Had I been playing keyboard, the instruction of \u0026ldquo;make it sound like the CD\u0026rdquo; wouldn’t have helped me at all. I would need him to break it down for me into something more tangible. E.g Faster, slower, louder, softer, etc…​\nUser interface design is very similar to music in this sense. When we use a well-designed UI, it just \u0026ldquo;feels\u0026rdquo; nice, but we may not know why. Those who are skilled in design may be able to break a successful design down into components – but the rest of us can only sit and marvel at the magic.\nI have blogged, in the past, about UI design in Codename One. In this tutorial, I walk, step by step, through the process of converting a PSD file into a mobile app. Unfortunately, upon re-reading that tutorial, I realize that I completely skipped one of the most important steps. I essentially began with \u0026ldquo;let’s make our app look just like the design\u0026rdquo;, but I didn’t describe what it meant to look \u0026ldquo;just like the design\u0026rdquo;. In this blog post, I’d like to unpack what \u0026ldquo;just like the design\u0026rdquo; means to me, in the context of mobile app development.\nSo, what does \u0026ldquo;Just like the design\u0026rdquo; mean? A broad overview is that fonts, colors, padding, margin, and alignment must match the design. In addition, the sections of the UI must be retained correctly. The last part (sections), is most relevant when adapting the UI to different screen sizes. Below, I go into detail on each of these aspects of design.\n__ I come from the \u0026ldquo;programming\u0026rdquo; side of the fence. I don’t have any formal design training, other than having read a few books on the subject, and tips that I have picked in in past projects by actual designers. Fonts Fonts should match as much as possible. Try to use the exact same font. If that isn’t possible, then at least find a similar font.\nThis website allows you to type in a font name, and it will show you a list of suggestions for similar fonts. At the bare minimum you’ll want to choose a font that is on the same side of the serif/sans-serif divide. One simple test I use to \u0026ldquo;rule out\u0026rdquo; a font is to compare the the lower case \u0026ldquo;a\u0026rdquo;, \u0026ldquo;g\u0026rdquo;, and \u0026ldquo;y\u0026rdquo;, as each has two distinct variants. I generally want my \u0026ldquo;similar\u0026rdquo; font to at least agree on those three glyphs.\nColors Colors should match exactly. I often use the built-in \u0026ldquo;Digital Color Meter\u0026rdquo; application on OS X for determining the color. An arguably better method is to go directly to the source, and ask Photoshop what color it is.\nPadding and Margin Padding and Margin should match. This is important and it is too often over-looked by developers. The spacing between icons and their labels, the amount of padding between a button’s text and its border, etc…​ The designer chose the spacing very carefully to create an over-all feeling. You can butcher the design by simply forgetting to pay attention to padding and margin.\n__ Always use millimetres for specifying margins, padding, and font-size. NEVER use pixels, except in cases where you are first calculating the run-time pixel dimensions of another component (or the screen) to use as a basis for your sizing. Alignment Alignment is critical. Pay close attention to any invisible \u0026ldquo;lines\u0026rdquo; in the design. E.g. which labels are aligned on their left or right sides, and which ones are centered. Your app should preserve these invisible lines.\nIdentify Sections Identify the Sections of the design. Take a step back and look at the big picture of the design. You need to understand the semantics of the design if you want to be able to adapt it to different screen sizes and aspect ratios. A simplified version of this step is identifying \u0026ldquo;Header\u0026rdquo;, \u0026ldquo;Content\u0026rdquo;, and \u0026ldquo;Footer\u0026rdquo;. Usually you’ll want to ensure that sections retain their size and position relative to the screen dimensions.\nI find it useful to draw a wire-frame representation of the design. Once I think I have it right, I’ll try to adapt the wireframe to different aspect ratios so I can decide, for example, whether an image should be 1 inch, or 25% of the screen height. This part can be the most challenging because there may be subtle design decisions in how the sections are laid out on the screen. Think along the lines of rule of thirds, a rule of thumb used by photographers for staging photographs. If you don’t have direct access to the designer, it may be difficult to \u0026ldquo;big picture\u0026rdquo; composition decisions that should be retained to preserve the spirit of the design; but you should at least try.\nStop, Stare, and Iterate When you think you have achieved a finished product, you should stop and stare at the design for a while. Pay attention to how it makes you feel. If something feels wrong, you should walk through the above points (fonts, colors, padding, alignment, sections), and try to identify what is off. Try this in the simulator using different skins and orientations.\nRepeat as necessary until it \u0026ldquo;feels\u0026rdquo; right.\nFresh Eyes Show the design and screenshots from your app to someone else and ask for feedback. They may be able to spot differences that you weren’t able to.\nConclusion These are the techniques that I use to recreate beautiful designs in Codename One. If you think I’ve missed something here, please leave comments so that I can improve my own process. The goal is perfection. Nothing less! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — August 29, 2017 at 11:51 pm (permalink) bryan says:\nI agree with all you wrote, but I’m wondering where you sit on the \u0026ldquo;native\u0026rdquo; L\u0026amp;F vs custom L\u0026amp;F. While you can set margins etc for your design, they may conflict with what people who expect a \u0026ldquo;pure\u0026rdquo; native design might expect ?\nShai Almog — August 30, 2017 at 3:51 am (permalink) Shai Almog says:\nI think the native theme should be the starting point and everything that \u0026ldquo;matters\u0026rdquo; should be layered on top. E.g. iOS and Android have slightly different title area behaviors that should be derived from the native theme e.g. title alignment. However, some designs require the title to behave differently so if you have one of those designs then just override the native theme for that specific purpose.\nSince both OS converged a lot over design I think you can extract reasonable commonality that will work well for both and still feel native enough to the platform but this requires some imagination and a good relationship with the designer which leaves a lot of room for problems.\nFrancesco Galgani — September 13, 2017 at 8:58 am (permalink) Francesco Galgani says:\nThanks for this article. You suggested: «Fonts should match as much as possible. Try to use the exact same font. If that isn’t possible, then at least find a similar font.», but in several articles and tutorials the use of the native fonts (roboto for Android and HelveticaNeue for iOS) is the suggested option because they are \u0026ldquo;good looking by default\u0026rdquo; and they support well all languages. I’m a bit confused.\nShai Almog — September 14, 2017 at 5:57 am (permalink) Shai Almog says:\nThe goal of this article is to get \u0026ldquo;pixel perfect\u0026rdquo; compatibility with the design. In order to do that the fonts must match. I find that what the designer/client usually \u0026ldquo;want\u0026rdquo; is the native OS fonts. The main reason they want those is for consistency, even if your font is really pretty it might feel out of place on the device so I always go with the native fonts.\nHaving said that, fonts have a HUGE impact on design. If you change the font the UI feels different and won’t match the PSD you got from the designer.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/make-it-look-the-same-as-the-design/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/make-it-look-the-same-as-the-design/learn-codenameone-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe Michael Jackson documentary, \u0026ldquo;This is It\u0026rdquo;, included a behind-the-scenes look at Michael Jackson’s preparation for his final tour, that tragically would never happen. In one scene, he has an exchange with the keyboard player that goes roughly as follows:\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eMichael Jackson (to keyboard player) :\u003c/strong\u003e That isn’t right\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eKeyboard player :\u003c/strong\u003e How do you want it? I can do it anyway you want it.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eMichael Jackson :\u003c/strong\u003e Just make it sound like on my CD.\u003c/p\u003e","title":"Make it Look Like the Design"},{"content":"\nThe summer is finally coming to an end but we might not get to full speed before mid September. Thankfully this didn’t impact Steve who did some pretty great things this August including a lot of GUI builder fixes/enhancements that we’ll cover with the next plugin update. But what we will have this weekend is pretty spectacular. As a short PSA: we’re pushing out the weekend release right now because I’ll be traveling tomorrow. So all this should be available today.\nVM Overhaul When we started ParparVM our goal was to create a stable, portable \u0026amp; simple VM. We didn’t aim for the performance crown in any way as stability, simplicity \u0026amp; size were far more important in our experience. As the VM stabilized we slowly expanded our ambition and improved performance.\nFor many use cases our VM now performs as fast as C but there were still a few things we could improve and Steve made major strides on these.\nSignal Handling VM’s usually use low level signaling to detect things like null pointer exceptions which can be detected with zero cost to the runtime environment. Up until now we didn’t do that as we focused on performance and this had some implications. Starting with this update we will convert signals to exceptions which means a null pointer exception should be automatic.\nThis also means you might get a null pointer exception or a runtime exception from a native OS failure and it can also mean that crash protection will become more effective as OS level crashes would translate to standard exceptions.\nThat’s a HUGE change in the way the VM works, it has one drawback: this doesn’t happen in the xcode debugger as the debug environment overrides the signals. So if you run into a null in the debugger you will get a crash and breakpoint instead of the exception. This isn’t a \u0026ldquo;bad thing\u0026rdquo; but the behavior difference is something you should be aware of. We hope this will improve the reliability \u0026amp; stability of Codename One and bring it to the next level. We also hope this will improve performance by eliminating null checks from our code.\nNew Allocator If you did any serious C/C++ coding you would know that malloc is pretty problematic. One of the advantages of Java SE is that allocation is faster in Java than it is in C. We didn’t create an allocator as fast as the one in the JDK but Steve integrated a well known malloc replacement that should make heap allocation much faster.\nSince Java is based mostly on heap this could have a huge impact on performance both in reducing GC overhead and in allocations themselves. This is off by default right now as it’s still undergoing testing but we hope to flip it to the default next week.\nYou can try it right now by setting the build hint ios.rpmalloc=true.\nNotice that if you set this flag to true (which will be the default soon) the iOS deployment target will be set to 8.0+ so if you use the build hint ios.deployment_target with a lower value or if you need support for older devices/OS’s you will need to explictly set this to false!\nFaster UTF-8 This might seem like a smaller feature but string decoding is probably one of the biggest bottlenecks in app logic.\nIn fact it was such a big bottleneck that we optimized UTF-8 decoding with a special case that detected ASCII code and used a special case fast decode. This worked great for ASCII but not as great for localized text. If you had an app that did a lot of character decoding from a source that wasn’t English\nIn fact it was such a big bottleneck that we optimized UTF-8 decoding with a special case that detected ASCII code and used a special case fast decode. This worked great for ASCII but not as great for localized text. If you had an app that did a lot of character decoding from a source that wasn’t of the lower 7 bit ASCII table you paid a penalty in terms of performance as parsing was delegated to Objective-C code.\nSteve wrote a fast C based UTF-8 decoding function that should remove that significant bottleneck that might impact a lot of apps.\nUpcoming Changes There are quite a few other updates I’d like to share including some great pull requests from Diamond and some other things we’ve been working on but this post is getting long enough.\nThe next two-three weeks will probably be pretty busy but after that I hope to push a plugin refresh and start working on getting 3.8 out of the door. With 3.8 we will be focusing on refinement and stability and don’t plan major new features at this time.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/vm-changes-updates/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/vm-changes-updates/new-features-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe summer is finally coming to an end but we might not get to full speed before mid September. Thankfully this didn’t impact Steve who did some pretty great things this August including a lot of GUI builder fixes/enhancements that we’ll cover with the next plugin update. But what we will have this weekend is pretty spectacular. As a short PSA: we’re pushing out the weekend release right now because I’ll be traveling tomorrow. So all this should be available today.\u003c/p\u003e","title":"VM Changes and Updates"},{"content":"\nI’ve been working on the new pixel perfect post which I would like to focus around the text components, in order to do that I needed an underline border type. Historically this is something we shrugged off and pointed people at the 9-piece border. That was the wrong answer and it partially related to the way rendering used to work in Codename One and partially related to our reluctance in changing the resource file format.\nBoth of these are no longer an issue or a priority so in the upcoming update I added new methods to the Border class:\npublic static Border createLineBorder(float thickness, int color) public static Border createLineBorder(float thickness) public static Border createUnderlineBorder(int thickness, int color) public static Border createUnderlineBorder(float thickness, int color) public static Border createUnderlineBorder(int thickness) public static Border createUnderlineBorder(float thickness) Notice that we already had a createLineBorder(int thickness, int color) method which worked with pixels. The floating point version of the method works with millimeters. For consistency I made the new underline border mode work in the same way and so the int version of the method works with pixels and the float version of the method works with millimeters.\nAlso notice the versions of the methods that don’t take a color as an argument use the styles foreground color for the painting.\nThe upcoming version of the Codename One designer will now include the additional underline option in the combo box of borders and a new millimeter checkbox next to the thickness entry in the first tab.\nThis can have far reaching effect as a lot of our components currently feature default 9-piece borders to workaround the lack of this border type. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — August 24, 2017 at 3:43 pm (permalink) Francesco Galgani says:\nThank you. Can you add some screenshots to show the new features? 🙂\nShai Almog — August 25, 2017 at 3:24 am (permalink) Shai Almog says:\nI thought about that when I was making the post but frankly there isn’t much to see. It’s just a line at the bottom like you have in the iOS theme for multi button and other components.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/millimeter-underline/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/millimeter-underline/uidesign.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been working on the new pixel perfect post which I would like to focus around the text components, in order to do that I needed an underline border type. Historically this is something we shrugged off and pointed people at the 9-piece border. That was the wrong answer and it partially related to the way rendering used to work in Codename One and partially related to our reluctance in changing the resource file format.\u003c/p\u003e","title":"Millimeter Underline"},{"content":"\nSometimes I get a question on stack overflow that triggers a \u0026ldquo;yes this should be easy\u0026rdquo; reflex. I got such a question a couple of weeks ago when I implemented the animated gif support cn1lib and I had another one last week which asked about sorting tables.\nThis is actually pretty easy to do but it’s just something we didn’t get around to. So I just implemented it and decided this would make a lot of sense in the core API. Sortable tables make a lot of sense and ideally should be the default.\nSo I added support for this directly into Codename One and you can now make a table sortable like this:\nForm hi = new Form(\u0026quot;Table\u0026quot;, new BorderLayout()); TableModel model = new DefaultTableModel(new String[] {\u0026quot;Col 1\u0026quot;, \u0026quot;Col 2\u0026quot;, \u0026quot;Col 3\u0026quot;}, new Object[][] { {\u0026quot;Row 1\u0026quot;, \u0026quot;Row A\u0026quot;, 1}, {\u0026quot;Row 2\u0026quot;, \u0026quot;Row B\u0026quot;, 4}, {\u0026quot;Row 3\u0026quot;, \u0026quot;Row C\u0026quot;, 7.5}, {\u0026quot;Row 4\u0026quot;, \u0026quot;Row D\u0026quot;, 2.24}, }); Table table = new Table(model); table.setSortSupported(true); hi.add(BorderLayout.CENTER, table); hi.add(NORTH, new Button(\u0026quot;Button\u0026quot;)); hi.show(); Notice this works with numbers, Strings and might work with dates but you can generally support any object type by overriding the method protected Comparator createColumnSortComparator(int column) which should return a comparator for your custom object type in the column. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — August 16, 2017 at 4:59 pm (permalink) Francesco Galgani says:\nThank you very much! 🙂\nFrancesco Galgani — August 16, 2017 at 5:11 pm (permalink) Francesco Galgani says:\nFirst question: I tested your code in a new Netbeans project, but it doesn’t compile because it «cannot find symbol table.setSortSupported(true);». I’ve seen that you updated the API, but… how do I update Netbeans?\nSecond question: in your code, is the Table sorted by the third column? How can I choose which column to order by?\nThank you for any help (and for your work in vacation time…)\nShai Almog — August 17, 2017 at 4:39 am (permalink) Shai Almog says:\nMake sure to update the libraries by opening Codename One Settings -\u0026gt; Basic -\u0026gt; Update Client Libs.\nFrancesco Galgani — August 17, 2017 at 9:35 am (permalink) Francesco Galgani says:\nOk, now it compiles… but the table is not sorted (using exactly your code). How can I sort it according to the values in third column? Thank you\nShai Almog — August 18, 2017 at 5:53 am (permalink) Shai Almog says:\nClick the columns to sort them and again to flip ascending/descending direction.\nsalah Alhaddabi — August 21, 2017 at 4:44 am (permalink) salah Alhaddabi says:\nVery nice you guys are amazing!!!\nSoAppMedia — August 21, 2017 at 4:42 pm (permalink) SoAppMedia says:\nThanks for sharing! this is such a great help this is worth to share!\nFrancesco Galgani — August 21, 2017 at 5:02 pm (permalink) Francesco Galgani says:\nOk. Is there any way to get a column already selected for ordering (in ascending or descending direction) before any user input, for example on myForm.show or myForm.revalidate()?\nShai Almog — August 22, 2017 at 5:27 am (permalink) Shai Almog says:\nI’ll add a sort(column, ascending) method to allow this.\nFrancesco Galgani — August 22, 2017 at 11:13 am (permalink) Francesco Galgani says:\nThank you! 😀\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/sortable-table/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/sortable-table/new-features-5.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSometimes I get a question on stack overflow that triggers a \u0026ldquo;yes this should be easy\u0026rdquo; reflex. I got such a question a couple of weeks ago when I implemented the \u003ca href=\"/blog/animated-gif-support.html\"\u003eanimated gif support cn1lib\u003c/a\u003e and I had \u003ca href=\"https://stackoverflow.com/questions/45330419/codename-one-sort-table-with-data-from-sql-database/45341816\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eanother one last week\u003c/a\u003e which asked about sorting tables.\u003c/p\u003e\n\u003cp\u003eThis is actually pretty easy to do but it’s just something we didn’t get around to. So I just implemented it and decided this would make a lot of sense in the core API. Sortable tables make a lot of sense and ideally should be the default.\u003c/p\u003e","title":"Sortable Table"},{"content":"\nSo you know how you write a blog post just before you go on vacation, press publish and never check that it actually got published…​ Funny thing, that’s exactly what I did and the blog post mentioning that I was on \u0026ldquo;vacation\u0026rdquo; for a couple of weeks never got published. Anyway, other people have been busy while I was \u0026ldquo;away\u0026rdquo; but I got a couple of things done too including animated gif support.\nBefore we get to that Steve did a lot of work on Mac retina display support. This is a HUGE leap in usability if you use a retina Mac. It makes the iPhone 3gs skin tiny but you can now use the iPhone 5 skin without scaling…​ It looks great and uses the pixels on these Macs really well.\nI also released a new cn1lib that implements animated GIF support in Codename One without the resource file hack. It’s still not something I would recommend as animated gifs can be pretty expensive in terms of resources but you can still use it to get a pretty decent animation.\nOne of the cool things is that this works as a plug in image and you should be able to use it in most places where image works. There are caveats though. E.g. you can’t use it as a native map marker as that image is passed to native. But other than such API’s it should work in labels and even in background image styles, although I would suggest avoiding the latter as it would be a memory/battery drain.\nThe library is in the extensions section and you can use it like this:\nForm hi = new Form(\u0026quot;Gif\u0026quot;, new BorderLayout()); try { hi.add(CENTER, new ScaleImageLabel(GifImage.decode(getResourceAsStream(\u0026quot;/giphy-downsized.gif\u0026quot;), 1177720))); } catch(IOException err) { log(err); } hi.show(); Notice the following:\nGifImage.decode can throw an IOException\nIt accepts an InputStream and the length of the input stream so you need to know the size in advance\nIt returns a GifImage which is a subclass of Image\nArchived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nsalah Alhaddabi — August 10, 2017 at 1:01 pm (permalink) salah Alhaddabi says:\nThanks a lot Shai.\nSo does this mean that the image will be animated continously??\nShai Almog — August 11, 2017 at 7:22 am (permalink) Shai Almog says:\nIt will loop based on the loop settings in the GIF itself. GIF’s contain a loop count. If it’s 0 it means looping forever.\nFrancesco Galgani — August 16, 2017 at 5:19 pm (permalink) Francesco Galgani says:\nThank you 🙂\nHow are the various densities managed by animated GIFs? Is there any multi-image equivalent for GIF?\nShai Almog — August 17, 2017 at 4:39 am (permalink) Shai Almog says:\nWe don’t. GIF has no density support so it can only be scaled. Using an approach like multi-image with GIF would be prohibitive as the file size will balloon. GIF’s are huge enough as it is.\nFrancesco Galgani — August 17, 2017 at 9:39 am (permalink) Francesco Galgani says:\nMmm… is there any way to get the right animated GIF size using an external service such as Cloudinary? I’ve never used it, so I don’t know if it supports animated GIFs.\nShai Almog — August 18, 2017 at 5:56 am (permalink) Shai Almog says:\nI don’t know. I’m not familiar with that.\nRainer — August 23, 2017 at 7:52 pm (permalink) Rainer says:\nHello! I tried the sample code with an animated gif, but nothing appears with the simulator\nShai Almog — August 24, 2017 at 9:04 am (permalink) Shai Almog says:\nDo you see any error in the console?\nHave you tried with a different gif file?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/animated-gif-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/animated-gif-support/vacation.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSo you know how you write a blog post just before you go on vacation, press publish and never check that it actually got published…​ Funny thing, that’s exactly what I did and the blog post mentioning that I was on \u0026ldquo;vacation\u0026rdquo; for a couple of weeks never got published. Anyway, other people have been busy while I was \u0026ldquo;away\u0026rdquo; but I got a couple of things done too including animated gif support.\u003c/p\u003e","title":"Animated Gif Support"},{"content":"\nHopefully by now, most of you have had a chance to try out the new GUI Builder – specifically the new \u0026ldquo;auto layout\u0026rdquo; mode that allows you to position components with much greater precision than before. For this blog post, I have prepared a couple of video tutorials to walk you through the creation of a Sign In form using the GUI Builder. I have taken the existing Sign In demo project as a basis, but I’m re-doing the UI, which was originally hand-coded, using the GUI Builder.\nThe finished result will look like this :\nFollowing Along If you want to follow along, you’ll need to do the following :\nDownload the codenameone-demos repository, then open the Sign In project in Netbeans.\nYou’ll need to copy the CodenameOneBuildClient.jar, JavaSE.jar, and lib directory from another Codename One project into the SignIn folder for the dependencies to be met. These videos were created using version 3.7.2 of the Codename One plugin. If you are using a different version, your experience will be slightly different.\nFor this video tutorial, I skipped directly to the blank canvas in the GUI builder. I skipped the part where I create a new GUIForm in Netbeans, and open it in the GUI builder. If you want to begin at the same point, you would perform the following steps :\nRight click on the com.codename1.demos.signin package in the project explorer, and select \u0026ldquo;Other…​\u0026rdquo; from the context menu. Select \u0026ldquo;Codename One\u0026rdquo; → \u0026ldquo;GUI Builder Form\u0026rdquo; In the next form, enter \u0026ldquo;SignInFormGB\u0026rdquo; for the name, and keep \u0026ldquo;Form\u0026rdquo; selected, and \u0026ldquo;Auto Layout\u0026rdquo; checked. Click \u0026ldquo;Finish\u0026rdquo;. This will create a java class named \u0026ldquo;SignInFormGB.java\u0026rdquo; in your com.codename1.demos.signin package.\nRight-click on this class in the project explorer, and select \u0026ldquo;Gui Builder\u0026rdquo; in the context menu to open up the blank form in the GUI Builder.\nNow you’re ready to begin.\nPart 1: Laying out the Form Summary of this Video :\nIn this video I lay out the key elements of the sign-in form. I begin by dragging an empty label onto the canvas which I intend to use as a guide. This is a little trick that can be used in the GUI builder to assist in aligning elements together.\nNext I drag the logo onto the canvas. For this I use a \u0026ldquo;Label\u0026rdquo; element. I set the \u0026ldquo;Icon\u0026rdquo; of this label using the property editor, and I remove the text.\nI then drag a text field onto the canvas to be used as the username field. This is positioned below the logo, and its top inset is linked to the logo. The left and right insets are linked to the left and right insets of the guide that we added at the beginning.\nI use copy/paste on the username field to add a password textfield below it. Then I drag a button onto the canvas, and position it below the password field.\nFinally, I add the buttons to be used for Google and Facebook login. For these buttons, I set their icons to images (which are already in the resource file), and I change their UIIDs to \u0026ldquo;Label\u0026rdquo; so that they don’t acquire the normal blue border that regular buttons get. These buttons are positioned at the bottom of the canvas, centered horizontally.\nKey Features Demonstrated In this Video\nDragging components from the palette onto the canvas.\nDragging components around the canvas.\nExplicitly setting insets using the inset editor.\nLinking component insets to other components on the form so that they will be repositioned properly if the parent container is resized.\nUsing the property editor to change the text, icon, hint, and name of text fields, buttons, and labels.\nThe Finished Product\nThe XML for the SignIn Form can be found here. If you want to skip to the end, you can copy and paste this code into your res/guibuilder/com/codename1/demos/signin/SignInFormGB.gui file.\nPart 2: Making the Form Responsive Summary of this Video\nNear the end of the first video I allude to a slight problem with our form: It looks horrible when displayed in landscape mode. This video shows how we can fix this, and produce a form that is fully responsive.\nWe begin by shifting our attention back to Netbeans. There we inspect the code that was generated by the GUI builder. I note that parts of the source code should not be modified manually, but we are free to modify other parts of the code as we see fit.\nI make a small change to the app’s start() method so that it uses our SignInFormGB class instead of the old, hand-coded sign-in form:\nnew SignInFormGB(theme).show(); Then we run our app in both portrait and landscape mode to demonstrate the problem :\nFigure 1. Portrait mode. Form looks fine\nFigure 2. Landscape mode. Form buttons start to overlap\nThere are many solutions to this problem, but the solution I demonstrate in this video is to conditionally hide the logo, and slide the username and password fields up to the top of the form, so that overlap doesn’t occur anymore. To that end, I override the layoutContainer() method in the SignInFormGB class.\n@Override public void layoutContainer() { LayeredLayout ll = (LayeredLayout)getLayout(); __**(1)** if (Display.getInstance().isPortrait()) { gui_logo.setVisible(true); __**(2)** ll.setReferenceComponentTop(gui_username, gui_logo, 1f); __**(3)** } else { gui_logo.setVisible(false); __**(4)** ll.setReferenceComponentTop(gui_username, null, 0f); __**(5)** } super.layoutContainer(); } __1 We get a reference to the LayeredLayout for the form. When Auto-Layout mode is enabled, the GUI Builder always uses LayeredLayout. __2 In portrait mode we make the logo visible. __3 In portrait mode, the top inset of the username field is linked to the bottom of the logo. The third parameter 1f, indicates the \u0026ldquo;oppositeness\u0026rdquo; of this link – because the top inset (of username) is linked to the bottom edge of the reference component (logo). __4 In landscape mode, we hide the logo. __5 With the logo hidden, we still need to slide up the username field. We do this by linking it to the top of the form instead of the logo. The 2nd parameter of setReferenceComponentTop() = null indicates that the top inset of username isn’t linked to any other component on the form. Then it defaults to the top edge of the form. The third parameter, 0f in this context indicates the \u0026ldquo;same-ness\u0026rdquo; of the side of the inset with the edge of the reference. I.e. the top inset is linked to the top edge of the form. Hence the 0f value. __ The layoutContainer() method is called whenever the form needs to be re-laid out. Now we run our app again in the simulator and find that our results have improved.\nFigure 3. Portrait mode after overriding layoutContainer. Form still looks fine.\nFigure 4. Landscape mode after overriding layoutContainer. Logo is now hidden, and the other components fit nicely on the form. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nTommy Mogaka — July 26, 2017 at 11:38 am (permalink) Awsome!\nLukman Javalove Idealist Jaji — July 27, 2017 at 11:25 pm (permalink) and some of us are still attached to the OGUIB…. 🙁\nFrancesco Galgani — July 30, 2017 at 7:53 am (permalink) Very useful tutorial, thank you.\nBogdan Istrate — August 13, 2017 at 10:22 pm (permalink) Very good tutorial!\nJson — September 2, 2017 at 6:07 am (permalink) hi!\na n00b to cn1 here.. I followed the above tutorials and was able to largely get the same results however, the final step, upon compiling I got this error:\njava.lang.ClassCastException: com.codename1.ui.layouts.FlowLayout cannot be cast to com.codename1.ui.layouts.LayeredLayout\non:\nLayeredLayout ll = (LayeredLayout) getLayout();\nof:\n@Override\npublic void layoutContainer() {\nLayeredLayout ll = (LayeredLayout) getLayout();\nif (Display.getInstance().isPortrait()) {\ngui_logo.setVisible(true);\nll.setReferenceComponentTop(gui_username, gui_logo, 1f);\n} else {\ngui_logo.setVisible(false);\nll.setReferenceComponentTop(gui_username, null, 0f);\n}\nsuper.layoutContainer();\n}\nI’ve checked the parent class which instantiated the form and couldnt find any declaration of a form being of type \u0026ldquo;FlowLayout\u0026rdquo;.\nAny ideas where this casting is set? thanks in advance!\nShai Almog — September 3, 2017 at 4:13 am (permalink) Make sure your plugin is at the latest version and open the project properties then press \u0026ldquo;OK\u0026rdquo; it should update the internal jar that should fix this.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-gui-builder-autolayout-signin-form-responsive/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-gui-builder-autolayout-signin-form-responsive/uidesign.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eHopefully by now, most of you have had a chance to try out the new GUI Builder – specifically the new \u0026ldquo;auto layout\u0026rdquo; mode that allows you to position components with much greater precision than before. For this blog post, I have prepared a couple of video tutorials to walk you through the creation of a Sign In form using the GUI Builder. I have taken the existing Sign In demo project as a basis, but I’m re-doing the UI, which was originally hand-coded, using the GUI Builder.\u003c/p\u003e","title":"Responsive Sign-In Form Using New GUI Builder"},{"content":"\nI hoped to finish migrating all of the material from the original bootcamp to the new courses but got delayed due to external influences. There isn’t much left so I’m sure I’ll be done with the existing modules in early August and get started on the first of the new modules.\nIf you haven’t kept up I added a lot of modules over the past few weeks covering a very wide set of subjects such as animations, tablet support, cloud server setup and much more.\nOne of the big additions to the Deep Dive into Mobile Development with Codename One is a new segment from Chidi Okwudire who is the author of parse4cn1 and the perfect person to teach it…​ This segment covers parse from the level of \u0026ldquo;I don’t know what parse is\u0026rdquo; to the level of adapting the app to the cloud server which is pretty cool!\nNext in Line Now that this is coming to an end we need to start picking up the important modules you feel are missing in the academy.\nOne thing I know we need to produce is a GUI builder tutorial, Steve has actually built a great one that we’ll publish soon in the blog but I think we need more than that although I’m not sure if these should be done now or later.\nWhat’s missing or isn’t covered enough?\nHow can this be improved?\nPlease let me know in the comments, I’ll use that and some of the other feedback I got and hopefully create a survey if necessary.\nThanks! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMichael Lindvall — July 25, 2017 at 2:20 pm (permalink) Michael Lindvall says:\nI thought the additional module for parse4cn1 was a great addition to the training.\nShai Almog — August 9, 2017 at 8:04 am (permalink) Shai Almog says:\nI would create new content with the GUI builder. There is no reason to redo things I already covered.\nGUI builder content takes longer to create as everything needs to be done via video and editing. The GUI builder is still evolving so it’s unclear when I’ll get to it.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/course-updates/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/course-updates/build-real-world-full-stack-mobile-apps-in-java.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI hoped to finish migrating all of the material from the original bootcamp to the \u003ca href=\"https://codenameone.teachable.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003enew courses\u003c/a\u003e but got delayed due to external influences. There isn’t much left so I’m sure I’ll be done with the existing modules in early August and get started on the first of the new modules.\u003c/p\u003e\n\u003cp\u003eIf you haven’t kept up I added a lot of modules over the past few weeks covering a very wide set of subjects such as animations, tablet support, cloud server setup and much more.\u003c/p\u003e","title":"Course Updates"},{"content":"\nWe’ve been very busy the past few weeks despite the summer time but August is always problematic, I will personally take some time off from the blog next week and near the end of August. To allow that I want to clear my table from a lot of the features that went into Codename One over the past couple of weeks and didn’t get sufficient or any documentation…​\nI wrote about some of these features before in the pixel perfect posts but I glossed over them. Some of the other features I didn’t cover at all!\nGoogle Plus is Dead Even when we wrote the blog posts detailing google plus login we new the end was near for that social network…​\nGoogle has pretty much ended support for the old Google+ login API’s and Steve migrated our existing Google+ support to use standard Google account connect. The cool thing is that the integration should now be MUCH easier and can be summed up with:\nGo to the Google Developer Portal\nFollow the steps to create an App\nEnable Google Sign-In\nDownload the google-services.json file into your project’s native/android directory\nDownload the GoogleService-Info.plist file into your project’s native/ios directory\nThis is the super short version…​ Steve updated the developer guide section on Google Cconnect with a longer more detailed explanation of the steps.\nFractional Padding/Margin This is a pretty big feature, currently the only way you can use this is by compiling your own version of the Codename One Designer but it will be around with plugin update 3.7.3 (we don’t have an ETA for that yet but I hope it won’t be too long).\nThis essentially means you would be able to use fractions to define padding and margin in the designer UI:\nFigure 1. Fractions in margin\nThis won’t work for pixels, it will get rounded down. But it should work great for millimeters where 1mm often proved to be too much in newer devices.\nThe reason we didn’t have that around sooner is that it requires a deep change to the resource file format which is always a painful nuanced process. We bundled this with another big change to the file format…​\nRethinking Round Rect We created Border in the LWUIT days and it grew very old. The goals it set out to accomplish were radically different from the ones we have today which is why we created RoundBorder when we needed something more expressive.\nRoundBorder works great for round and pill shapes but the classic square with rounded corners is still only available in the Border class. Normally, this would be enough but there is a lot of nuance we wanted to introduce to that API and a lot that we learned from the RoundBorder. So we created a new class RoundRectBorder which allows you to create a round border that’s more refined. Here I adapted the original RoundBorder sample to work with RoundRect:\nForm hi = new Form(\u0026quot;RoundRect\u0026quot;, new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER)); Button ok = new Button(\u0026quot;OK\u0026quot;); Button cancel = new Button(\u0026quot;Cancel\u0026quot;); Label loginLabel = new Label(\u0026quot;Login\u0026quot;, \u0026quot;Container\u0026quot;); loginLabel.getAllStyles().setAlignment(Component.CENTER); Label passwordLabel = new Label(\u0026quot;Password\u0026quot;, \u0026quot;Container\u0026quot;); passwordLabel.getAllStyles().setAlignment(Component.CENTER); TextField login = new TextField(\u0026quot;\u0026quot;, \u0026quot;Login\u0026quot;, 20, TextArea.ANY); TextField password = new TextField(\u0026quot;\u0026quot;, \u0026quot;Password\u0026quot;, 20, TextArea.PASSWORD); Style loginStyle = login.getAllStyles(); Stroke borderStroke = new Stroke(2, Stroke.CAP_SQUARE, Stroke.JOIN_MITER, 1); loginStyle.setBorder(RoundRectBorder.create(). strokeColor(0). strokeOpacity(120). stroke(borderStroke)); loginStyle.setBgColor(0xffffff); loginStyle.setBgTransparency(255); loginStyle.setMarginUnit(Style.UNIT_TYPE_DIPS); loginStyle.setMargin(Component.BOTTOM, 3); Style passwordStyle = password.getAllStyles(); passwordStyle.setBorder(RoundRectBorder.create(). strokeColor(0). strokeOpacity(120). stroke(borderStroke)); passwordStyle.setBgColor(0xffffff); passwordStyle.setBgTransparency(255); Container box = BoxLayout.encloseY( loginLabel, login, passwordLabel, password, GridLayout.encloseIn(2, cancel, ok)); Button closeButton = new Button(); Style closeStyle = closeButton.getAllStyles(); closeStyle.setFgColor(0xffffff); closeStyle.setBgTransparency(0); closeStyle.setPaddingUnit(Style.UNIT_TYPE_DIPS); closeStyle.setPadding(3, 3, 3, 3); closeStyle.setBorder(RoundBorder.create().shadowOpacity(100)); FontImage.setMaterialIcon(closeButton, FontImage.MATERIAL_CLOSE); Container layers = LayeredLayout.encloseIn(box, FlowLayout.encloseRight(closeButton)); Style boxStyle = box.getUnselectedStyle(); boxStyle.setBgTransparency(255); boxStyle.setBgColor(0xeeeeee); boxStyle.setMarginUnit(Style.UNIT_TYPE_DIPS); boxStyle.setPaddingUnit(Style.UNIT_TYPE_DIPS); boxStyle.setMargin(4, 3, 3, 3); boxStyle.setPadding(2, 2, 2, 2); hi.add(BorderLayout.CENTER, layers); hi.show(); Figure 2. Round rect sample\nThere are several things we learned from doing the RoundBorder that we applied and did differently in RoundRectBorder:\nWe use the UIID for the background color that just makes sense. We didn’t do the same for the stroke color/foreground color though. The background should now behave nicely including gradients and images!\nWe use millimeters where it makes sense, so a stroke can be in pixels since a 1 or 2 pixel stoke is something you might need but corner radius is always in millimeters as pixels just don’t fit here\nThis can also be customized via the designer tool which is another reason we had to change the resource file format:\nFigure 3. New rounded rectangle UI in the designer tool\nRipple Effect The ripple effect is an Android effect that occurs when you press and hold a button. It ripples slightly.\nIt’s actually pretty nice and assuring that your touch was intercepted. This effect is implemented in the component level but at the moment it was only turned on for Button. Moving forward this will probably be enabled for MultiButton, SpanButton and other component types.\nEvery component has a ripple effect flag now that you can check and toggle via isRippleEffect() and setRippleEffect(boolean). In buttons that flag is set from the default state which you can tune via the theme constant buttonRippleBool or via the Button.setButtonRippleEffectDefault(boolean) method.\nWhen a component is pressed and it has the ripple effect we keep painting it until it’s released. During that time we draw a translucent black color on top as a growing circle until it fills up the available space. You can customize the behavior of this painting by overriding paintRippleOverlay(Graphics g, int x, int y, int position). I wouldn’t recommend doing that unless you are going for a completely unique application look.\nButton Caps One of the more controversial changes we made was to upcase all the button text by default for Android. You can disable that behavior by using the theme constant capsButtonTextBool and set it to false or invoking Button.setCapsTextDefault(false).\nAndroid buttons should be upper case but iOS should have correct casing. This is very obvious when looking at iOS/Android UI’s critically. If you want to leave the global behavior but have case correctness for one individual button you can do this by invoking Button.setCapsText(boolean).\nIn order to reduce the impact of this behavior we didn’t apply it to every Button in existence even when it’s turned on. This only applies to Dialog buttons and buttons with the UIID’s Button or RaisedButton. That means that if you have a custom button UIID you will need to explicitly call setCapsText(Button.isCapsTextDefault()) to force this feature on for that Button. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nGareth Murfin — July 24, 2017 at 10:26 pm (permalink) Great update, it is a joy to see such leaps and bounds in functionality, congrats. Keep up the good work guys!..\nNick Koirala — July 25, 2017 at 2:20 am (permalink) I like the ripple effect but it seems like its in slow motion compared to the material design ripple effect, how is the speed controlled?\nShai Almog — July 25, 2017 at 4:34 pm (permalink) Right now it’s hardcoded. I looked at several implementations and each one looked very different so I eyeballed it. I’ll try to think of the right way to customize this, can you file an RFE?\nNick Koirala — August 10, 2017 at 3:10 am (permalink) Nick Koirala says:\nButton caps is a bit messy. If you use the GUI Builder it sets the text before setting the UIID so you get caps regardless of UIID (because its ‘Button’ when the text is set) so you can’t use a custom UIID to manage this if you wanted smaller buttons in a lowercase style or whatever. If you did want them caps but then set the text later with setText() it’ll be whatever case you set it as and the UIID has been set by then.\nAlso if you do use a custom UIID on a lot of buttons and want them in caps you need to call setCapsText(Button.isCapsTextDefault()) on each instance as its not an option you can toggle on all buttons at once or at a UIID level. So it requires additional code throughout simply to achieve what this is setting out to do (Caps on one platform and not on others).\nI’m not sure why this system is needed at all really, its not hard to implement if you do need it, not hard to turn off if you don’t want it, but if you do want caps on buttons on Android this system produces inconsistent behaviour.\nThis is a change that has an effect on the UI of apps currently in development – changing the style between builds, with the default set to be the new behaviour. I don’t think that should be the way that updates like this are rolled out.\nShai Almog — August 10, 2017 at 5:17 am (permalink) Shai Almog says:\nThanks for the feedback. I agree we need a better way to indicate supported/unsupported UIID’s. Any suggestions?\nI chose the default to work with specific UIID’s since button is so widespread that doing it for everything might have been even more disruptive.\nThe goal is to have a default \u0026ldquo;native\u0026rdquo; behavior that’s \u0026ldquo;seamless\u0026rdquo;. Android does the same thing by styling buttons as all caps by default so this seems like the right thing to do.\nIn that sense a better place to put this would have been the style text effects property, I chose not to do that for performance reasons but I’m not sure if that was the right call.\nI agree that launching something and flipping a default is problematic but leaving something that’s wrong is problematic too. I asked in the original post for suggestions on how we can move things forward without disruption and got crickets…\nIt’s pretty easy to say \u0026ldquo;don’t release it like this\u0026rdquo; without suggesting a better way. We asked this multiple times and suggestions effectively amounted to don’t change the product. Those conflict with the notion of moving it forward:\n– Leave it off by default – that’s a bad suggestion. It’s off then no one uses it and it might as well not exist\n– Release in a specific time or with huge/many announcements – We did an announcement and included a big \u0026ldquo;compatibility warning\u0026rdquo;. Distributed as much as we reasonably can… In the past we did bigger/longer term announcements for similar changes (gradle migration, xcode migration etc). People don’t read these. It’s just a waste of time that delays forward progress\n– Add ability to disable this easily – we have that\n– Add ability not to be affected – we did this right after the 3.7 release so a versioned build would be relevant and allow you not to feel such issues\nWe have many changes like this coming so if you have a suggestion I’m listening…\nNick Koirala — August 10, 2017 at 6:39 am (permalink) Nick Koirala says:\nI think it should apply to buttons regardless of style – obviously still with the options to turn it off. Using UIID to signal if it applies or not is a good idea, but only if it was part of the style definition which no doubt adds a whole lot more complexity.\nI didn’t think it was too important one way or the other if button labels were in caps on Android – most of my apps aren’t really trying to look native but rather mostly similar but familiar on each platform – but once I suddenly had an Android build that had some buttons in caps and some not it was a mess that needed to be resolved. As the GUI Builder puts them all in caps regardless of UIID but calls to setText may not it took some tidying to put right. In this case I DID go for having all buttons in uppercase on Android mainly because your post highlighted that it was more correct but due to the implementation it was more work than just setting the theme constant and putting it back to proper case.\nObviously changes and progress of your product can’t be a democratic progress where everyone’s view is counted and people are happy all the time, but forced changes especially ones that alter the look and feel of the app are not certainly not desirable. I’d suggest new features or performance enhancements get rolled out straight away as you currently do. But changes to default behaviour do need to be signaled a bit better and they need to be solid when they are made the default.\nI check the blog every day, to the point I was worried about you when you went on vacation :). I’ve used the options for the newVM and gradle builds when they were rolled out. It was great to be able to build projects consistently with the old settings while these changes were coming in and also use the new settings for new projects.\nSo my preference is that any changes to default have some period where the original behaviour is default. I understand why you don’t like this as it makes the roll out more difficult with less initial adoption but its a balancing act between letting developers complete their projects, updating and providing new functionality to your core, and using your developers as guinea pigs on new functionality and disrupting their own progress.\nI’m not sure how difficult it is to manage changes with the build process at your end – big red warnings in the console output or something. I’m thinking of the way methods are deprecated before being removed from APIs allows progress and updates while making developers be aware of the upcoming changes and giving them the opportunity to adapt on their schedules.\nShai Almog — August 11, 2017 at 7:21 am (permalink) Shai Almog says:\nThe GUI builder uppercasing is indeed something we need to fix. You are referring to the new GUI builder right?\nI’ve committed a fix for this and will push it into today’s update.\nIf we were building a new product from scratch I would uppercase all buttons or put this into the style both of which I agree are better choices. The problem is that both would disrupt too many production apps in unpredictable ways. I’d also want this to apply correctly for multibuttons, span buttons etc. as we move forward and none of them are buttons. So the \u0026ldquo;right thing\u0026rdquo; here is a bit \u0026ldquo;off\u0026rdquo;.\nI’m actually all for a democracy here, even in a democracy there is a PM or President who navigates but can’t do stuff congress disagrees with. Unfortunately I made a post about this which got literally zero comments. Maybe it’s the writing that’s too verbose but I’m guessing it’s just hard for people to understand until they see something that impacts their app.\nIn the past we did a lot of staged rollouts like the ones you describe and the results were the exact same thing. Everyone ignored the rollout until we flipped the default. That made releasing harder as we already moved forward on several fronts and it was harder to revert.\nOther tools take the opposite approach to us where developers work on the feature release e.g. 3.7.0 (like our versioned builds) and get an update once every few months that’s really disruptive. Some developers stay on older versions which makes their support process much harder. I don’t think that’s better. Every developer works on a different version and we don’t get immediate feedback for features/bugs so by the time something reaches you guys we forgot why we did something or what we did. Smaller features vanish with big releases like that and it’s harder on everyone.\nUsing some notification on changes in the build server makes sense for changes like the 64 bit migration (we did that and people still ignore it) but for something like this it doesn’t really make sense. It might seem like a huge disruptive change to you but the fact is that except for a few people who had a problem with it, this went mostly unnoticed by the community at large. That’s a good thing, changes like this should be mostly seamless.\nNotice that when Google or Apple update their OS’s a native app that’s already on the device will break and/or change its look. With Codename One updates you will only see it for your builds not for production apps so we are better off than standard native apps in that sense.\nDiamond — August 22, 2017 at 9:13 am (permalink) Diamond says:\nI love the fractional padding and margin values. Will this be available in code too?\nLike having:\ncmp.getAllStyles().setPaddingTop(2.6);\nShai Almog — August 22, 2017 at 1:20 pm (permalink) Shai Almog says:\nRight now we have only the setPadding(top, bottom, left, right) that accepts float values (not double like your code does). We don’t have the floating point equivalents for setPaddingTop/Bottom/Left/Right. Mostly due to laziness. Notice that if you want to submit a PR you will need to add new methods and can’t change the existing method signature from int to float as that will break binary compatibility.\nDiamond — August 22, 2017 at 2:10 pm (permalink) Diamond says:\nI’ve added the methods.\nThomas — March 22, 2018 at 8:00 pm (permalink) Thomas says:\nIs there a way to use rounded borders from the new GUI builder? In the old builder there was a border wizard that allowed to create custom borders by generating a 9 components image but I could not find it in the new GUI builder and the RoundRectBorder type is not offered as an option (only the \u0026ldquo;round\u0026rdquo; border type, that seems to map to RoundBorder exists in the border editor of the new GUI builder)\nShai Almog — March 23, 2018 at 2:42 am (permalink) Shai Almog says:\nWhen you edit a style in the GUI builder it’s meant more as a small override over the default theming. 9-piece borders are a bit more complex as they require image generation and this can get tricky if you have multiple variants.\nRoundRectBorder is relatively new and came to be in parallel to this feature. Can you please file an issue on that? It should go into the style UI too.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/factional-padding-margin-rounded-border-ripple-caps-google-connect/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/factional-padding-margin-rounded-border-ripple-caps-google-connect/new-features-6.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve been very busy the past few weeks despite the summer time but August is always problematic, I will personally take some time off from the blog next week and near the end of August. To allow that I want to clear my table from a lot of the features that went into Codename One over the past couple of weeks and didn’t get sufficient or any documentation…​\u003c/p\u003e","title":"Fractional Padding/Margin, Rounded Border, Ripple, Caps, Google Connect"},{"content":"\nLocalization and internationalization are probably some of the most important features for a modern app. Most frameworks tuck on localization as an afterthought as authors of such frameworks are often born in the states…​ Codename One integrates localization, deep into the framework. It becomes transparent and invisible…​\nWe plan to make a lot of enhancement to the localization process which is why I was hesitant on releasing this update. However, we don’t have an ETA for these updates and I don’t think that’s a valid reason to delay the release any further. One of the nice things with our new video system is that this would be relatively easy to edit with new information as it becomes available…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-localization-intenationalization-i18n-l10n/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-localization-intenationalization-i18n-l10n/learn-codenameone-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eLocalization and internationalization are probably some of the most important features for a modern app. Most frameworks tuck on localization as an afterthought as authors of such frameworks are often born in the states…​ Codename One integrates localization, deep into the framework. It becomes transparent and invisible…​\u003c/p\u003e\n\u003cp\u003eWe plan to make a lot of enhancement to the localization process which is why I was hesitant on releasing this update. However, we don’t have an ETA for these updates and I don’t think that’s a valid reason to delay the release any further. One of the nice things with our new video system is that this would be relatively easy to edit with new information as it becomes available…​\u003c/p\u003e","title":"Tutorial – Localization and Internationalization (i18n/l10n)"},{"content":"\nLast week I wrote about the effort of revitalizing the native themes in Codename One and I’m not sure if I got the point across as I would have liked it. So this week before I go into the changes and work we’re doing I’d like to take a step back and explain how everything works and why we need a native theme…​\n__ To implement the features this week we made some big changes check out the section titled changes for the gist of this…​ In order to adapt an application to OS conventions Codename One loads an internal theme that matches the given OS. This is a theme we developed for every OS we support. We then load your theme on top of that theme and you can override various default behaviors.\nThe native theme is crucial as it defines a lot of conventions, standards \u0026amp; theme constants that would be hard to guess otherwise. A great example for that is the padding of the status bar on iOS which is defined in the native theme.\nWhen we launched Codename One the latest iOS version was 4.x and apps looked very different back then. So we designed the iOS theme for that. Android 2.x just launched around then and we built the Android theme with that purpose. Both OS’s looked radically different from one another in practically every way.\nSince then both Apple and Google adopted a lot of the flat design sensibilities and made their respective UI’s cleaner. We adapted the native themes to match and left it at that as changes in the UI were far more nuanced.\nHowever, as our product matures people expect a higher standard of fidelity both from Codename One and from apps in general and we didn’t dedicate resources to address a lot of the nuances. Google has made great strides in refining their UI and UX designs and we didn’t keep up mostly expecting developers to do the design while we focus on the technology. While design is still your responsibility as a developer, we want to shorten the distance you need to go in order to create a good looking native feel.\nThe purpose of this segment is 3 fold:\nDocument the process\nInform you of upcoming changes\nEducate you about how things \u0026ldquo;should\u0026rdquo; look\nYou don’t really need to do anything. Your apps will just \u0026ldquo;look better\u0026rdquo;.\nWith the new native themes I also hope to reduce variance between the native themes as the OS’s look far more alike today. I also hope to reduce usage of images and as a result allow deeper customization with less resources. E.g. currently in order to change the color of components we often need to define image borders but this is fixable. We should be able to colorize an app just by overriding a few elements.\nChanges In order to implement the things below we had to do a lot of changes to the core of Codename One, I’ll write more about what we did exactly next week but these are the things you need to be careful with:\nIf you are a pro user using the versioned build feature, don’t update the skins!\nWe had to update the resource file format to support some functionality. If you need this contact us on support and we’ll add a workaround.\nThe Android style ripple effect will be on by default for buttons. You can disable it by defining the theme constant buttonRippleBool to false\nIf you want to edit the resource file for the native Android theme you will need to compile your own resource editor (designer tool). We’ll release a plugin update to include this eventually but right now this is what we have\nAs I mentioned before we’ll probably do a lot of these changes in the coming months as we strive to align more closely with the native OS’s and refine our themes.\nLast Time on Pixel Perfect Last time on pixel perfect I mentioned these big ticket items for the next session:\nRaised button UIID\nRipple effect\nRound corners on Android raised button and pressed color\nLets get thru them one by one…​\nRaised Button First we need to know whether a raised button exists in the theme. For this we’ve added the theme constant hasRaisedButtonBool which will return true on Android but will be false elsewhere. You can use it like this:\nif(UIManager.getInstance().isThemeConstant(\u0026quot;hasRaisedButtonBool\u0026quot;, false)) { // that means we can use a raised button } To enable this I added a new RaisedButton UIID that derives from Button and will act like it except for the places where hasRaisedButtonBool is true in which case it will look like this:\nFigure 1. Raised and flat button in simulator\nNotice that you can easily customize the colors of these buttons now since the border respects user colors…​\nIn this case I just set the background color to purple and the foreground to white:\nFigure 2. Purple raised button\nForm f = new Form(\u0026quot;Pixel Perfect\u0026quot;, BoxLayout.y()); Button b = new Button(\u0026quot;Raised Button\u0026quot;, \u0026quot;RaisedButton\u0026quot;); Button r = new Button(\u0026quot;Flat Button\u0026quot;); f.add(b); f.add(r); f.show(); How does it Work? To enable this I added a new round rect border type similar to the round border type. This will supersede the existing round rect border functionality and there is quite a bit to say about that which I will cover next week.\nFor now the cool thing is you can use use the system colors and things will work pretty much as you would expect…​\nPressed Effect for Flat Buttons As I mentioned above we have a new round rectangle border. It’s now used for the pressed effect in the flat buttons on Android as well as indicated here:\nFigure 3. Pressed state for the flat button\nTo generate this image I used this code:\nCheckBox pressed = CheckBox.createToggle(\u0026quot;Pressed Flat Button\u0026quot;); pressed.setSelected(true); pressed.setUIID(\u0026quot;Button\u0026quot;); f.add(pressed); That’s actually really important…​ If you try to press a button with your finger and not via this approach you might get a different result because of the next item…​\nRipple Effect The ripple effect in material design highlights the location of the finger and grows as a circle to occupy the full area of the component as the user presses the button.\nWe added the ability to perform a ripple effect by darkening the touched area and growing that in a quick animation:\nRipple effect can be applied to any component but we currently only have it turned on for buttons on Android which also applies to things like title commands, side menu elements etc. This might not apply at this moment to lead components like multi-buttons but we’re getting there…​\nComponent has a new property to enable the ripple effect setRippleEffect(boolean) and the corresponding isRippleEffect(). You can turn it on or off individually in the component level. However, Button has static setButtonRippleEffectDefault(boolean) and isButtonRippleEffectDefault(). These allow us to define the default behavior for all the buttons and that can be configured via the theme constant buttonRippleBool which is currently on by default on the native Android theme.\nMoving On To get the full changes you will also need to update your simulator skins again this Friday. Once you update them your libs must be up to date too with Update Client Libs from Codename One Settings → Basic.\nAfter last week we got quite a bit of contacts about buttons becoming upper case all of a sudden. I understand that people don’t want to read the long blog posts or even shorter alerts explaining these updates. A huge part of the reason we are doing these changes now is the proximity to the 3.7 release so pro users can leverage versioned build effectively in case we break something big…​\nWe are going to do a lot of changes here, we don’t want to disrupt your work but it’s essential we move Codename One forward. If there is any way we can communicate this better we are open to suggestions…​ Keep in mind that there will be a lot of these changes and just having a banner somewhere wouldn’t be enough.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/pixel-perfect-material-buttons-part-2/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/pixel-perfect-material-buttons-part-2/pixel-perfect.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eLast week I \u003ca href=\"/blog/pixel-perfect-material-buttons.html\"\u003ewrote about the effort of revitalizing the native themes\u003c/a\u003e in Codename One and I’m not sure if I got the point across as I would have liked it. So this week before I go into the changes and work we’re doing I’d like to take a step back and explain how everything works and why we need a native theme…​\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eTo implement the features this week we made some big changes check out the section titled changes for the gist of this…​\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eIn order to adapt an application to OS conventions Codename One loads an internal theme that matches the given OS. This is a theme we developed for every OS we support. We then load your theme on top of that theme and you can override various default behaviors.\u003c/p\u003e","title":"Pixel Perfect – Material Buttons part 2"},{"content":"\nAs you may have already read, we have just added support for Kotlin in Codename One. In this post, I elaborate on some of the behind the scene work that was involved in bringing Kotlin to Codename One.\nWhat is a JVM Language? A JVM Language is any programming language that can be compiled to byte-codes that will run on the JVM (Java Virtual Machine). Java was the original JVM language, but many others have sprung up over the years. Kotlin, Scala, Groovy, and JRuby come to mind as well-established and mature languages, but there are many others.\nHow Hard is it to Port a JVM Language to Codename One? The difficulty of porting a particular language to Codename One will vary depending on such factors as:\nDoes it require a runtime library?\nHow complex is the runtime library? (E.g. Does it require classes that aren’t currently offered in Codename One’s subset of the java standard libraries?) Does it need reflection?\nCodename One doesn’t support reflection because it would result in a very large application size. If a JVM language requires reflection just to get off the ground then adding it to Codename one would be tricky. Does it perform any runtime byte-code manipulation?\nSome dynamic languages may perform byte-code manipulation at runtime. This is problematic on iOS (and possibly other platforms) which prohibits such runtime behaviour. Step 1: Assess the Language The more similar a language, and its build outputs are to Java, the easier it will be to port (probably). Most JVM languages have two parts:\nA compiler, which compiles source files to JVM byte-code (usually as .class files).\nA runtime library.\nCurrently I’m only aware of one language (other than Java) that doesn’t require a runtime library, and that is Mirah.\n__ Codename One also supports Mirah Assessing the Byte-Code The first thing I do is take a look at the byte-code that is produced by the compiler. I use javap to print out a nice version.\nConsider this sample Kotlin class:\npackage com.codename1.hellokotlin2 import com.codename1.ui.Button import com.codename1.ui.Form import com.codename1.ui.Label import com.codename1.ui.layouts.BoxLayout /** * Created by shannah on 2017-07-10. */ class KotlinForm : Form { constructor() : super(\u0026quot;Hello Kotlin\u0026quot;, BoxLayout.y()) { val label = Label(\u0026quot;Hello Kotlin\u0026quot;) val clickMe = Button(\u0026quot;Click Me\u0026quot;) clickMe.addActionListener { label.setText(\u0026quot;You Clicked Me\u0026quot;); revalidate(); } add(label).add(clickMe); } } Let’s take a look at the bytecode that Kotlin produced for this class:\n$ javap -v com/codename1/hellokotlin2/KotlinForm.class Classfile /Users/shannah/IdeaProjects/HelloKotlin2/out/production/HelloKotlin2/com/codename1/hellokotlin2/KotlinForm.class Last modified 10-Jul-2017; size 1456 bytes MD5 checksum 1cb00f6e63b918bb5a9f146ca8b0b78e Compiled from \u0026quot;KotlinForm.kt\u0026quot; public final class com.codename1.hellokotlin2.KotlinForm extends com.codename1.ui.Form SourceFile: \u0026quot;KotlinForm.kt\u0026quot; InnerClasses: static final #31; //class com/codename1/hellokotlin2/KotlinForm$1 RuntimeVisibleAnnotations: 0: #56(#57=[I#58,I#58,I#59],#60=[I#58,I#61,I#58],#62=I#58,#63=[s#64],#65=[s#55,s#66,s#6,s#67]) minor version: 0 major version: 50 flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER Constant pool: #1 = Utf8 com/codename1/hellokotlin2/KotlinForm #2 = Class #1 // com/codename1/hellokotlin2/KotlinForm #3 = Utf8 com/codename1/ui/Form #4 = Class #3 // com/codename1/ui/Form #5 = Utf8 \u0026lt;init\u0026gt; #6 = Utf8 ()V #7 = Utf8 Hello Kotlin #8 = String #7 // Hello Kotlin #9 = Utf8 com/codename1/ui/layouts/BoxLayout #10 = Class #9 // com/codename1/ui/layouts/BoxLayout #11 = Utf8 y #12 = Utf8 ()Lcom/codename1/ui/layouts/BoxLayout; #13 = NameAndType #11:#12 // y:()Lcom/codename1/ui/layouts/BoxLayout; #14 = Methodref #10.#13 // com/codename1/ui/layouts/BoxLayout.y:()Lcom/codename1/ui/layouts/BoxLayout; #15 = Utf8 com/codename1/ui/layouts/Layout #16 = Class #15 // com/codename1/ui/layouts/Layout #17 = Utf8 (Ljava/lang/String;Lcom/codename1/ui/layouts/Layout;)V #18 = NameAndType #5:#17 // \u0026quot;\u0026lt;init\u0026gt;\u0026quot;:(Ljava/lang/String;Lcom/codename1/ui/layouts/Layout;)V #19 = Methodref #4.#18 // com/codename1/ui/Form.\u0026quot;\u0026lt;init\u0026gt;\u0026quot;:(Ljava/lang/String;Lcom/codename1/ui/layouts/Layout;)V #20 = Utf8 com/codename1/ui/Label #21 = Class #20 // com/codename1/ui/Label #22 = Utf8 (Ljava/lang/String;)V #23 = NameAndType #5:#22 // \u0026quot;\u0026lt;init\u0026gt;\u0026quot;:(Ljava/lang/String;)V #24 = Methodref #21.#23 // com/codename1/ui/Label.\u0026quot;\u0026lt;init\u0026gt;\u0026quot;:(Ljava/lang/String;)V #25 = Utf8 com/codename1/ui/Button #26 = Class #25 // com/codename1/ui/Button #27 = Utf8 Click Me #28 = String #27 // Click Me #29 = Methodref #26.#23 // com/codename1/ui/Button.\u0026quot;\u0026lt;init\u0026gt;\u0026quot;:(Ljava/lang/String;)V #30 = Utf8 com/codename1/hellokotlin2/KotlinForm$1 #31 = Class #30 // com/codename1/hellokotlin2/KotlinForm$1 #32 = Utf8 (Lcom/codename1/hellokotlin2/KotlinForm;Lcom/codename1/ui/Label;)V #33 = NameAndType #5:#32 // \u0026quot;\u0026lt;init\u0026gt;\u0026quot;:(Lcom/codename1/hellokotlin2/KotlinForm;Lcom/codename1/ui/Label;)V #34 = Methodref #31.#33 // com/codename1/hellokotlin2/KotlinForm$1.\u0026quot;\u0026lt;init\u0026gt;\u0026quot;:(Lcom/codename1/hellokotlin2/KotlinForm;Lcom/codename1/ui/Label;)V #35 = Utf8 com/codename1/ui/events/ActionListener #36 = Class #35 // com/codename1/ui/events/ActionListener #37 = Utf8 addActionListener #38 = Utf8 (Lcom/codename1/ui/events/ActionListener;)V #39 = NameAndType #37:#38 // addActionListener:(Lcom/codename1/ui/events/ActionListener;)V #40 = Methodref #26.#39 // com/codename1/ui/Button.addActionListener:(Lcom/codename1/ui/events/ActionListener;)V #41 = Utf8 com/codename1/ui/Component #42 = Class #41 // com/codename1/ui/Component #43 = Utf8 add #44 = Utf8 (Lcom/codename1/ui/Component;)Lcom/codename1/ui/Container; #45 = NameAndType #43:#44 // add:(Lcom/codename1/ui/Component;)Lcom/codename1/ui/Container; #46 = Methodref #2.#45 // com/codename1/hellokotlin2/KotlinForm.add:(Lcom/codename1/ui/Component;)Lcom/codename1/ui/Container; #47 = Utf8 com/codename1/ui/Container #48 = Class #47 // com/codename1/ui/Container #49 = Methodref #48.#45 // com/codename1/ui/Container.add:(Lcom/codename1/ui/Component;)Lcom/codename1/ui/Container; #50 = Utf8 clickMe #51 = Utf8 Lcom/codename1/ui/Button; #52 = Utf8 label #53 = Utf8 Lcom/codename1/ui/Label; #54 = Utf8 this #55 = Utf8 Lcom/codename1/hellokotlin2/KotlinForm; #56 = Utf8 Lkotlin/Metadata; #57 = Utf8 mv #58 = Integer 1 #59 = Integer 6 #60 = Utf8 bv #61 = Integer 0 #62 = Utf8 k #63 = Utf8 d1 #64 = Utf8 nn20¢¨ #65 = Utf8 d2 #66 = Utf8 Lcom/codename1/ui/Form; #67 = Utf8 HelloKotlin2 #68 = Utf8 KotlinForm.kt #69 = Utf8 Code #70 = Utf8 LocalVariableTable #71 = Utf8 LineNumberTable #72 = Utf8 SourceFile #73 = Utf8 InnerClasses #74 = Utf8 RuntimeVisibleAnnotations { public com.codename1.hellokotlin2.KotlinForm(); descriptor: ()V flags: ACC_PUBLIC Code: stack=5, locals=3, args_size=1 0: aload_0 1: ldc #8 // String Hello Kotlin 3: invokestatic #14 // Method com/codename1/ui/layouts/BoxLayout.y:()Lcom/codename1/ui/layouts/BoxLayout; 6: checkcast #16 // class com/codename1/ui/layouts/Layout 9: invokespecial #19 // Method com/codename1/ui/Form.\u0026quot;\u0026lt;init\u0026gt;\u0026quot;:(Ljava/lang/String;Lcom/codename1/ui/layouts/Layout;)V 12: new #21 // class com/codename1/ui/Label 15: dup 16: ldc #8 // String Hello Kotlin 18: invokespecial #24 // Method com/codename1/ui/Label.\u0026quot;\u0026lt;init\u0026gt;\u0026quot;:(Ljava/lang/String;)V 21: astore_1 22: new #26 // class com/codename1/ui/Button 25: dup 26: ldc #28 // String Click Me 28: invokespecial #29 // Method com/codename1/ui/Button.\u0026quot;\u0026lt;init\u0026gt;\u0026quot;:(Ljava/lang/String;)V 31: astore_2 32: aload_2 33: new #31 // class com/codename1/hellokotlin2/KotlinForm$1 36: dup 37: aload_0 38: aload_1 39: invokespecial #34 // Method com/codename1/hellokotlin2/KotlinForm$1.\u0026quot;\u0026lt;init\u0026gt;\u0026quot;:(Lcom/codename1/hellokotlin2/KotlinForm;Lcom/codename1/ui/Label;)V 42: checkcast #36 // class com/codename1/ui/events/ActionListener 45: invokevirtual #40 // Method com/codename1/ui/Button.addActionListener:(Lcom/codename1/ui/events/ActionListener;)V 48: aload_0 49: aload_1 50: checkcast #42 // class com/codename1/ui/Component 53: invokevirtual #46 // Method add:(Lcom/codename1/ui/Component;)Lcom/codename1/ui/Container; 56: aload_2 57: checkcast #42 // class com/codename1/ui/Component 60: invokevirtual #49 // Method com/codename1/ui/Container.add:(Lcom/codename1/ui/Component;)Lcom/codename1/ui/Container; 63: pop 64: return LocalVariableTable: Start Length Slot Name Signature 32 32 2 clickMe Lcom/codename1/ui/Button; 22 42 1 label Lcom/codename1/ui/Label; 0 65 0 this Lcom/codename1/hellokotlin2/KotlinForm; LineNumberTable: line 13: 0 line 14: 12 line 15: 22 line 16: 32 line 21: 48 } That’s a big mess of stuff, but it’s pretty easy to pick through it when you know what you’re looking for. The layout of this output is pretty straight forward. The beginning shows that this is a class definition:\npublic final class com.codename1.hellokotlin2.KotlinForm extends com.codename1.ui.Form Even just comparing this line with the class definition from the source file we have learned something about the Kotlin compiler. It has made the class final by default. That observation shouldn’t affect our assessment here, but it is kind of interesting.\nAfter the class definition, it shows the internal classes:\nInnerClasses: static final #31; //class com/codename1/hellokotlin2/KotlinForm$1 The Constant Pool\nAnd the constants that are used in the class:\nConstant pool: #1 = Utf8 com/codename1/hellokotlin2/KotlinForm #2 = Class #1 // com/codename1/hellokotlin2/KotlinForm #3 = Utf8 com/codename1/ui/Form #4 = Class #3 // com/codename1/ui/Form #5 = Utf8 \u0026lt;init\u0026gt; #6 = Utf8 ()V #7 = Utf8 Hello Kotlin #8 = String #7 // Hello Kotlin #9 = Utf8 com/codename1/ui/layouts/BoxLayout ... etc... The constant pool will consist of class names, and strings mostly. You’ll want to peruse this list to see if the compiler has added any classes that aren’t in the source code. In the example above, it looks like Kotlin is pretty faithful to the original source’s dependencies. It didn’t inject any classes that aren’t in the original source.\nEven if the compiler does inject other dependencies into the bytecode, it might not be a problem. It is only a problem if those classes aren’t supported by Codename One. Keep your eyes peeled for anything in the java.lang.reflect package or unsolicited use of java.net, java.nio, or any other package that aren’t part of the Codename One standard library. If you’re not sure if a class or package is available in the Codename One standard library, check the javadocs.\nThe ByteCode Instructions :\nAfter the constant pool, we see each of the methods of the class written out as a list of bytecode instructions. E.g.\npublic com.codename1.hellokotlin2.KotlinForm(); descriptor: ()V flags: ACC_PUBLIC Code: stack=5, locals=3, args_size=1 0: aload_0 1: ldc #8 // String Hello Kotlin 3: invokestatic #14 // Method com/codename1/ui/layouts/BoxLayout.y:()Lcom/codename1/ui/layouts/BoxLayout; 6: checkcast #16 // class com/codename1/ui/layouts/Layout 9: invokespecial #19 // Method com/codename1/ui/Form.\u0026quot;\u0026lt;init\u0026gt;\u0026quot;:(Ljava/lang/String;Lcom/codename1/ui/layouts/Layout;)V 12: new #21 // class com/codename1/ui/Label 15: dup 16: ldc #8 // String Hello Kotlin etc... In the above snippet, the first instruction is aload_0 (which adds this to the stack). The 2nd instruction is ldc, (which loads constant #8 — the string \u0026ldquo;Hello Kotlin\u0026rdquo; to the stack). The 3rd instruction is invokestatic which calls the static method define by Constant #14 from the constant pool, with the two parameters that had just been added to the stack.\n__ You don’t need to understand what all of these instructions do. You just need to look for instructions that may be problematic. The only instruction that I think might be problematic is \u0026ldquo;invokedynamic\u0026rdquo;. All other instructions should work find in Codename One. (I don’t know for a fact that invokedynmic won’t work – I just suspect it might not work on some platforms).\nSummary of Byte-code Assessment\nSo to summarize, the byte-code assessment phase, we’re basically just looking to make sure that the compiler doesn’t tend to add dependencies to parts of the JDK that Codename One doesn’t currently support. And we want to make sure that it doesn’t use invokedynamic.\nIf you find that the compiler does use invokedynamic or add references to classes that Codename One doesn’t support, don’t give up just yet. You might be able to create your own \u0026ldquo;porting\u0026rdquo; runtime library that will provide these dependencies at runtime.\nAssessing the Runtime Library The process for assessing the runtime library is pretty similar to the process for the bytecodes. You’ll want to get your hands on the language’s runtime library, and use javap to inspect the .class files. You’re looking for the same things as you were looking for in the compiler’s output: \u0026ldquo;invokedynamic\u0026rdquo; and classes that aren’t supported in Codename One.\nStep 2: Convert the Runtime Library into a CN1Lib Once you have assessed the language and are optimistic that it is a good candidate for porting, you can proceed to port the runtime library into Codename One. Usually that language’s runtime library will be distributed in .jar format. You need to convert this into a cn1lib so that it can be used in a Codename One project. If you can get your hands on the source code for the runtime library then the best approach is to paste the source files into a Codename One Library project, and try to build it. This has the advantage that it will validate the source during compile to ensure that it doesn’t depend on any classes that Codename One doesn’t support.\nIf you can’t find the sources of the runtime library or they don’t seem to be easily \u0026ldquo;buildable\u0026rdquo;, then the next best thing is to just get the binary distribution’s jar file and convert it to a cn1lib. This is what I did for the Kotlin runtime library.\nThis procedure exploits the fact that a cn1lib file is just a zip file with a specific file structure inside it. The cross-platform Java .class files are all contained inside a file named \u0026ldquo;main.zip\u0026rdquo;, inside the zip file. This is the only mandatory file that must be inside a cn1lib.\nTo make the library easier to use the cn1lib file can also contain a file named \u0026ldquo;stubs.zip\u0026rdquo; which includes stubs of the Java sources. When you build a cn1lib using a Codename One Library project, it will automatically generate stubs of the source so that the IDE will have access to nice things like Javadoc when using the library. The kotlin distribution includes a separate jar file with the runtime sources, named \u0026ldquo;kotlin-runtime-sources.jar\u0026rdquo;, so I used this as the \u0026ldquo;stubs\u0026rdquo;. It contains full sources, which isn’t necessary, but it also doesn’t hurt.\nSo now that I had my two jar files: kotlin-runtime.jar and kotlin-runtime-sources.jar, I created a new empty directory, and copied them inside. I renamed the jars \u0026ldquo;main.zip\u0026rdquo; and \u0026ldquo;stubs.zip\u0026rdquo; respectively. Then I zipped up the directory and renamed the zip file \u0026ldquo;kotlin-runtime.cn1lib\u0026rdquo;.\n__ Building cn1libs manually in this way is a very bad habit, as it bypasses the API verification step that normally occurs when building a library project. It is possible, even likely, that the jar files that you convert depend on classes that aren’t in the Codename One library, so your library will fail at runtime in unexpected ways. The only reason I could do this with kotlin’s runtime (with some confidence) is because I already analyzed the bytecodes to ensure that they didn’t include anything problematic. Step 3: Hello World For our \u0026ldquo;Hello World\u0026rdquo; test we will need to create a separate project in our JVM language and produce class files that we will manually copy into an appropriate location of our project. We’ll want to use the normal tools for the language and not worry about how it integrates with Codename One. For Kotlin, I just followed the getting started tutorial on the Kotlin site to create a new Kotlin project in IntelliJ. When I ported Mirah, I just used a text editor and the mirahc command-line compiler to create my Hello World class. The tools and process will depend on the language.\nHere is the \u0026ldquo;hello world\u0026rdquo; I created in Kotlin:\npackage com.mycompany.myapp class HelloKotlin { fun hello() { System.out.println(\u0026quot;Hello from Kotlin\u0026quot;); } } After building this, I have a directory that contains \u0026ldquo;com/mycompany/myapp/HelloKotlin.class\u0026rdquo;.\nIt also produced a .jar file that contains this class.\nI have found that the easiest way to integrate external code into a Codename One project, is just to wrap it as a cn1lib file and place it into my Codename One project’s lib directory. That way I don’t have to mess with any of the build files. So, using roughly the same procedure as I used to create the kotlin-runtime.cn1lib, I wrap my hellokotlin.jar as a cn1lib to produce \u0026ldquo;hellokotlin.cn1lib\u0026rdquo; and copy it to the \u0026ldquo;lib\u0026rdquo; directory of a Codename One project.\n__ Remember to select \u0026ldquo;Codename One\u0026rdquo; → \u0026ldquo;Refresh CN1Libs\u0026rdquo; after placing the cn1lib in your lib directory or it won’t get picked up. Finally, I call my library from the start() method of my app:\nHelloKotlin hello = new HelloKotlin(); hello.hello(); If I run this in the Simulator, it should print \u0026ldquo;Hello from Kotlin\u0026rdquo; in the output console. If I get an error, then I dig in and try to figure out what went wrong using my standard debugging techniques. EXPECT an error on the first run. Hopefully it will just be a missing import or something simple.\nStep 4: A More Complex Hello World In the case of Kotlin, the hello world example app would actually run without the runtime library because it was so simple. So it was necessary to add a more complex example to prove the need for the runtime library. It doesn’t matter what you do with your more complex example, as long as it doesn’t require classes that aren’t in Codename One.\nIf you want to use the Codename One inside your project, you should add the CodenameOne.jar (found inside any Codename One project) to your classpath so that it will compile.\nStep 5: Automation and Integration At this point we already have a manual process for incorporating files built with our alternate language into a Codename One project. The process looks like:\nUse standard tools for your JVM language to write your code.\nUse the JVM language’s standard build tools (e.g. command-line compiler, etc..) to compile your code so that you have .class files (and optionally a .jar file).\nWrap your .class files in a cn1lib.\nAdd the cn1lib to the lib directory of a Codename One project.\nUse your library from the Codename One project.\nWhen I first developed Mirah support I just automated this process using an ANT script. I also automatically generated some bootstrap code so that I could develop the whole app in Mirah and I woudn’t have to write any Java. However, I soon found that this level of integration has limitations.\nFor example, with this approach alone, I couldn’t have two-way dependencies between Java source and Mirah source. Yes, my Mirah code could use Java libraries (and it did depend on CodenameOne.jar), and my Java code could use my Mirah code. However, my Mirah source code could not depend on the Java source code in my project. This has to do with the order in which code is compiled. It’s a bit of a chicken and egg issue. If we are building a project that has Java source code and Mirah source code, we are using two different compilers: mirahc to compile the Mirah files, and javac to compile the Java files. If we are starting from a clean build, and we run mirahc first, then the .java files haven’t yet been compiled to .class files – and thus mirahc can’t reference them – and any mirah code that depends on those uncompiled Java classes will fail. If we compile the .java files first, then we have the opposite problem.\nI worked around this problem in Mirah by writing my own pseudo-compiler that produced stub class files for the java source that would be referenced by mirahc when compiling the Mirah files. In this way I was able to have two-way dependencies between Java and Mirah in the same project.\nKotlin also supports two-way dependencies, probably using a similar mechanism.\nHow Seamless Can You Make It? For both the Kotlin and Mirah support, I wanted integration to be seamless. I didn’t want users to have to create a separate project for their Kotlin/Mirah code. I wanted them to simply add a Kotlin/Mirah file into their project and have it just work. Achieving this level of integration in Kotlin was quite easy, since they provide an ANT plugin that essentially allowed me to just add one tag inside my \u0026lt;javac/\u0026gt; tags:\n\u0026lt;withKotlin/\u0026gt; And it would automatically handle Kotlin and Java files together: Seamlessly. There are a few places in a Codename One’s build.xml file where we call \u0026ldquo;javac\u0026rdquo; so we just needed to inject these tags in those places. This injection is performed automatically by the Codename One IntelliJ plugin.\nFor Mirah, I developed my own ANT plugins and Netbeans module that do something similar in Netbeans.\nWhich Language Will Be Next? Hacking on JVM byte-code can actually be a lot of fun. If you are interested in adding support for a language, we’d love to know about it. Until then, happy coding! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nGareth Murfin — July 18, 2017 at 1:19 pm (permalink) Gareth Murfin says:\nIncredible work. So will the gui builder spit out kotlin too ? Also I think adding swift for iOS native dev would be awesome!..\nDon\u0026rsquo;t Bother — July 18, 2017 at 5:07 pm (permalink) Don\u0026rsquo;t Bother says:\nSwift is already a native language for iOS. So I don’t really understand what you are asking for. And I have not heard about ability to complie swift to java bytecode.\nshannah78 — July 18, 2017 at 6:35 pm (permalink) shannah78 says:\nNot sure about the maturity of this, but here’s one. https://github.com/brettwoo…. If someone wants to try to add swift support to Codename One, it might make for an interesting exercise.\nThis is not to be confused with using Swift to write native iOS code in a Codename one native interface. This is already possible (albiet a bit painful) by building a library separately using swift/xcode, and including the library in your ios/native lib – You only need to write a small amount of Objective-C to serve as the native interface itself.\nGareth Murfin — July 19, 2017 at 2:19 am (permalink) Gareth Murfin says:\nOh thats interesting is there any links for that? I I want to write more native libs but I want to use swift.\nShai Almog — July 19, 2017 at 5:08 am (permalink) Shai Almog says:\nThat’s a very different thing. The main blocker for this is integrating ARC with the GC. That should work in theory but doesn’t.\nAdi J — August 6, 2017 at 1:11 pm (permalink) Adi J says:\ncan I make app for tizen os along with android and ios by codename one.\nShai Almog — August 7, 2017 at 5:23 am (permalink) Shai Almog says:\nWe don’t natively support tizen but we do support JavaScript in the enterprise tier which should work on Tizen.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/how-to-port-jvm-languages-to-codename-one/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/how-to-port-jvm-languages-to-codename-one/kotlin_800x320.png\"\u003e\u003c/p\u003e\n\u003cp\u003eAs you may have already read, we have just added support for Kotlin in Codename One. In this post, I elaborate on some of the behind the scene work that was involved in bringing Kotlin to Codename One.\u003c/p\u003e\n\u003ch2 id=\"what-is-a-jvm-language\"\u003eWhat is a JVM Language?\u003c/h2\u003e\n\u003cp\u003eA JVM Language is any programming language that can be compiled to byte-codes that will run on the JVM (Java Virtual Machine). Java was the original JVM language, but many others have sprung up over the years. \u003ca href=\"https://kotlinlang.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eKotlin\u003c/a\u003e, \u003ca href=\"https://www.scala-lang.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eScala\u003c/a\u003e, \u003ca href=\"http://groovy-lang.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGroovy\u003c/a\u003e, and \u003ca href=\"http://jruby.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eJRuby\u003c/a\u003e come to mind as well-established and mature languages, but there are \u003ca href=\"https://en.wikipedia.org/wiki/List_of_JVM_languages\" target=\"_blank\" rel=\"noopener noreferrer\"\u003emany others\u003c/a\u003e.\u003c/p\u003e","title":"Tutorial: How to Add Support for other JVM Languages"},{"content":"\nI got a question the other day about a UI design for an upcoming Codename One app. In this UI the title floated on top of the content as the content scrolled past and tabs were a part of the title area in the style of material design.\nOur tabs component predated material design by many years and wasn’t designed for this sort of UI. When you scroll out of a tab it scrolls out. Using it for this sort of UI doesn’t make much sense. The solution was to use a custom title area with two toggle radio buttons representing each tab with a line below to indicate the selected button.\nThat’s pretty easy to do in Codename One, we can just style a toggle button with the right colors or border but the question is: \u0026ldquo;How do we animate the line motion\u0026rdquo;.\nWell…​ That’s actually really easy to accomplish once we decide the line isn’t a part of the button…​\nThis is a quick demo I made using maps and a floating toolbar and here is the annotated code:\npublic void init(Object context) { theme = UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;); // Enable Toolbar on all Forms by default __**(1)** //Toolbar.setGlobalToolbar(true); } public void start() { if(current != null){ current.show(); return; } Form m = new Form(\u0026quot;Map\u0026quot;, new BorderLayout()); Toolbar tb = new Toolbar(true); __**(2)** m.setToolbar(tb); m.add(BorderLayout.CENTER, new MapContainer(\u0026quot;... PLACE A KEY HERE ...\u0026quot;)); __**(3)** Label title = new Label(\u0026quot;Map\u0026quot;, \u0026quot;Title\u0026quot;); ButtonGroup bg = new ButtonGroup(); RadioButton modeA = RadioButton.createToggle(\u0026quot;Mode A\u0026quot;, bg); __**(4)** RadioButton modeB = RadioButton.createToggle(\u0026quot;Mode B\u0026quot;, bg); RadioButton modeC = RadioButton.createToggle(\u0026quot;Mode C\u0026quot;, bg); modeA.setUIID(\u0026quot;SmallTitle\u0026quot;); modeB.setUIID(\u0026quot;SmallTitle\u0026quot;); modeC.setUIID(\u0026quot;SmallTitle\u0026quot;); modeA.setSelected(true); Container radioGrid = GridLayout.encloseIn(3, modeA, modeB, modeC); Label whiteLine = new Label(); __**(5)** whiteLine.setShowEvenIfBlank(true); whiteLine.getUnselectedStyle().setBgColor(0xffffff); whiteLine.getUnselectedStyle().setBgTransparency(255); whiteLine.getUnselectedStyle().setPaddingUnit(Style.UNIT_TYPE_DIPS); whiteLine.getUnselectedStyle().setPadding(1, 0, 1, 1); Container lineGrid = GridLayout.encloseIn(3, whiteLine, new Label(), new Label()); __**(6)** bg.addActionListener(e -\u0026gt; { __**(7)** int offset = radioGrid.getComponentIndex(e.getComponent()); whiteLine.remove(); lineGrid.addComponent(offset, whiteLine); lineGrid.animateLayout(150); }); Container titleArea = BoxLayout.encloseY(title, radioGrid, lineGrid); __**(8)** tb.setTitleComponent(titleArea); m.show(); } __1 I commented out the toolbar as I will use an overlay toolbar on top of the map __2 When creating a toolbar instance with true, it \u0026ldquo;floats\u0026rdquo; on top of the UI notice the transparency to the underlying map __3 The API key is required if you want to use the JavaScript version __4 The radio toggle buttons are pretty standard, I styled them to look the same in all modes __5 I could have used the style to do the \u0026ldquo;white line\u0026rdquo; but chose to do it in code. It’s just a white background padding __6 Both the button and the white line are in 1×3 grids which means the elements will inherently have the same size __7 I listen on the button group and when a radio is selected I just move the white line to the selected radio offset. Then animate the layout __8 Box Y gives components the same width so the grids both get the same width and will thus match in size Check out the full code on github here: https://github.com/codenameone/MapAnimateTitle/\nLearn More It’s small things like that and attention to detail that can transform your app into a loved app. If you See similar effects or don’t fully understand why the code above works just ask in the comments!\nWe’re here to help you make great looking apps. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — July 18, 2017 at 12:00 am (permalink) bryan says:\nThat’s pretty clever. Very neat.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-animate-line-under-button/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-animate-line-under-button/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI got a question the other day about a UI design for an upcoming Codename One app. In this UI the title floated on top of the content as the content scrolled past and tabs were a part of the title area in the style of material design.\u003cbr\u003e\nOur tabs component predated material design by many years and wasn’t designed for this sort of UI. When you scroll out of a tab it scrolls out. Using it for this sort of UI doesn’t make much sense. The solution was to use a custom title area with two toggle radio buttons representing each tab with a line below to indicate the selected button.\u003c/p\u003e","title":"TIP: Animate Line Under Button"},{"content":"\nOur original How Do I video covering native interfaces was pretty old by now and needed a serious refresh. I created a new one that goes into a lot of the details although can’t go as deep as the subject matter is pretty huge to begin with.\nI see a lot of developers shy away from using native interfaces which is partially understandable. A big reason for picking Codename One is to avoid native. But this isn’t so bad or hard, if you get stuck implementing a native interface we are here to help you with that. Just ask us here, on stack overflow or in the discussion forum and we’ll help you with your issues.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-native-interfaces/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-native-interfaces/learn-codenameone-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOur original \u003ca href=\"/how-do-i.html\"\u003eHow Do I video\u003c/a\u003e covering native interfaces was pretty old by now and needed a serious refresh. I created a new one that goes into a lot of the details although can’t go as deep as the subject matter is pretty huge to begin with.\u003c/p\u003e\n\u003cp\u003eI see a lot of developers shy away from using native interfaces which is partially understandable. A big reason for picking Codename One is to avoid native. But this isn’t so bad or hard, if you get stuck implementing a native interface we are here to help you with that. Just ask us here, on stack overflow or in the discussion forum and we’ll help you with your issues.\u003c/p\u003e","title":"Tutorial – Native Interfaces"},{"content":"\nI’ve mentioned before that our biggest priority in 3.8 is refining the UI design of Codename One applications. This is a difficult task as it is so vague. There are so many small things we can do, when they are viewed in unison they seem approachable but as we start going thru the tasks priorities muddle. That’s why we need feedback from you guys on what bothers you about the UI and its refinement.\nBe specific, use screenshots, samples and references. Otherwise we can spend ages fixing things that don’t matter to any user out there or things that only matter to one user…​\nPixel Perfect To get this process moving I’d like to start a segment which ideally will run on a weekly basis. In this segment I’ll focus on refining one aspect of the UI completely. Besides the value this delivers to the UI itself as we’ll integrate those nuances into the code I think you would be able to gain insight into the way UI’s should be designed for the mobile platforms.\nI’ll focus on iOS flat design and Android material design as those are more understood and approachable.\nButtons Today I’ll cover a relatively simple component: Button.\nAs you will see there is a lot of nuance there…​\nAs they are Today The screenshots below are from the simulator but represent relatively closely the way buttons look on Android and iOS with Codename One applications.\nForm f = new Form(\u0026quot;Pixel Perfect\u0026quot;, BoxLayout.y()); Button b = new Button(\u0026quot;Button\u0026quot;); f.addComponent(b); f.show(); Figure 1. iOS Button Today\nFigure 2. Android Button Today\nAs they Should Be Material design specifies 3 types of buttons, one of them is a floating action button which we’ll discuss later but the other ones are:\nFigure 3. Material design raised button\nFigure 4. Material design flat button\niOS doesn’t have the plain button as much opting more for grouping but when it does it looks like this:\nFigure 5. iOS Button\nThere is also a round button which is used in grouping scenarios mostly. I don’t think it’s applicable in this scenario but I’m mentioning it here for completeness:\nFigure 6. Grouped iOS Button\nSo both iOS and Android use a \u0026ldquo;flat\u0026rdquo; button by default and we should align based on that. We also need to provide a way to show the Android raised button but that’s a special case that doesn’t exist in iOS.\nAction Items The theme for Android and iOS is current implemented within the resource files here: https://github.com/codenameone/CodenameOne/tree/master/Themes\nAndroid uses the holo theme whereas iOS uses the iOS 7 theme. We need to update these files with improved fonts and new designs. This might be a problem for developers who relied on the older theme behavior but these changes should be done to keep the platform moving forward.\nSo here are the things we need to change:\nText on buttons in Android should be capitalized but not on iOS\nFonts should be switched to millimeter native fonts instead of the current system fonts\nBackground color on iOS \u0026amp; Android is out of date. By default on Android it should be fafafa and on iOS it should be efeff4\nAndroid defaults to opaque components which is a bit inconsistent. They need to be transparent\nAndroid button needs to be flat and match the native look\nPressed \u0026amp; disabled states should match native design\nWe should have a ripple effect for Android buttons\nWe should add an Android specific raised button UIID\nA big advantage of switching to flat mode is in removing the image border images, this makes color customization much easier moving forward.\nCaps To solve this I added a new feature to Button called setCapsText(boolean) which has the corresponding isCapsText, isCapsTextDefault \u0026amp; setCapsTextDefault(boolean). This is pretty core to Codename One so to prevent this from impacting everything unless you explicitly invoke setCapsText(boolean) the default value of true will only apply when the UIID is Button or for the builtin Dialog buttons.\nI’ve also added the theme constant capsButtonTextBool to control this from the theme itself.\nI’ve made this change by overriding setText(String) and the constructor both of which aren’t performance critical. The alternative of overriding getText() or the paint logic might have been better but it would have an impact on performance.\nColors, Opacity \u0026amp; Fonts I’ve made a lot of changes to the fonts, transparency \u0026amp; colors in the Android and iOS themes. This means updating all the skin files and it might break some of your designs if you relied on some native theme behaviors.\nSince we plan to do a lot of changes like this there might be a lot of those disruptive changes but they are for a good cause!\nThis is what we have after the changes:\nFigure 7. Android Button after the change\nFigure 8. iOS Button after the change\nNotice that these are screenshots from the simulator and the fonts will look a bit different on the devices.\nComing Up We have several big and small things we need to refine and a couple of tasks mentioned above:\nRaised button UIID\nRipple effect\nRound corners on Android raised button and pressed color\nI hope I’ll be able to address at least some of these next week and this is where you come in…​\nIt’s not enough to complain about something missing or not functioning. We need issues but we also need \u0026ldquo;actionable\u0026rdquo; issues. Issues that we can look at and instantly see what needs fixing, e.g. if a button has the wrong default color, font or padding you can just provide a screenshot of a native app next to a screenshot from a simple Codename One application as part of the issue. This helps us make such fixes quickly.\nThe issue tracker is the best place for these things. We appreciate comments here and please do comment, but these things get lost. Once an issue is assigned to a milestone it might get postponed but it won’t be forgotten. So if you think Codename One can use a facelift, please help us pull that off! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nRoss Taylor — July 12, 2017 at 5:30 pm (permalink) Are you saying the priorities are not clear where CN1 should focus on when it comes to aligning CN1 UI with the UI guidelines of the respective OS? Its going to be tough because ideally I was hoping to rely on CN1 to have most of the guideline knowledge build-in and occasionally look at guidelines to verify things like spacings and so on.\nShai Almog — July 13, 2017 at 4:02 am (permalink) Native API’s don’t keep up with the guidelines at all times so that’s a bit more tricky.\nBy default your app won’t look very good if you use native SDK’s or Codename One. You need to pay attention to the design regardless of the platform.\nRoss Taylor — July 14, 2017 at 5:46 pm (permalink) So what you mean is one must be creating our own theme that conforms to design guidelines instead of relying on the default theme?\nShai Almog — July 15, 2017 at 8:08 am (permalink) What I’m saying is that design guidelines wouldn’t exist if there was a technical possibility to make them seamless. We currently bring you to a point of portability but we can bring you closer in terms of look (which is what this article is about).\nYou already have your own theme, I’m saying you should pay attention to design and not just expect it to \u0026ldquo;look good\u0026rdquo; without any conscious effort on your part.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/pixel-perfect-material-buttons/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/pixel-perfect-material-buttons/pixel-perfect.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve mentioned before that our biggest priority in 3.8 is refining the UI design of Codename One applications. This is a difficult task as it is so vague. There are so many small things we can do, when they are viewed in unison they seem approachable but as we start going thru the tasks priorities muddle. That’s why we need feedback from you guys on what bothers you about the UI and its refinement.\u003c/p\u003e","title":"Pixel Perfect – Material Buttons"},{"content":"\nWe were prepared for an uphill effort in terms of getting Kotlin up and running…​ Turns out that getting the basic support out of the door was much easier than expected with a few expected caveats that will hopefully be acceptable moving forward. Steve did pretty much all of the work on this, I asked him to write a post where he explains the challenges as this isn’t the first time he ported a JVM language to Codename One.\nI’ll try to cover the user experience of using Kotlin. But let’s start with the caveats:\nYou need to use IntelliJ/IDEA – I don’t think that’s a big sacrifice as it’s an excellent IDE with great Kotlin support. Doing this for other IDE’s would be a bit more challenging\nYou will need the latest 3.7.2 plugin we released the other day\nYou will need to install the Kotlin support libraries from the extension manager tool in Codename One Preferences\nDon’t use the project conversion tools or accept the warning that the project isn’t a Kotlin project. We do our own build process\nWarnings and errors aren’t listed correctly and a build that claimed to have 2 errors actually passed…​\nThis will increase your jar size by roughly 730kb which might make it harder for free tier users\nHaving said all that we got a couple of apps working on iOS, Android and on the web (using the JavaScript port) without a problem. This is still a beta thought so we might have missed some functionality.\nHello World Ideally as we will refine this we will have a Kotlin option within the new project wizard that will already include all of the necessary pieces. But for now you can take the following steps.\nOpen your Codename One project with the 3.7.2 plugin or newer.\nIn the right click menu select Codename One → Codename One Preferences.\nSelect Extensions type in kotlin and install. Then right click the project select Codename One → Refresh Libs.\nConversion The hello world Java source file looks like this (removed some comments and whitespace):\npublic class MyApplication { private Form current; private Resources theme; public void init(Object context) { theme = UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;); Toolbar.setGlobalToolbar(true); Log.bindCrashProtection(true); } public void start() { if(current != null){ current.show(); return; } Form hi = new Form(\u0026quot;Hi World\u0026quot;, BoxLayout.y()); hi.add(new Label(\u0026quot;Hi World\u0026quot;)); hi.show(); } public void stop() { current = getCurrentForm(); if(current instanceof Dialog) { ((Dialog)current).dispose(); current = getCurrentForm(); } } public void destroy() { } } When I select that file and select the menu option Code → Convert Java file to Kotlin File I get this:\nclass MyApplication { private var current: Form? = null private var theme: Resources? = null fun init(context: Any) { theme = UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;) Toolbar.setGlobalToolbar(true) Log.bindCrashProtection(true) } fun start() { if (current != null) { current!!.show() return } val hi = Form(\u0026quot;Hi World\u0026quot;, BoxLayout.y()) hi.add(Label(\u0026quot;Hi World\u0026quot;)) hi.show() } fun stop() { current = getCurrentForm() if (current is Dialog) { (current as Dialog).dispose() current = getCurrentForm() } } fun destroy() { } } That’s pretty familiar. The problem is that there are two bugs in the automatic conversion…​ That is the code for Kotlin behaves differently from standard Java.\nThe first problem is that Kotlin classes are final unless declared otherwise so we need to add the open keyword before the class declaration as such:\nopen class MyApplication This is essential as the build server will fail with weird errors related to instanceof so pay attention…​ We’ll try to make this fail on the simulator in the future.\nThe second problem is that arguments are non-null by default. The init method might have a null argument which isn’t used…​ So this fails with an exception. The solution is to add a question mark to the end of the call: fun init(context: Any?).\nSo the full working sample is:\nopen class MyApplication { private var current: Form? = null private var theme: Resources? = null fun init(context: Any?) { theme = UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;) Toolbar.setGlobalToolbar(true) Log.bindCrashProtection(true) } fun start() { if (current != null) { current!!.show() return } val hi = Form(\u0026quot;Hi World\u0026quot;, BoxLayout.y()) hi.add(Label(\u0026quot;Hi World\u0026quot;)) hi.show() } fun stop() { current = getCurrentForm() if (current is Dialog) { (current as Dialog).dispose() current = getCurrentForm() } } fun destroy() { } } Where do we go from Here? That’s up to you. Our GUI builder still works with Java files, we can probably get it to work with Kotlin files too and improve the wizard to include support for new Kotlin projects.\nWe can add support for NetBeans \u0026amp; Eclipse. We can work on adapting our documentation to include Kotlin samples everywhere, the sky is the limit…​\nWe can do lots of things but to do those we need feedback and traction. Feedback helps us know what’s important to you, the people who use our product. Traction brings in new users and helps us promote what we are doing. If you care about this, let your friends know. They might ask for further Kotlin features and we’ll increase our investment in Kotlin. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nTom Tantisalidchai — July 11, 2017 at 12:14 pm (permalink) Tom Tantisalidchai says:\nThanks for the awesome work! It’d be great if we can easily use Kotlin’s coroutines library from https://github.com/Kotlin/k…\nsalah Alhaddabi — July 11, 2017 at 5:46 pm (permalink) salah Alhaddabi says:\nDoes this mean you will no longer support java and use kotlin instead??? This would be a pity as Java was the main reason i am using CN1…..\nshannah78 — July 11, 2017 at 5:54 pm (permalink) shannah78 says:\nNo. We still support, Java. I’m fairly confident that we will always support Java as, like you said, that is the main reason why many developers are using CN1 in the first place. Adding support for Kotlin just provides the option of using Kotlin in your projects as well.\nShai Almog — July 12, 2017 at 5:07 am (permalink) Shai Almog says:\nThanks for the feedback. I’m pretty sure this can be ported to a cn1lib although I’m not sure how well cn1libs work with Kotlin. Steve?\nshannah78 — July 12, 2017 at 6:06 pm (permalink) shannah78 says:\ncn1libs will work fine with Kotlin.\nI have taken a quick look at this library though and there are a few red flags that may limit its usefulness. For example, the async/yield stuff it appears to have special providers for JavaFX and Swing. Really that portion is just doing the same thing as invokeAndBlock, which CN1 has had for years (since the beginning), so I question the value of that portion of the library in the CN1 context.\nAlbert Gao — October 8, 2017 at 9:12 pm (permalink) Albert Gao says:\nGreat news! The Kotlin is the reason we are currently evaluating the codenameOne as a cross platform solution. Although I have a little program on how to consume the lib that are written in Kotlin, any help would be great. I use this repo and it works: https://github.com/shannah/… , but don’t know how to add another kotlin lib like kotlin coroutine and kotlin reflection. Any help would be thankful.\nShai Almog — October 9, 2017 at 4:38 am (permalink) Shai Almog says:\nI think you should be able to wrap them as cn1libs\nThomas — March 2, 2018 at 3:04 am (permalink) Thomas says:\nIs the kotlin api fully supported or is it just a subset of its classes like for java (for example can I import io.socket.client.Socket in a kotlin class in codenameone and this would work out of the box? or like for java.io some kotlin class aren’t supported?)\nAlso, is it possible to mix some kotlin files with some java ones in the same codenameone project?\nShai Almog — March 2, 2018 at 4:52 am (permalink) Shai Almog says:\nYou can mix Java \u0026amp; Kotlin files like any other project.\nNo you can’t access the full Java SE API, you have almost the same restrictions as the Java version has. Notice that projects like Kotlin Native have even worse restrictions…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/kotlin-support-public-beta/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/kotlin-support-public-beta/kotlin_800x320.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe were prepared for an uphill effort in terms of getting Kotlin up and running…​ Turns out that getting the basic support out of the door was much easier than expected with a few expected caveats that will hopefully be acceptable moving forward. Steve did pretty much all of the work on this, I asked him to write a post where he explains the challenges as this isn’t the first time he ported a JVM language to Codename One.\u003c/p\u003e","title":"Kotlin Support Public Beta"},{"content":"\nOn occasion I answer a question on stackoverflow, the discussion forum or elsewhere and I get a response of the form of: \u0026ldquo;this wasn’t clear from the docs\u0026rdquo;. We improved the docs but befitting a huge project run by engineers without a technical writer in sight this is a bit of a problem…​ The thing is that this is a problem you can fix regardless of your level in engineering or in English.\nThe benefits are pretty cool:\nYou have a pull request in your name\nDocumenting stuff helps understand the nuance and makes you a better programmer\nWe would really appreciate it\nThat’s a lot for something that’s so trivial to accomplish!\nFixing the JavaDocs Fixing the JavaDoc for a class couldn’t be easier. You need a github account (which is free) you can then go to https://github.com/codenameone/CodenameOne and type in the search bar the name of the file you want to fix in the javadoc e.g. if you want to improve the JavaDoc for component just type: filename:Component.java\nInclude the filename: prefix for a quicker find…​\nYou should see something like this:\nFigure 1. List of component classes the first one is what we are looking for\nWhen we enter we first must select the master branch in the combo box then we can press the edit button on the top right:\nFigure 2. The combo box to select the master branch and edit button for the source file\nYou’ll get a couple of standard notices:\nFigure 3. Standard notices\nFind the method whose JavaDoc you want to edit and just edit it. Once you do that scroll all the way down and enter a description in the propose file change box and submit it:\nFigure 4. The propose change box, make sure to describe your change briefly\nOnce you click propose change you can make it into a pull request and thus submit it to us. This takes two clicks on green buttons and literally nothing more.\nFigure 5. First stage of pull request you are prompted with the diff of the change you made\nFigure 6. Second stage of pull request you can edit the submit comment\nWe usually accept simple pull requests pretty quickly. Please feel free to submit. Once you go thru that process it becomes trivial and helps you dive deeper into the code.\nYou can see the pull request I did for the screenshots above here: https://github.com/codenameone/CodenameOne/pull/2153\nEdit the Developer Guide This is actually easier. You can just open the developer guide and edit it without a pull request as it’s hosted in our project wiki!\nYou can open it here or by clicking the wiki tab in the Codename One github project. The edit button on the top right allows you to edit the document instantly and save it directly to the project.\nThe one hurdle is that the guide is written using asciidoc which is a simple language but if you aren’t familiar with it then it might take a couple of minutes to understand. You can just follow the conventions in other parts of the guide to get started. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — August 19, 2017 at 7:37 pm (permalink) Thank you Shai.\nAre the wiki modifications by users automatically converted to the manual pages in the Codename One site without any check by the Codename One team?\nI’ve seen few errors and several incompleteness in the manual and in the API about the code examples, I’ll try to contribute the next time that I’ll find something strange.\nOf course, I’m only an user of Codename One and I’m studying it, so at the moment I feel better to tell a problem in the \u0026ldquo;Issues page\u0026rdquo; of GitHub than to try to do changes by myself.\nShai Almog — August 20, 2017 at 4:58 am (permalink) No. We monitor the edits and review every change. Then when we choose we sync it to the site.\nFeel free to edit or clarify, worst case scenario we’ll fix mistakes or omissions.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-edit-docs-fun-profit/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-edit-docs-fun-profit/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOn occasion I answer a question on stackoverflow, the discussion forum or elsewhere and I get a response of the form of: \u0026ldquo;this wasn’t clear from the docs\u0026rdquo;. We improved the docs but befitting a huge project run by engineers without a technical writer in sight this is a bit of a problem…​ The thing is that this is a problem you can fix regardless of your level in engineering or in English.\u003c/p\u003e","title":"TIP: Edit the Docs for Fun and Profit"},{"content":"\nPush gets a lot of support queries, it’s a hard subject to wrap your head around especially with all of the conflicting and shifting landscape around it. To make matters worse every OS conceptualizes it very differently. I go into some of the really advanced stuff such as fallback behavior in the advanced course but basic stuff is still a crucial first step.\nSo I adapted some of the material from there and re-did the push How Do I? video to use the newer API’s and settings. Check out that page for the full transcript of the video.\nNotice that push is a pretty big subject and I couldn’t cover everything in a 15 minute video so I didn’t discuss other platforms such as Windows and JavaScript (both of which are supported). I didn’t discuss parsing the JSON results from our servers and handling them even though there is a lot of nuance there. It’s just too much to discuss and JSON parsing in JavaSE isn’t something I’d like to discuss right now.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-using-push-notification/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-using-push-notification/learn-codenameone-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003ePush gets a lot of support queries, it’s a hard subject to wrap your head around especially with all of the conflicting and shifting landscape around it. To make matters worse every OS conceptualizes it very differently. I go into some of the really advanced stuff such as fallback behavior in the \u003ca href=\"https://codenameone.teachable.com/p/build-real-world-full-stack-mobile-apps-in-java\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eadvanced course\u003c/a\u003e but basic stuff is still a crucial first step.\u003c/p\u003e\n\u003cp\u003eSo I adapted some of the material from there and re-did the push \u003ca href=\"/how-do-i---use-push-notification-send-server-push-messages.html\"\u003eHow Do I? video\u003c/a\u003e to use the newer API’s and settings. Check out that page for the full transcript of the video.\u003c/p\u003e","title":"Tutorial – Using Push Notification"},{"content":"\nWhen discussing the features Chen slipped in just in the last minute of 3.7 I mentioned there were two such features but only discussed the desktop skin. The second one is a more terse/logical API for calling REST web services using the builder pattern.\nI actually discussed this briefly in the how do i video for networking \u0026amp; web services near the end. But that’s one of those details that might have easily been missed in that video…​\nEasy Approach to Rest The important class of note is Rest. You can use it to define the HTTP method and start building based on that. So if I want to get a parsed JSON result from a URL I could do:\nResponse\u0026lt;Map\u0026gt; jsonData = Rest.get(myUrl).getAsJsonMap(); For a lot of REST requests this will fail because we need to add an HTTP header indicating that we accept JSON results. We have a special case support for that:\nResponse\u0026lt;Map\u0026gt; jsonData = Rest.get(myUrl).acceptJson().getAsJsonMap(); We can also do POST requests just as easily:\nResponse\u0026lt;Map\u0026gt; jsonData = Rest.post(myUrl).body(bodyValueAsString).getAsJsonMap(); Notice the usage of post and the body builder method. There are MANY methods in the builder class that cover pretty much everything you would expect and then some when it comes to the needs of rest services.\nI changed the code in the kitchen sink webservice sample to use this API. I was able to make it shorter and more readable without sacrificing anything.\nFuture There is a lot of additional work that we can put into this API and we’ll invest the time based on interest from you. It has an async API too which I didn’t mention because I think it needs some additional work and there are probably good ways to better map this into properties to make the code more fluent and easy. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nsalah Alhaddabi — July 6, 2017 at 9:24 pm (permalink) salah Alhaddabi says:\nThanks a lot Shi. This is a big help for today’s mobile businesses.\nTim Gallagher — July 24, 2017 at 8:08 pm (permalink) Tim Gallagher says:\nJust in time for me. Is this included in the the base library or do I need to install one of the extensions?\nShai Almog — July 25, 2017 at 4:35 am (permalink) Shai Almog says:\nIt’s in the library just import\nTim Gallagher — July 27, 2017 at 6:30 pm (permalink) Tim Gallagher says:\nOK – I’ve looked through the REST api, and found that I need more control. I have to use Basic Authorization to log into a web service, which then supplies a token in the response header, but not a cookie, and at the same time some JSON with details of the login. Then I have to use that token on subsequent requests. I’ve looked at the ConnectionRequest class, which seems to be the best option for me, adding header params and overriding buildRequestBody() (based on these two SO items: https://stackoverflow.com/q… and https://stackoverflow.com/q…) but I’m not sure which method, if any, I can override in order to get the header information, the token, in the response. What do you suggest?\nShai Almog — July 28, 2017 at 5:24 am (permalink) Shai Almog says:\nIn ConnectionRequest readHeaders() can be overridden to read the headers. I lost you a bit on the token.\nThe new REST API should have methods to process response headers and cookies. Can you please file RFE’s to add those?\nThanks.\nThomas — March 20, 2018 at 12:35 am (permalink) Thomas says:\nThis is nothing but the Rest object is currently missing the .patch(url) method. Would be nice if it could be add in the next release (Furthermore that the RequestBuilder(method, url) constructor is not public so you have to extend it if you want to create a custom one to handle the PATCH method for now….)\nNOTE: the PATCH method act as a post or put, so, aditionnaly to define it in the Rest object, in the createRequest() method of RequestBuilder you also need to change\nreq.setPost(method.equalsIgnoreCase(\u0026ldquo;POST\u0026rdquo;) || method.equalsIgnoreCase(\u0026ldquo;PUT\u0026rdquo;));\nto\nreq.setPost(method.equalsIgnoreCase(\u0026ldquo;POST\u0026rdquo;) || method.equalsIgnoreCase(\u0026ldquo;PUT\u0026rdquo;) || method.equalsIgnoreCase(\u0026ldquo;PATCH\u0026rdquo;));\nto handle it correctly\nShai Almog — March 20, 2018 at 6:00 am (permalink) Shai Almog says:\nThanks, can you file an issue?\nTafadzwa Moyo — April 17, 2018 at 5:36 am (permalink) Tafadzwa Moyo says:\ndoes it work for https too?\nShai Almog — April 18, 2018 at 5:19 am (permalink) Shai Almog says:\nSure.\nFrancesco Galgani — May 6, 2018 at 8:21 pm (permalink) Francesco Galgani says:\nIn this post, you wrote:\nMap\u0026lt;string, object=\u0026quot;\u0026quot;\u0026gt; jsonData = Rest.get(myUrl).getAsJsonMap(); but getAsJsonMap() returns a Response.\nI suppose that you mean:\nResponse jsonData = Rest.get(myUrl).acceptJson().getAsJsonMap();\nif (jsonData.getResponseCode() == 200) {\nMap\u0026lt;string, object=\u0026quot;\u0026quot;\u0026gt; response = jsonData.getResponseData();\n}\nFrancesco Galgani — May 6, 2018 at 8:22 pm (permalink) Francesco Galgani says:\nDisquis changed the code in my comment…\nShai Almog — May 7, 2018 at 4:16 am (permalink) Shai Almog says:\nThanks, I’ll fix that in the next site update\nMax Amende — January 8, 2019 at 2:31 pm (permalink) Max Amende says:\nHi,\nI have a problem and I can not find the solution. I use:\nResponse\u0026lt;map\u0026gt; jsonData = Rest.get(myUrl).acceptJson().getAsJsonMap();\nto get Data from a firestore database.\nThe query works and codename one should get:\n{ \u0026quot;name\u0026quot;: \u0026quot;\u0026quot;, \u0026quot;fields\u0026quot;: { \u0026quot;1\u0026quot;: { \u0026quot;stringValue\u0026quot;: \u0026quot;Test One\u0026quot; }, \u0026quot;2\u0026quot;: { \u0026quot;stringValue\u0026quot;: \u0026quot;Test Two\u0026quot; }, \u0026quot;3\u0026quot;: { \u0026quot;stringValue\u0026quot;: \u0026quot;Test Three\u0026quot; }, \u0026quot;4\u0026quot;: { \u0026quot;integerValue\u0026quot;: \u0026quot;1234\u0026quot; } }, \u0026quot;createTime\u0026quot;: \u0026quot;2019-01-07T21:10:00.621697Z\u0026quot;, \u0026quot;updateTime\u0026quot;: \u0026quot;2019-01-08T13:09:05.737437Z\u0026quot; }\nBut no matter how it try it I can not get the vales out of it.\nI thought I should get the value with:\njsonData.getResponseData().get(\u0026quot;1\u0026quot;); @codenameone:disqus Do you know where my thinking error is?\nShai Almog — January 9, 2019 at 3:36 am (permalink) Shai Almog says:\nShouldn’t it be:\nString value = (String)((Map)jsonData.getResponseData().get(\u0026ldquo;1\u0026rdquo;)).get(\u0026ldquo;stringValue\u0026rdquo;);\nNotice you can inspect the returned Map in the debugger…\nMax Amende — January 9, 2019 at 5:35 pm (permalink) Max Amende says:\nFound the mistake.\nThanks a lot for your help.\nSorry\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/terse-rest-api/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/terse-rest-api/new-features-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen discussing the features Chen slipped in just in the last minute of 3.7 I mentioned there were two such features but only discussed the \u003ca href=\"/blog/desktop-skin.html\"\u003edesktop skin\u003c/a\u003e. The second one is a more terse/logical API for calling REST web services using the builder pattern.\u003c/p\u003e\n\u003cp\u003eI actually discussed this briefly in the \u003ca href=\"/how-do-i/how-do-i-use-http-sockets-webservices-websockets/\"\u003ehow do i video for networking \u0026amp; web services\u003c/a\u003e near the end. But that’s one of those details that might have easily been missed in that video…​\u003c/p\u003e","title":"Terse REST API"},{"content":"\nDuring the final stages of the 3.7 release cycle we had a lot of material to go thru and Chen slipped a couple of features that we just didn’t have the time to discuss. One of those features is the new desktop skin which is a special case skin to debug desktop and JavaScript apps.\nUnlike other skins it doesn’t scale, it resizes the UI when you resize it. It has no skin decorations except for a small bar at the bottom that indicates the current resolution. You can use this to simulate resizing from the user.\nFigure 1. Activate the desktop skin thru the skins menu\nFigure 2. The desktop skin running the kitchen sink demo\nDesktop Features We’ve been moving slowly to improve Codename Ones desktop support. Our own tools are already mostly written using Codename One (GUI builder, Settings).\nWe already feel that using Codename One in a desktop setting can produce a decent result in the right hands and we know a few people do exactly that. However, it’s hard for us to gauge expectations and desires from customers without feedback. When we build our own apps we use a lot of tricks we never bother to publish as our use cases are usually edge cases.\nIf you are looking to build desktop and web apps using Codename One let us know and we can discuss features that would make it better suited for those use cases. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nCarlos — July 4, 2017 at 6:53 pm (permalink) Good move.\nIs it possible to programmatically set the size of the window at startup? That is something that I’m missing.\nShai Almog — July 5, 2017 at 4:10 am (permalink) Thanks.\nNot at this time, we have the desktop.width and desktop.height build hints but not programmatically.\nYou can use a native interface and just fine the JFrame then resize that using Swing code.\nGareth Murfin — February 14, 2018 at 9:03 am (permalink) Gareth Murfin says:\nI love the desktop skin, it would definitely be great if when you resized it then remembered the size for next time, this skin makes the emulator very usable I think, and would be far cooler if it would remember resize too.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/desktop-skin/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/desktop-skin/new-features-4.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eDuring the final stages of the 3.7 release cycle we had a lot of material to go thru and Chen slipped a couple of features that we just didn’t have the time to discuss. One of those features is the new desktop skin which is a special case skin to debug desktop and JavaScript apps.\u003c/p\u003e\n\u003cp\u003eUnlike other skins it doesn’t scale, it resizes the UI when you resize it. It has no skin decorations except for a small bar at the bottom that indicates the current resolution. You can use this to simulate resizing from the user.\u003c/p\u003e","title":"Desktop Skin"},{"content":"\nI wrote in the past about importing a Codename One demo from github but I left the whole working with git as an open subject. Mostly because I considered it a bit out of scope for the discussion. I have a section in the free online course about the anatomy of a Codename One application which I completely forgot to upload until I wrote this!\nIf you want to understand more, I strongly suggest watching that as it explains a lot of the \u0026ldquo;why\u0026rdquo; and \u0026ldquo;how\u0026rdquo; logic of Codename One project structures. It explains the purpose of every file you see in the project…​\nThe Right Gitignore We spent yesterday migrating our internal SVN repository (yes we still used SVN internally) to git. The reason we didn’t do it before was historic. We have a 15gb repository for Codename One that includes a lot of history and junk. Git doesn’t work well with large repositories and splitting up the whole thing effectively means discarding history.\nWe made some attempts at migrating in the past but the scripts would generally fail after 2-3 days of continuous work…​ So we split up the repositories to smaller ones and made a clean break. While doing that we wrote a lot of gitignore files and this made me think a bit about the whole thing. I think there is a lot of nuance in setting up the right gitignore file and there are a few interesting tradeoffs we should consider.\nWhen we first started committing to git we used something like this for netbeans projects:\n*.jar nbproject/private/ build/ dist/ lib/CodenameOne_SRC.zip Removing the jars, build, private folder etc. makes a lot of sense but there are a few nuances that are missing here…​\ncn1lib’s You will notice we excluded the jars which are stored under lib and we exclude the Codename One source zip. But I didn’t exclude cn1libs…​ That was an omission since the original project we committed didn’t have cn1libs. But should we commit a binary file to git?\nI don’t know. Generally git isn’t very good with binaries but cn1libs make sense. In another project that did have a cn1lib I did this:\n*.jar nbproject/private/ build/ dist/ lib/CodenameOne_SRC.zip lib/impl/ native/internal_tmp/ The important lines are lib/impl/ and native/internal_tmp/. Technically cn1libs are just zips. When you do a refresh libs they unzip into the right directories under lib/impl and native/internal_tmp. By excluding these directories we can remove duplicates that can result in conflicts.\nI’m not sure if committing the cn1libs is a good choice. It’s something i’m still conflicted about.\nResource Files I’m generally in favor of committing the res file and it’s committed in the git ignore files above. The res file is at risk of corruption and in that case having a history we can refer to matters a lot.\nBut the resource file is a bit of a problematic file. As a binary file if we have a team working with it the conflicts can be a major blocker. This was far worse with the old GUI builder, that was one of the big motivations of moving into the new GUI builder which works better for teams.\nStill, if you want to keep an eye of every change in the resource file you can switch on the File → XML Team Mode which should be on by default. This mode creates a file hierarchy under the res directory to match the res file you opened. E.g. if you have a file named src/theme.res it will create a matching res/theme.xml and also nest all the images and resources you use in the res directory.\nThat’s very useful as you can edit the files directly and keep track of every file in git. However, this has two big drawbacks:\nIt’s flaky – while this mode works it never reached the stability of the regular res file mode\nIt conflicts – the simulator/device are oblivious to this mode. So if you fetch an update you also need to update the res file and you might still have conflicts related to that file\nUltimately both of these issues shouldn’t be a deal breaker. Even though this mode is a bit flaky it’s better than the alternative as you can literally \u0026ldquo;see\u0026rdquo; the content of the resource file. You can easily revert and reapply your changes to the res file when merging from git, it’s tedious but again not a deal breaker.\nEclipse Version Building on the gitignore we have for NetBeans the eclipse version should look like this:\n.DS_Store *.jar build/ dist/ lib/impl/ native/internal_tmp/ .metadata bin/ tmp/ *.tmp *.bak *.swp *.zip *~.nib local.properties .settings/ .loadpath .recommenders .externalToolBuilders/ *.launch *.pydevproject .cproject .factorypath .buildpath .project .classpath IntelliJ/IDEA .DS_Store *.jar build/ dist/ lib/impl/ native/internal_tmp/ *.zip .idea/**/workspace.xml .idea/**/tasks.xml .idea/dictionaries .idea/**/dataSources/ .idea/**/dataSources.ids .idea/**/dataSources.xml .idea/**/dataSources.local.xml .idea/**/sqlDataSources.xml .idea/**/dynamic.xml .idea/**/uiDesigner.xml .idea/**/gradle.xml .idea/**/libraries *.iws /out/ atlassian-ide-plugin.xml Finally This is by no means the final version of this. These sort of files tend to change over time as more functionality (e.g. Kotlin support) makes its way into Codename One or the respective IDE’s. This can also be impacted by your OS or IDE plugin. Notice I excluded .DS_Store which is a file Mac OS sometimes creates but I didn’t exclude Thumbs.db because I don’t use Windows as much. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMartin Grajcar — November 4, 2018 at 3:11 pm (permalink) Martin Grajcar says:\nMy project build just failed in \u0026lt;copy todir=\u0026quot;bin\u0026quot;\u0026gt;\u0026lt;fileset dir=\u0026quot;override\u0026quot;/\u0026gt;\u0026lt;/copy\u0026gt; because of the missing override directory. This was my fault as I deleted all empty directories, but git doesn’t track them, so build of a cloned project will fail for the very same reason.\nShai Almog — November 5, 2018 at 5:26 am (permalink) Shai Almog says:\nIs it possible your build.xml is out of date?\nbuild.xml should implicitly create that directory if it’s missing when you send a build and when you run if you use netbeans.\nMartin Grajcar — November 5, 2018 at 3:19 pm (permalink) Martin Grajcar says:\nIt may be out of date, but at most by a week as on Oct 29, I created a new project. I edited it manually, because of https://www.codenameone.com….\nThere are many \u0026lt;mkdir dir=\u0026quot;override\u0026quot;/\u0026gt; there, but there’s none before the copy in the jar target. So I added it now.\nI’m using Eclipse. I wonder, how to get updates to build.xml, in case you do some important changes in the future (overwriting my edited file is no problem because of git).\nShai Almog — November 6, 2018 at 6:55 am (permalink) Shai Almog says:\nbuild.xml is embedded in Codename One Settings so when you save changes there it offers to override your current version. Please file an issue on this and we’ll try to add that mkdir before that as well.\nThomasH99 — September 19, 2021 at 2:30 pm (permalink) ThomasH99 says:\nHi, is this approach is still the right way to use Git for CN1 projects using maven? (I’m no expert on either so maybe this is a basic question 🙂\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-using-git-for-codename-one-projects/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-using-git-for-codename-one-projects/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI wrote in the past about \u003ca href=\"/blog/tip-setup-codename-one-demo-from-git.html\"\u003eimporting a Codename One demo from github\u003c/a\u003e but I left the whole working with git as an open subject. Mostly because I considered it a bit out of scope for the discussion. I have a section in the free online course about the \u003ca href=\"https://codenameone.teachable.com/courses/java-for-mobile-devices-introducing-codename-one/lectures/2925056\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eanatomy of a Codename One application\u003c/a\u003e which I completely forgot to upload until I wrote this!\u003c/p\u003e\n\u003cp\u003eIf you want to understand more, I strongly suggest watching that as it explains a lot of the \u0026ldquo;why\u0026rdquo; and \u0026ldquo;how\u0026rdquo; logic of Codename One project structures. It explains the purpose of every file you see in the project…​\u003c/p\u003e","title":"TIP: Using Git for Codename One Projects"},{"content":"\nIt’s been a hectic month getting the academy up and orchestrating the release. I have a mixed bag of updates and announcements we need to make. Specifically covering the surveys for the next academy app, the Kotlin survey, the coming update to 3.7.2 and future milestones.\nKotlin As you recall I published a Kotlin survey a while back and we didn’t publish the results. Some of the result were a bit surprising…​ Lets review some of the answers.\nFigure 1. How do you use Kotlin today?\nMost of the people who responded used Kotlin to some degree which is very good and indicates they have a sense of what to expect.\nFigure 2. Do you build Android applications with Kotlin?\nSo 58% said they use Kotlin today in some form but only 37.9% use it for Android?\nMy first thought was that it’s Codename One fans who use Kotlin on the server and there were those but not much. I’m not sure.\nFigure 3. Do You Use GUI Builders?\nThis number is a bit larger than I expected. I would have expected fewer people to use GUI builders but I guess that’s just me.\nFigure 4. Should the Codename One GUI builder generate Kotlin code instead of Java?\nI expected this to be easy, I would have expected overwhelmingly that people wouldn’t care. Maybe I should have opened with the disclaimer that it will divert work from other things…​\nI don’t care much about the GUI builder language/code. I’m not sure how much Kotlin will benefit from that if we generate code in Kotlin instead of Java. Maybe I phrased the question badly…​\nWhat’s next for Kotlin I’m not sure if we’ll do the whole Kotlin code in the GUI builder. It shouldn’t impact development as you can still write Kotlin code everywhere but a GUI builder form will probably a java form for now. I’d like to push something out relatively quickly rather than spend time on things like the GUI builder support.\nI’m not sure when this will be out as we have a lot on our plate for 3.8.\nWhatsapp vs. Social App Continuing with the trend of surveys you have all helped tremendously with the decision to go with an Uber clone as the first app built for the new course.\nAs I mentioned before the results for the second place were ambiguous and within the margin of error. They favored the social app which went against my personal intuition…​ Turns out my intuition got it wrong…​\nFigure 5. Survey results for whatsapp vs. social app\nWhich means our second app developed in the course will be a social app.\nIt doesn’t mean the third app will be a whatsapp clone…​\nI’ll do a new survey when we reach that point as a lot can change by then and we might have additional app suggestions.\nUpdate 3.7.2 We already have some changes and bug fixes for the GUI builder lined up. We didn’t include them in 3.7.1 which just included critical code fixes.\nWe won’t release an update this Friday because we still have some things we’d like to finish but the week after that we’ll push out a new update both to the library and the plugin.\nSummer Time \u0026amp; Course Updates Next week Steve will be on a much deserved vacation and during the month of August some of us (myself included) have more spotty schedules due to the summer vacation. During August we might skip a Friday update in August if there aren’t any significant changes to the libraries.\nBlog posts probably won’t have the same volume during August either.\nFuture Milestones – 3.9 and beyond One of the things we didn’t mention in the release is the dates of the releases after 3.8.\nWe decided to move all of that into the github project where it’s easier to manage everything in one place. Check out the milestones section. We listed all the dates of the milestones for 2018 although these can change in some situations but we’ll try to abide by them as 3 releases per year is pretty good.\nAcademy I’ve posted some additional modules covering things such as push, websockets etc. since publishing the academy but haven’t kept the same pace as before. I still have a lot of material that needs publishing just to get to the starting line.\nI’m working hard on finishing this and would hopefully have more time to do this during July\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/survey-results-kotlin-updates-news/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/survey-results-kotlin-updates-news/codenameone-academy.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIt’s been a hectic month getting the academy up and orchestrating the release. I have a mixed bag of updates and announcements we need to make. Specifically covering the surveys for the next academy app, the \u003ca href=\"/blog/kotlin-wora-ios-iphone-windows-android.html\"\u003eKotlin survey\u003c/a\u003e, the coming update to 3.7.2 and future milestones.\u003c/p\u003e\n\u003ch3 id=\"kotlin\"\u003eKotlin\u003c/h3\u003e\n\u003cp\u003eAs you recall I published a Kotlin survey a while back and we didn’t publish the results. Some of the result were a bit surprising…​ Lets review some of the answers.\u003c/p\u003e","title":"Survey Results, Kotlin, Updates and News"},{"content":"\nWith version 3.7, we have revamped the GUI builder with a designer that allows you to position your elements precisely where you want them. The experience should be closer to what you find in graphical design applications like Photoshop rather than the more rigid \u0026ldquo;drop in the slot\u0026rdquo; approach in previous versions of the GUI builder. There are caveats to be aware of with this approach, but overall, it should empower you to build beautiful UIs with greater ease than before.\nIn this blog post I will be focusing on the low-level details of \u0026ldquo;how it works\u0026rdquo; so that you can understand how to best tune it to your liking. We will be producing additional demos, posts, and documentation that cover these changes from a higher-level perspective.\nBackground If you’ve used Codename One at all, you’re likely aware of its heavy usage of layout managers for positioning components on the screen. You don’t just place a button on the screen at a particular size and position. You would, instead, add the button to a container and have the container’s layout manager calculate the correct position for the button. If you wanted your components to be laid out across the screen and then wrap when it runs out of room, you would use FlowLayout. If you wanted to tile your buttons in a grid, you might use GridLayout. If you want to layout the buttons vertically down the page you would use a box layout Y. Etc.. In general, it is possible to reproduce any design from a PSD file by nesting components with the classical layout managers.\nWhy Can’t We Just Place A Component at some (x,y) Coordinate? Shai has written about this many times in the past. The long and short of it is that when your app is shown on a screen with different resolution or dimensions, the app may need to reposition the element. You need a layout manager that is able to dynamically calculate the appropriate position for your components based on the current state.\nUnfortunately, this explanation provides little consolation to new users who just want to drag a button onto the form where they want it, and run their app. To expect new users to understand layout managers before they can build their \u0026ldquo;Hello World\u0026rdquo; app is, perhaps, a little demanding.\nOne key goal for this iteration of the designer was to make it more accessible to new users. I want a user to be able to drag labels, buttons, text fields, etc.. from the palette onto the form and position them freely, exactly how they like. I didn’t want them to have to worry about layout managers and the like. Just drag widgets around, and then run the app.\nBut Didn’t I Just Say that Absolute Positioning isn’t Practical? Indeed absolute positioning in a mobile application is not practical. Our solution is \u0026ldquo;relative\u0026rdquo; positioning. We have beefed up the layered layout manager to support insets and inter-component references, and we have added the ability to manipulate the layout using familiar drag-and-drop GUI designer controls.\nFor example, if you drag a button down to the bottom corner of the form, the designer doesn’t save the absolute X,Y coordinate for the button. If saves the insets (distance) from that bottom corner. That way, at runtime, the button will always be rendered appropriately in the bottom corner no matter what the device dimensions are.\nGoing a step further, if you then drag a text field just to the left of the button, the designer will record the text field’s insets relative to the button so that it will lay out properly still even as the device is resized.\n__ The designer only automatically links the text field’s position to the button if \u0026ldquo;Smart Insets\u0026rdquo; is enabled. With \u0026ldquo;Smart Insets\u0026rdquo; disabled, you would need to link it explicitly. The example with only two components may seem contrived, but we have worked hard to ensure that it can scale to arbitrary UI complexity with dozens of components positioned exactly the way you want.\nUnder the Hood Before we go into the designer’s UI, let’s take a moment to look at the new and improved Layered Layout manager, upon which all of this goodness rests.\nPre-3.7, LayeredLayout simply laid out containers on top of each other in layers. It didn’t allow you to position the child components, except via margins and padding.\nIn this release, we have kept the default behaviour the same, but have added support for constraints that add insets to child components. Here is a simple example that adds a button to the bottom, right corner of a container.\nContainer cnt = new Container(new LayeredLayout()); Button btn = new Button(\u0026quot;Submit\u0026quot;); LayeredLayout ll = (LayeredLayout)cnt.getLayout(); cnt.add(btn); ll.setInsets(btn, \u0026quot;auto 0 0 auto\u0026quot;); The result is:\nThe only thing new here is this line:\nll.setInsets(btn, \u0026quot;auto 0 0 auto\u0026quot;); This is called after btn has already been added to the container. It says that we want its insets to be \u0026ldquo;auto\u0026rdquo; on the top and left, and 0 on the right and bottom. This insets string follows the CSS notation of top right bottom left (i.e. start on top and go clockwise), and the values of each inset may be provided in pixels (px), millimetres (mm), percent (%), or the special \u0026ldquo;auto\u0026rdquo; value. Like CSS, you can also specify the insets using a 1, 2, or 3 values. E.g.\n\u0026quot;1mm\u0026quot; – Sets 1mm insets on all sides.\n\u0026quot;1mm 2mm\u0026quot; – Sets 1mm insets on top and bottom; 2mm on left and right.\n\u0026quot;1mm 10% 2mm\u0026quot; – Sets 1mm on top, 10% on left and right, and 2mm on bottom.\n\u0026quot;1mm 2mm 1px 50%\u0026quot; – Sets 1mm on top, 2mm on right, 1px on bottom, and 50% on left.\nauto Insets The special \u0026ldquo;auto\u0026rdquo; inset indicates that it is a flexible inset. If all insets are set to \u0026ldquo;auto\u0026rdquo;, then the component will be centered both horizontally and vertically inside its \u0026ldquo;bounding box\u0026rdquo;.\n__ The \u0026ldquo;inset bounding box\u0026rdquo; is the containing box from which a component’s insets are measured. If the component’s insets are not linked to any other components, then its inset bounding box will be bounds of the component’s parent container. If one inset is fixed (i.e. defined in px, mm, or %), and the opposite inset is \u0026ldquo;auto\u0026rdquo;, then the \u0026ldquo;auto\u0026rdquo; inset will simply allow the component to be its preferred size. So if you want to position a component to be centered vertically, and 5mm from the left edge, you could do:\nll.setInsets(btn, \u0026quot;auto auto auto 5mm\u0026quot;); Resulting in:\nMove it to the right edge with:\nll.setInsets(btn, \u0026quot;auto 5mm auto auto\u0026quot;); % Insets Percent (%) insets are calculated with respect to the inset bounding box. A 50% inset is measured as 50% of the length of the bounding box on the inset’s axis. E.g. A 50% inset on top would be 50% of the height of the inset bounding box. A 50% inset on the right would be 50% of the width of the inset bounding box.\nInsets, Margin, and Padding A component’s position in a layered layout is determined as follows: (Assume that cmp is the component that we are positioning, and cnt is the container (In pseudo-code):\nx = cnt.paddingLeft + cmp.calculatedInsetLeft + cmp.marginLeft y = cnt.paddingTop + cmp.calculatedInsetTop + cmp.marginTop w = cnt.width - cnt.verticalScroll.width - cnt.paddingRight - cmp.calculatedInsetRight - cmp.marginRight - x h = cnt.height - cnt.horizontalScroll.height - cnt.paddingBottom - cmp.calculatedInsetBottom - cmp.marginBottom - y __ The calculatedInsetXXX values here will be the same as the corresponding provided inset if the inset has no reference component. If it does have a reference component, then the calculated inset will depend on the position of the reference component. If no inset is specified, then it is assumed to be 0. This ensures compatibility with designs that were created before layered layout supported insets.\nComponent References: Linking Components together If all you need to do is position a component relative to its parent container’s bounds, then mere insets provide you with sufficient vocabulary to achieve this. But most UIs are more complex than this and require another concept: reference components. In many cases you will want to position a component relative to another child of the same container. This is also supported.\nFor example, suppose I want to place a text field in the center of the form (both horizontally and vertically), and have a button placed beside it to the right. Positioning the text field is trivial (setInset(textField, \u0026quot;auto\u0026quot;)), but there is no inset that we can provide that would position the button to the right of the text field. To accomplish our goal, we need to set the text field as a reference component of the button’s left inset – so that the button’s left inset is \u0026ldquo;linked\u0026rdquo; to the text field. Here is the syntax:\nContainer cnt = new Container(new LayeredLayout()); LayeredLayout ll = (LayeredLayout)cnt.getLayout(); Button btn = new Button(\u0026quot;Submit\u0026quot;); TextField tf = new TextField(); cnt.add(tf).add(btn); ll.setInsets(tf, \u0026quot;auto\u0026quot;) .setInsets(btn, \u0026quot;auto auto auto 0\u0026quot;) .setReferenceComponentLeft(btn, tf, 1f); This would result in:\nThe two active lines here are the last two:\n.setInsets(btn, \u0026quot;auto auto auto 0\u0026quot;) __**(1)** .setReferenceComponentLeft(btn, tf, 1f); __**(2)** __1 Sets the left inset on btn to 0. __2 Links btn’s left inset to tf so that it is measured from the text field. The third parameter (1.0) is the reference position. This will generally either be 0(meaning the reference point is the left edge of the text field), or1(meaning the reference point is the right edge of the text field). In this case we set a reference position of1.0` because we want the button to be aligned to the text field’s right edge. __ The reference position is defined as the distance, expressed as a fraction of the reference component’s length on the inset’s axis, between the reference component’s leading (outer) edge and the point from which the inset is measured. A reference position of 0 means that the inset is measured from the leading edge of the reference component. A value of 1.0 means that the inset is measured from the trailing edge of the reference component. A value of 0.5 means that the inset is measured from the center of the reference component. Etc…​ Any floating point value can be used. The designer currently only makes use of 0 and 1. The definition above may make reference components and reference position seem more complex than it is. Some examples:\nFor a top inset :\nreferencePosition == 0 ⇒ the inset is measured from the top edge of the reference component.\nreferencePosition == 1 ⇒ the inset is measured from the bottom edge of the reference component.\nFor a bottom inset :\nreferencePosition == 0 ⇒ the inset is measured from the bottom edge of the reference component.\nreferencePosition == 1 ⇒ the inset is measured from the top edge of the reference component.\nFor a left inset :\nreferencePosition == 0 ⇒ the inset is measured from the left edge of the reference component.\nreferencePosition == 1 ⇒ the inset is measured from the right edge of the reference component.\nFor a right inset :\nreferencePosition == 0 ⇒ the inset is measured from the right edge of the reference component.\nreferencePosition == 1 ⇒ the inset is measured from the left edge of the reference component.\nThe New Designer Now that you understand the basics of insets and reference components, let’s delve into the UI that we’ve designed to leverage this layout. The new GUI Builder includes a new designer that makes it a breeze to layout UIs. It allows you to drag components from the component palette onto the canvas just as you did before. The difference is that now you can move and resize your components exactly as you see fit. You aren’t constrained to the positions dictated by the form’s layout manager.\nAs an example, let’s drag a button onto a blank form and see what happens. The button will be \u0026ldquo;selected\u0026rdquo; initially after adding, it so you’ll see its outline, and resize handles for adjusting its size and position. You’ll also see four floating labels (above, below, to the left, and to the right) that show the corresponding side’s inset values and allow you to adjust them.\nPress the mouse inside the bounds of the button and drag it around to reposition it. You will notice that the inset labels change to reflect the new inset values. If you drag the button close to the edge of the form, the corresponding inset value will change to millimetres. If you move farther away from the edge, it will change to percentage values.\nThe Inset Control Let’s take a closer look at the inset control (the inset controls are the black buttons that appear to the top, bottom, left, and right of the selected component).\nEach control has three sections:\nThe inset value drop-down menu. This shows the current value of the inset (e.g. 0mm, 25%, auto, etc…​). If you click on this, it will open a menu that will allow you to change the units. If the inset is currently in millimetres, it will have options for pixels, and percent. If the inset is in percent, it will have options for pixels and millimetres. Etc.. It also includes a text field to enter a an inset value explicitly. The \u0026ldquo;Link\u0026rdquo; Button – If the inset is linked to a reference component, then this button will be highlighted \u0026ldquo;blue\u0026rdquo;, and hovering over it will highlight the reference component in the UI so that you can clearly see which component it is linked to. Clicking on this button will open a dialog that will allow you to \u0026ldquo;break\u0026rdquo; this link. You can drag this button over any component in the form to \u0026ldquo;link\u0026rdquo;.\nThe \u0026ldquo;Lock\u0026rdquo; Button\u0026quot; – This button allows you to toggle the inset between \u0026ldquo;flexible\u0026rdquo; (i.e. auto) and \u0026ldquo;fixed\u0026rdquo; (i.e. millimetres or percent).\nAuto Snap Notice the \u0026ldquo;auto-snap\u0026rdquo; checkbox that appears in the top-right corner of the designer.\nAuto-snap does exactly what it sounds like: It automatically snaps two components together when you drag them near each other. This is handy for linking components together without having to explicitly link them (using the \u0026ldquo;link\u0026rdquo; button). This feature is turned on by default. If auto-snap is turned off, you can still initiate a \u0026ldquo;snap\u0026rdquo; by holding down the ALT/Option key on your keyboard during the drag.\nSmart Insets Beside the \u0026ldquo;auto-snap\u0026rdquo; checkbox is another checkbox named \u0026ldquo;Smart Insets\u0026rdquo;.\nSmart Insets is an experimental feature at this point. It uses some heuristics during a drag to try to determine how the insets should be linked. Currently the heuristics are quite basic (it tries to link to the nearest neighbour component in most cases), but we will be working on improving this for future releases. This feature is turned off by default while it is still being refined. The goal is to improve this to the point where it always makes the correct link choices – at which time you will be able to use the designer without having any knowledge of insets or reference components. It will just work. In the current version, I generally work with auto-snap \u0026ldquo;on\u0026rdquo;, and explicitly assign links myself using the \u0026ldquo;link\u0026rdquo; button. This gives me full control of my UI and how it will be resized. Once you get used to insets and how the links work, it becomes quite easy.\nThe Widget Control Pad When a component is selected, you should see a black floating panel appear in the lower right of the screen.\nThis is the widget control pad, and it provides an alternative view of the component’s links. It also provides a useful list of incoming links (i.e. components that \u0026ldquo;depend on\u0026rdquo; this component’s positioning). In some cases, you may want to disconnect incoming links so that you can drag the component without affecting the position of dependent components.\nThis control pad also includes game-pad-like controls (up, down, left, right), that allow you to \u0026ldquo;tab\u0026rdquo; the component to the next guide in that direction. Tab positions exist at component edges in the form. This is useful for aligning components with each other.\nKeyboard Short-Cuts Arrow Keys – Use the up/down/left/right arrow keys to nudge the currently selected component a little bit at a time. This is a convenient way to move the component to a position that is more precise than can easily be achieved with a mouse drag.\nArrow Keys + SHIFT – Hold down the SHIFT key while pressing an arrow key and it will \u0026ldquo;tab\u0026rdquo; the component to the next tab marker. The form has implicit tab markers at the edge of each component on the form.\nALT/Option Key + Click or Drag – Holding down the option/alt key while clicking or dragging a component will resulting in \u0026ldquo;snapping\u0026rdquo; behaviour even if auto-snap is turned off.\nSub-Containers In some cases, you may need to add sub-containers to your form to aid in grouping your components together. You can drag a container onto your form using the \u0026ldquo;Container\u0026rdquo; palette item (under \u0026ldquo;Core Components\u0026rdquo;). The default layout the subcontainer will be LayeredLayout so that you are able to position components within the sub-container with precision, just like on the root container.\nYou can also change the layout of subcontainers to another classical layout manager (e.g. grid layout, box layout, etc..) and drag components directly into it just as you did with the old designer. This is very useful if parts of your form lend themselves. As an example, let’s drag a container onto the canvas that uses BoxLayout Y. (You can find this under the \u0026ldquo;Containers\u0026rdquo; section of the component palette).\nDrag the button (that was previously on the form) over that container, and you should see a drop-zone become highlighted.\nYou can drop the button directly there. You can As you drag more components into the sub-container, you’ll see them automatically laid out vertically.\nThe Canvas Resize Tool When designing a UI with the new designer it is very important that you periodically test the form’s \u0026ldquo;resizing\u0026rdquo; behaviour so that you know how it will behave on different devices. Components may appear to be positioned correctly when the canvas is one size, but become out of whack when the container is resized. After nearly every manipulation you perform, it is good practice to drag the canvas resize tool (the button in the lower right corner of the designer) smaller and bigger so you can see how the positions are changed. If things grow out of whack, you may need to toggle an inset between fixed and auto, or add a link between some of the components so that the resizing behaviour matches your expectations.\nThe Future This GUI builder release represents the first step in a new direction. We have our own internal todo list for moving the GUI builder forward – things like improvements to Smart Insets, better styles integration, support for more component types, and better UI tools for manipulating component properties. But we’d like to hear your feedback. What are your pain points? What do you want to do with the GUI builder that you currently find difficult? Please let us know in the comments. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — June 28, 2017 at 9:53 pm (permalink) I haven’t used this, so the answer might be obvious – when you use the new GUI builder, does this create a \u0026ldquo;GUI only\u0026rdquo; app ?\nShai Almog — June 29, 2017 at 3:30 am (permalink) The GUI project is an old concept that was retired.\nThe new GUI builder uses one form per GUI form. This means it works with regular Codename One projects and without the state machine.\nsalah Alhaddabi — June 29, 2017 at 9:09 am (permalink) Very nice.\nI would like to bring to your attention another tool that you might consider while you are improving your UI design tool as well. It is called Livecode (LC). In LC, you dont have to worry at all about positioning your UI with different screen resolutions and only one line of code makes all your UIs fit all screens. I wish CN1 has a similar ability since it is far more advanced that LC when it comes to technology integration.\nShai Almog — June 29, 2017 at 12:59 pm (permalink) Their tool is more about natural language not layout. It works with templates not components so it doesn’t allow you to do anything you want for any resolution or form factor (e.g. tablets). We would like to have more ready made templates that would effectively reduce the amount of UI you need to create.\nAlso features like properties and the automatic UI generation API can go a long way here where you don’t need to write any UI code.\nDavid G — July 1, 2017 at 12:49 am (permalink) Took the new GUI builder for a test run today and looks very promising, guys! Still some bugs to sort out (eg. the Tabs component was difficult to work with) but I’m sure you’re working on it. I can definitely see a business case for me signing up to CodeName one if the GUI builder reaches a point where I can quickly and reliably develop high quality front-ends for mobile devices.\nlooking forward to future updates!\nShai Almog — July 1, 2017 at 4:03 am (permalink) Thanks!\nThe tabs should be improved/fixed by now, we specifically didn’t commit that to keep the release stable. As I mentioned here: https://www.codenameone.com…\nWe’ll include that fix in the 3.7.2 update that will come our on Friday.\nDavid G — July 9, 2017 at 3:53 am (permalink) Hi Shai,\nThought I’d let you know I just downloaded the 3.7.2 pluggin for NetBeans and the GUI builder still doesn’t handle Tabs properly… there’s just nothing showing up in the navigation pane when components are added to a Tabs container. I was able to define tab text and icons but couldn’t go any further.\nShai Almog — July 9, 2017 at 5:08 am (permalink) Thanks. Can you please file an issue on that?\nIt probably didn’t make it eventually, I recall seeing it on an internal list but it must have gotten buried.\nΓιάννης Σαλταπίδας — June 29, 2018 at 11:19 am (permalink) Hello. There should be a tool to convert the style of the old GUI builder with the new GUI. Error free and smooth.\nShai Almog — June 30, 2018 at 4:57 am (permalink) Hi,\ntools become error free when people report errors in the issue tracker and we fix them: http://github.com/codenameo…\nThe converter is old so most people didn’t use it and just chose to start from scratch hence its still buggy. It’s probably not worth our time fixing a feature that people don’t report issues on.\nRegardless the converter was written for the original incarnation of the new GUI builder. The new GUI builder now includes the autolayout mode which is FAR superior to the previous approach. Since it’s so different conceptually from the old layout based approach there is no way to make it compatible or smooth. The converter will translate to the old approach which doesn’t give a huge advantage.\nI think our resources are better spent fixing issues in the devices/simulator. Improving the default UX and addressing issues people report in the issue tracker. Having said that if you run into an issue and report it in the issue tracker we’ll fix it.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/gui-builder-improvements-3-7/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/gui-builder-improvements-3-7/uidesign.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWith version 3.7, we have revamped the GUI builder with a designer that allows you to position your elements precisely where you want them. The experience should be closer to what you find in graphical design applications like Photoshop rather than the more rigid \u0026ldquo;drop in the slot\u0026rdquo; approach in previous versions of the GUI builder. There are caveats to be aware of with this approach, but overall, it should empower you to build beautiful UIs with greater ease than before.\u003c/p\u003e","title":"GUI Builder Improvements"},{"content":"\nCodename One 3.7, the \u0026ldquo;Write Once Run Anywhere\u0026rdquo; mobile solution for Java developers is now live!\nThis exciting new release brings with it a surprising new overhaul of the Codename One GUI builder which now includes support to \u0026ldquo;auto-layout\u0026rdquo; allowing developers to place components with the ease/power of Photoshop or Illustrator..\nCodename One is the only platform that…​\nHas Write Once Run Anywhere with no special hardware requirements and 100% code reuse\nCompiles Java into native code for iOS, UWP (Universal Windows Platform), Android \u0026amp; even JavaScript\nIs Open Source \u0026amp; Free with an enterprise grade commercial offering\nIs Easy to use with 100% portable Drag \u0026amp; Drop GUI builder\nHas Full access to underlying native OS capabilities using the native OS programming language (e.g. Objective-C) without compromising portability\nLets you use native widgets (views) and mix them with Codename One components within the same hierarchy (heavyweight/lightweight mixing)\nTo learn more about Codename One check out the about page you can download it for free right now.\nFrom Lowlight to Feature When we released Codename One 3.6 we had this to say:\nThe one thing we really didn’t get out in this release is a new Codename One course which we’ve been working on for a while. We hope we’ll get it done during the 3.7 era but video production is always a big effort and we just don’t have enough hours in the day…​\n— Codename One 3.6 release announcement\nYesterday we announced the new Codename One Academy which includes 3 new media rich courses that will cover everything needed to build gorgeous real world apps. This is new original materials with a 2 year monthly update commitment roadmap!\nAs is our custom with some releases we are also running a promotion on these courses and our special offer expires on July 3rd so hurry up!\nHighlights of this Release Here are the top 5 features of this release illustrated in this short video, check out further details below.\nGUI Builder Auto Layout – We now support an inset based GUI builder mode that allows positioning components in a far more fluid way. We are still working on tutorials for this new mode and it’s highly experimental but you can start using it right now!\nIn addition to that we made numerous enhancements to the UX of the GUI builder further refining it\nLive Style Customization – The UI design of the application can be customized directly from the simulator\nZ-Ordering on All OS’s – You can mix native components e.g. maps, video. With Codename One components and draw on top of them\nProperties SQL \u0026amp; UI Binding – Support for database mapping (ORM), parsing \u0026amp; UI binding/generation seamlessly using the properties API\nRest API for Terse Networking – New builder style REST API that abstracts some of the verbosity of ConnectionRequest\nVM API Enhancements – Added some core VM classes and API’s such as java.lang.Number, CharSequence, exception chaining etc.\nTerse Syntax – New CN API allows developers to write more concise code, new helper API’s such as addAll \u0026amp; a jquery style component selector\nSecurity Oriented API’s – New API’s for detecting certificates on https servers as well as API’s for touch ID, jailbreak detection and more\nThread Helper \u0026amp; Threadsafe SQLite API’s – A new API for communicating with threads \u0026amp; a new threadsafe wrapper for sqlite\nBetter Desktop/Web API’s – We now support API’s such as mouse cursor customization, split pane, mouse hover events etc. which allow more elaborate desktop apps. We also include an experimental new \u0026ldquo;desktop skin\u0026rdquo; to debug desktop apps\nExperimental \u0026ldquo;On Top\u0026rdquo; Sidemenu \u0026amp; Form Layered Pane – Side menu can now be on top of the UI and potentially on top of the entire form with a new layered pane mode\nParparVM Performance Improvements – Some of the code such as method invocations will now compile to the C equivalent of that code in terms of performance, many basic numeric operations are much faster thanks to VM optimizations and code is up to 40% smaller over 3.6\nTwo Factor Authentication in Certificate Wizard – The certificate wizard now supports 2 factor authentication in your apple account\nFaster iOS Builds – Build times in the Apple servers are up to x3 faster for some users with exceptionally long build times.\nTest Recorder \u0026amp; Toolbar – The test recorder now works correctly with the toolbar\nLowlights As we always do with a release we’d like to shine a spotlight on the things 3.7 can do better and the things 3.8 can improve on. Overall we are thrilled with this release but here are a few things we can do better:\nOn device debugging – this was planned for 3.7 but didn’t make it. We have a running proof of concept but that also highlights the amount of work needed to bring this to production grade. Since 3.8 is relatively close by it’s hard for us to say if it will be a feature of 3.8.\nImproved default themes \u0026amp; material design – this is an area we need to spend more time on. We are attacking it one component at a time but that is often challenging. We can use your help in filing issues and pull requests to improve the situation. If you see something that doesn’t look good or doesn’t look native go to the issue tracker \u0026amp; create a new issue in it include a screenshot of how it looks now and a screenshot of how it should look. This helps us focus on the things that are important to our users. Even if we know about the problem an issue helps us focus!\nTheme \u0026amp; Localization – The new GUI builder is starting to take shape and it’s time to turn our attention to the other rolls that the old designer tool handles. We already made some improvements to styling but we can go further.\nOnwards to 3.8 We completed almost everything we wanted to do for 3.7, to be fair that’s not to hard as we delayed the release due to the bootcamp and that gave us extra time.\nThe next version will be out in mid November which already feels damn close by now so I’m not sure which ones of the lowlights above we’ll be able to address by then but those are our biggest priorities not necessarily in that order.\nThe one feature that we did announce for 3.8 is Kotlin support. We ran a survey whose results included a bit of a surprise to us, it’s something I’ll discuss in an upcoming post.\nWe Need your Help Spread the word, please let people know about us.\nSign up for enterprise accounts, besides the huge benefits of an enterprise account these are the guys that keep the lights on here and allow us to build Codename One. If your company can afford it please take the time and upgrade to enterprise, this will allow us to work on the things that are important for your company!\nThanks for reading this far and if you have any thoughts/suggestions of any kind please feel free to post below! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDalvik — June 27, 2017 at 1:11 pm (permalink) Dalvik says:\nI’ve just tried the new GUI builder, at first it was a bit confusing as it felt a bit like I can put a component anywhere but then I watched the video and it \u0026ldquo;clicked\u0026rdquo;.\nI really like the drag and drop UI of the GUI builder, it’s pretty smooth… Was it built with JavaFX?\nShai Almog — June 27, 2017 at 1:16 pm (permalink) Shai Almog says:\nThanks.\nNo, it’s actually written in Codename One… Just like the Codename One Settings. Just goes to show you what you can do with some attention to detail.\nMac Flanegan — June 27, 2017 at 1:30 pm (permalink) Mac Flanegan says:\nCongratulations on the updates of this new version!\nPS: In Delphi this feature is called \u0026ldquo;Anchors\u0026rdquo; what I think would be a more appropriate name.\nShai Almog — June 27, 2017 at 1:37 pm (permalink) Shai Almog says:\nThanks!\nWere anchors automatically placed and bound with percentage or millimeter units to other components?\nI haven’t used it in years so I don’t recall…\nI was for constraints and in Java there is a Spring layout (which I glad he didn’t pick as Spring is already deeply used in Java).\nPugazhendi E — June 27, 2017 at 1:46 pm (permalink) Pugazhendi E says:\nCongrats 🙂\nMac Flanegan — June 28, 2017 at 5:08 pm (permalink) Mac Flanegan says:\nIn Delphi this a more simple feature. The reference is \u0026ldquo;always\u0026rdquo; the parent component. But the idea is the same. Delphi has constraints too.\nAutoLayout reminds me the automatic arrangement of components, as it already exists in codename. So the suggestion to use Anchors. In my opinion Anchors says more about what this feature does.\nBefore I see it working, I even thought: – but the codenameonde already does autolayout …\nBut again, congratulations to the new features …\nShai Almog — June 29, 2017 at 3:54 am (permalink) Shai Almog says:\nAutolayout is a term used in iOS so we chose it to keep it familiar.\nFrancesco Leoni — June 29, 2017 at 6:35 am (permalink) Francesco Leoni says:\nHi Shai, congratulations on the new release!\nIs it possible to open an old Form (created using the previous GUuiBuilder) with the new GuiBuilder, or to convert an old Form to the new format?\nAt present I can use the new GB interface only wher I create a brand new Form.\nShai Almog — June 29, 2017 at 8:56 am (permalink) Shai Almog says:\nThanks!\nRight now there are 3 modes:\n– Old GUI builder – that’s the old designer tool where we still have theming. That’s a completely separate tool with the state machine etc.\nYou can use the conversion tool command line as explained here: https://www.codenameone.com… to convert that old GUI to the new GUI builder. Notice that it will not take advantage of the new auto-layout…\n– New GUI builder code created pre-3.7. These forms have auto-layout off by default for maximum compatibility as this might break some existing logic.\n– New GUI builder forms created with autolayout\nIf you are referring to converting the GUI builder code pre-3.7 to post 3.7 you can easily do that but it will require a bit of hacking. Just open the .gui XML file and set the layout of the form to be layered layout. Then set autoLayout=\u0026ldquo;true\u0026rdquo; in the top level component tag. This will enable the new layout mode on an older form. Everything might be \u0026ldquo;messed up\u0026rdquo; after you do that which might require some work of fixing.\nFrancesco Leoni — June 29, 2017 at 7:55 pm (permalink) Francesco Leoni says:\nThankyou so much for your reply. Unfortunately that didn’t do the trick: after modifying the top level component like this (see below), the GUI builder is not starting at all.\ncomponent type=\u0026ldquo;Form\u0026rdquo; layout=\u0026ldquo;LayeredLayout\u0026rdquo; title=\u0026ldquo;MyApp\u0026rdquo; name=\u0026ldquo;GuiComponent\u0026rdquo; autoLayout=\u0026ldquo;true\u0026rdquo;\u0026gt;\nLauching Gui builder from commandline I can see some null pointer exceptions like the one below:\n[EDT] 0:0:0,316 – Exception: java.lang.NullPointerException – null\njava.lang.NullPointerException\nat com.codename1.ui.layouts.LayeredLayout$LayeredLayoutConstraint.setInsets(LayeredLayout.java:1871)\nat com.codename1.apps.guibuilder.GuiPersister.createComponent(GuiPersister.java:282)\nat com.codename1.apps.guibuilder.GuiPersister.load(GuiPersister.java:99)\nat com.codename1.apps.guibuilder.GUIBuilder.connected(GUIBuilder.java:76)\nat com.codename1.apps.guibuilder.GUIBuilder.start(GUIBuilder.java:107)\nat com.codename1.apps.guibuilder.desktop.GUIBuilderMain$[11.run](http://11.run)([GUIBuilderMain.java](http://GUIBuilderMain.java):427)\nat com.codename1.ui.Display.processSerialCalls(Display.java:1056)\nat com.codename1.ui.Display.mainEDTLoop(Display.java:873)\nat [com.codename1.ui.RunnableWr…](http://com.codename1.ui.RunnableWrapper.run)([RunnableWrapper.java](http://RunnableWrapper.java):120)\nat [com.codename1.impl.Codename…](http://com.codename1.impl.CodenameOneThread.run)([CodenameOneThread.java](http://CodenameOneThread.java):176)\nShai Almog — June 30, 2017 at 3:59 am (permalink) Shai Almog says:\nSorry, it seems I remembered this incorrectly and the attribute should be autolayout lower case not camel case.\nFrancesco Galgani — June 30, 2017 at 11:27 am (permalink) Francesco Galgani says:\nAre these new features (in particular the new Gui Builder) covered in the three courses of the Codename One Academy?\nShai Almog — June 30, 2017 at 12:46 pm (permalink) Shai Almog says:\nSome of them are, some are coming soon and some are not.\nIn particular the GUI builder should be coming soon.\nI started working on a module but it ended up being too problematic to document a tool that’s changing so quickly (case in point here). Hopefully this marks a stable point where I can start working on a GUI builder module which will hopefully be the first module I add after finishing this work.\nI’m considering building parts of the Uber app using the GUI builder but I’m not sure if it will work well with that use case.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-3-7-live/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-3-7-live/codenameone-3-7.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/\"\u003eCodename One\u003c/a\u003e 3.7, the \u0026ldquo;Write Once Run Anywhere\u0026rdquo; mobile solution for Java developers is now live!\u003cbr\u003e\nThis exciting new release brings with it a surprising new overhaul of the Codename One GUI builder which now includes support to \u0026ldquo;auto-layout\u0026rdquo; allowing developers to place components with the ease/power of Photoshop or Illustrator..\u003c/p\u003e\n\u003cp\u003eCodename One is the only platform that…​\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eHas Write Once Run Anywhere with no special hardware requirements and 100% code reuse\u003c/p\u003e","title":"Codename One 3.7 is Live"},{"content":"\nOn the eve of the release of Codename One 3.7 we are excited to announce the new Codename One Academy which will change the way people learn Codename One. We’ve invested a lot of effort in creating a smooth learning experience and we’re launching with 3 live courses.\nThis wouldn’t have been possible without all the help from community members who provided guidelines, feedback and assistance. It wouldn’t have been possible without the members of the bootcamp who helped with the process of refining the requirements from this course. Thank you all for your help!\nThanks to all of that the academy is launching with 3 courses:\nJava for Mobile Devices – This is the \u0026ldquo;learn Codename One\u0026rdquo; course. It covers the basics that all Codename One developers should know. This is a completely free course that we will keep enhancing!\nDeep Dive into Mobile – This course goes into all of the complex features of Codename One and builds a non-trivial application. In fact it builds the restaurant app\nBuild Real World Full Stack Mobile Apps in Java – is the pinnacle of this trio, it bundles the Deep Dive into Mobile course as it picks up where that course left off. It builds the full restaurant app builder application. It covers the server side and goes into deep details on everything. I’ll add at least 8 additional apps to this course over the next two years making it even more compelling than it is now\nThose of you who were a part of the bootcamp get all of these courses for free!\nLiving Courses We guarantee a new course module every month. That means you will get additional information in the courses as we move forward for the next two years.\nI will also develop at least 8 new complete, publishable apps and add them to Build Real World Full Stack Mobile Apps in Java over the next two years. That means that the courses you see today will be significantly larger and include a lot of additional information moving forward.\nSpecial Sale These courses don’t include everything that went into the bootcamp but they include a lot of material and will include a lot more as we move forward. As such the list prices for them is:\nJava for Mobile Devices – Free\nDeep Dive into Mobile – 199USD. The special sale price is 99USD or three installments of 39USD.\nBuild Real World Full Stack Mobile Apps in Java – 399USD (includes Deep Dive into Mobile). The special sale price for this bundle is 199USD or six installments of 39USD.\n__ The special sale price is for one week only and will expire on July 3rd! App Survey Results The final survey results for the app are pretty clear, it’s an Uber clone:\nFigure 1. Final survey results\nWhat isn’t clear is the second place where a whatsapp clone and social media app fall within the margin of error. These results can be flipped completely if people who voted for the Uber clone shift their votes overwhelmingly to one side so out of curiosity I made a new poll.\nThis poll only includes these two options and should display a clearer preference for the second app.\nThanks again for all the feedback it’s very much appreciated and this just wouldn’t exist without your help! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDalvik — June 26, 2017 at 12:09 pm (permalink) Great!\nJust signed up to the full package 😉\nThanks for the new survey I’m one of the guys who voted for Uber so I changed my vote to a whatsapp clone here.\nFrancesco Galgani — June 26, 2017 at 3:39 pm (permalink) Francesco Galgani says:\nAny extra discount for the PRO developers?\nShai Almog — June 26, 2017 at 4:12 pm (permalink) Shai Almog says:\nFYI you are in a serious minority as this seems to have flipped with the removal of Uber but things like this can change in an instant… https://uploads.disquscdn.c…\nShai Almog — June 26, 2017 at 4:16 pm (permalink) Shai Almog says:\nThis was something we thought about quite a bit. In the past we gave a coupon in the old Udemy course but the free course covers pretty much everything the old paid course had. So effectively we made the training free.\nThe higher end courses are far more advanced than anything we had before and discounting them doesn’t fit here.\nWe charge for them so we’ll have the financial incentive to keep enhancing and growing them.\nsalah Alhaddabi — June 26, 2017 at 5:53 pm (permalink) salah Alhaddabi says:\nAlready signed up and enrolled in all courses. I think i will skip the spring part and focus on building the UI only as i am only using java ee 7 instead of spring.\nShai Almog — June 26, 2017 at 7:09 pm (permalink) Shai Almog says:\nThanks!\nI was never a fan of Spring but Spring Boot won me over… It has some pretty spectacular ideas and brings Java to the level of agility normally reserved to scripting languages.\nMichael Lindvall — June 26, 2017 at 7:57 pm (permalink) Michael Lindvall says:\nI’m looking forward to all the material you’re sharing.\nbryan — June 26, 2017 at 8:06 pm (permalink) bryan says:\nLooking at the curriculum for the courses, I get the impression that you might be moving towards styling forms via CSS rather than themes ?\nStephen Aitchison — June 27, 2017 at 12:03 am (permalink) Stephen Aitchison says:\nwas thinking about learning more on Codename One, but I want to find some tutorials on how to learn without the initial investiment upfront.. do you know of any good resources that you would suggest?\nShai Almog — June 27, 2017 at 3:38 am (permalink) Shai Almog says:\nThere is a relatively big free course in that package for just that case. It’s not as refined as the other courses because I did it first (I will hopefully get the time to go back and polish it). But it still contains a lot of practical and important information.\nShai Almog — June 27, 2017 at 3:41 am (permalink) Shai Almog says:\nNo. I used CSS for the restaurant app because people wanted to learn CSS and because it fit into that specific use case.\nThe restaurant builder app generates versions of the restaurant app and customizing CSS in a code generator seems easier than the alternative.\nAmuche Chimezie — June 28, 2017 at 9:47 am (permalink) Amuche Chimezie says:\nHi Shai, Just seeing this today. Just to be sure before I sign up. With $200 I get access to Deep Dive into Mobile and Build Real World Full Stack Mobile Apps in Java bundles right?\nAn urgent feedback please to enable me close out on this.\nShai Almog — June 29, 2017 at 3:32 am (permalink) Shai Almog says:\nWhen you purchase build real world full stack mobile apps the deep dive is included.\nJoão Bastos — June 29, 2017 at 11:30 am (permalink) João Bastos says:\nAll-in!\nFrancesco Galgani — June 29, 2017 at 1:43 pm (permalink) Francesco Galgani says:\nI’m enrolled in Build Real World Full Stack Mobile Apps in Java. You wrote that is costs 199USD or six installments of 39USD. I paid the first installment, I expected to pay 39USD, but you charged me 47.6USD. Ok, it’s not a problem, but in my opinion it’s not correct to show prices without saying that taxes will be added to them at the payment. What taxes have I paid for? I live outside the United States.\nShai Almog — June 29, 2017 at 1:52 pm (permalink) Shai Almog says:\nI live outside of the US too. The problem is we can’t list after local tax prices since they are different to every region. Teachable specifies them and does so during the billing process when you enter your location. Notice that we don’t charge you, teachable does and we get paid by them. See this on their tax policy which is way more information about taxes than I care to read: https://support.teachable.c…\nJust so we are clear any extra amount you pay doesn’t get to us as it’s deducted immediately.\nFrancesco Galgani — June 29, 2017 at 1:55 pm (permalink) Francesco Galgani says:\nOk\nAmuche Chimezie — July 3, 2017 at 8:13 am (permalink) Amuche Chimezie says:\nMade Payments. Please help confirm.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/launching-codename-one-academy/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/launching-codename-one-academy/java-for-mobile-devices1024.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOn the eve of the release of Codename One 3.7 we are excited to announce the new \u003ca href=\"https://codenameone.teachable.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCodename One Academy\u003c/a\u003e which will change the way people learn Codename One. We’ve invested a lot of effort in creating a smooth learning experience and we’re launching with 3 live courses.\u003c/p\u003e\n\u003cp\u003eThis wouldn’t have been possible without all the help from community members who provided guidelines, feedback and assistance. It wouldn’t have been possible without the members of the bootcamp who helped with the process of refining the requirements from this course. Thank you all for your help!\u003c/p\u003e","title":"Launching the Codename One Academy"},{"content":"\nYou know that feeling before going on stage to talk or perform. It’s a knot in your stomach but also an exhilarating sense of excitement about what’s to come…​ I’ve got that fidgety feeling of \u0026ldquo;can’t wait to get it out\u0026rdquo; and yet I feel there is so much more to do.\nThanks for all the comments, questions, suggestions \u0026amp; votes for the last couple of posts. Those always help tremendously!\nOne of our bootcamp participants mentioned the length of my videos in the bootcamp and my response at the time was that I can’t possibly make the videos shorter as it would be far more work…​\nTurns out that this isn’t the case. It was just the problematic tools I was using. Once I got the flow of video making, splitting the videos to shorter more concise videos became easier. Newer videos within the course are much shorter but include roughly the same amount of information. That information density makes them more understandable and easier to go thru so I’m very excited about this.\nThree Courses I didn’t really explain too much about how this is going to work. I mentioned a few times that there will be 3 courses but didn’t go into details…​\nThe goal is to create something that’s more manageable for you and for us. An important part of taking a course is completing it and this is often difficult. However, if it’s three courses you can set a goal to finish one each month and it would be far more attainable.\nSegmenting the material allows more structure and ideally more people reaching that coveted 100% complete stage!\nThe courses will be:\nJava for Mobile Devices – This is the \u0026ldquo;learn Codename One\u0026rdquo; course. It covers the basics that all Codename One developers should know\nDeep Dive into Mobile – This course goes into all of the complex features of Codename One and builds a non-trivial application. In fact it builds the restaurant app\nBuild Real World Full Stack Mobile Apps in Java – is the pinnacle of this trio. It continues where the deep dive ended and builds the full restaurant app builder application. It covers the server side and goes into deep details on everything. I’ll add at least 8 additional apps to this course over the next two years making it even more compelling than it is now\nWhat about the Apps? We will produce at least one new module for the courses every month for the next two years.\nGuaranteed!\nThat means at least 24 additional modules beyond what we have on launch.\nOnce every 3 months (once a quarter) we’ll build a complete application as a module. Based on the current vote results it seems that the first app will be an Uber clone. In the module I’ll implement the app and teach you how to build such an app. This means we’ll implement 8 additional apps in total over the next two years (in additional to the 2 already in the course) and I’ll teach you how to build each one of those apps.\nI think this update commitment is crucial to keep the material fresh and up to date.\nSpeaking about this, thanks again for taking the time and voting!\nThis is the current set of results:\nFigure 1. App preference results\nThis isn’t final yet and I’ll redo a survey after launch for the 3rd app onwards so the question is whose number 2 after Uber clone?\nThat’s still open…​\nWhat will be Covered? These are pretty huge courses that literally cover everything you need to bring apps to production from idea to UI design all the way to deploying your cloud server to a VPS.\nI don’t like cutting corners so I try to cover as much as possible. Since the courses will be updated over the years and add additional application types I’m very confident that this scope will further expand with samples and subjects as we move forward.\nWhat if I’m a Beginner? Can I take all 3 courses? This depends on stamina, they are designed in sequence and the material gets harder on a curve. The first course should be easy, the second moderate and the third is harder…​\nThere probably won’t be blood sweat and tears (hopefully) but the final course isn’t easy.\nThe final course is designed to teach practical real world development techniques and that might be difficult for some. It’s an advanced course that will hopefully prepare you for real world workloads, problems \u0026amp; shortcuts.\nWould I get Assistance in Completing the Course? As usual you will get all the regular help in the forum, stackoverflow etc. Since this is an official course from Codename One we can answer the questions there.\nFurthermore, the course itself also includes discussion per module which you can also use. It has the advantage of being a part of the course and that way you can help future students using the course by asking the relevant questions.\nWill this Material be Exclusively in the Course? Yes. This is material that’s built specifically for these courses. Some of the materials were featured in the bootcamp or based on materials that appeared there but most of the material is either completely new or reworked. It won’t be available anywhere else for the next two years.\nIs there any time commitment like we had in the bootcamp? No. This is a standard course and you can take it at your leasure. Access to the course isn’t time limited.\nTeachable (who we use for our new course materials) used the term perpetual which I personally find \u0026ldquo;problematic\u0026rdquo; as I’m pretty sure access will not survive the Sun going supernova.\nHaving said that, we plan to keep the course online as long as possible and ideally as long as it’s useful. We also guarantee new materials will be added to the courses over the next 2 years at least!\nIs there a Certification Process? Not at this time. We’d like to add Codename One certification but this is a pretty difficult process to go thru (on our side).\nHowever, the best way to market your skills is by showcasing an attractive application. Showing and deploying such an application is a core goal of this course.\nComing Soon At first I thought we should launch the new courses with the 3.7 release next week. However, one might overshadow the other so we’ll publish the courses Monday and release Codename One 3.7 on Tuesday. Keep an eye on this…​\nTwo weeks after registration closed for the bootcamp we still got a lot of emails from people claiming they didn’t know the bootcamp was available or sold out. I felt I sent too many emails but people still missed it and were very disappointed. I hope we don’t get something like this with the coming launch so please keep an eye on the blog next week.\nThanks again for all the great feedback, comments \u0026amp; votes. They are all highly appreciated especially when they are mixed with constructive criticism. Please keep it coming and let me know what you think. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — June 22, 2017 at 12:22 pm (permalink) Thank you!\nJérémy MARQUER — June 22, 2017 at 1:32 pm (permalink) Jérémy MARQUER says:\nHappy to see that CN1 is on the good way and you are really listening to customers 🙂\nI would like to inform you one major difficulty I had, when I start working with codenameone : project architecture.\nAs you know, few years ago, principle of CN1 was StateMachine class, in which we could find ALL the code. It was pretty difficult to organize my code. I’ve tried to apply a pseudo MVC architecture to my project but it was a bit difficult with this \u0026ldquo;StateMachine\u0026rdquo; class. So I’ve decided to handcoded all my form (and erase all from GuiBuilder). In addition, you have changed the manner form was build with the new gui builder. We have now one class for one form. What I didn’t like much was that everything was in a form class : UI construction as well as event management. I can now tell you my architecture :\n– \u0026ldquo;controller\u0026rdquo; for pure calcul\n– \u0026ldquo;dao\u0026rdquo; for database access\n– \u0026ldquo;model\u0026rdquo;\n– \u0026ldquo;service\u0026rdquo; for interfacing dao\n– \u0026ldquo;view\u0026rdquo; with all my form, dialog and components\n– \u0026ldquo;viewController\u0026rdquo; which contains all the event management and controllers invocation\nAbout view and viewController : each classes in viewController have a maching view (Form, Dialog or Container). Every main classes of my view are manage by a class : \u0026ldquo;ComponentManager\u0026rdquo;. Same as for viewController : \u0026ldquo;ComponentControllerManager\u0026rdquo;. All of my views and controller’s view are singleton and could be recreate by manager.\nI tell you that because I noticed all demos aren’t so much organize which must, in my opinion, not be the case for bigger application. I didn’t say my method is the best, but I wanted to let you know.\nMaybe it could be a good idea to have an architecture course 🙂\nJust a word about 3.7 : I’ve installed successfully on Eclipse Luna (which was impossible with 3.6). New gui builder doesn’t seems to work. I think it should be better on Eclipse Neon.\nDalvik — June 22, 2017 at 2:26 pm (permalink) Dalvik says:\nCan’t wait 😉\nShai Almog — June 22, 2017 at 2:52 pm (permalink) Shai Almog says:\nThanks!\nI actually spend a lot of time talking about architecture in the courses. I cover both client and server architecture \u0026amp; how to tie them all together. I go into details such as cases where architectural decisions I take in the server impact security or the UX of the final app. It’s not an architecture course as it’s very pragmatic though.\nThe old GUI builder which we are no longer using used an architecture that made a lot of sense on J2ME devices where every class file we added impacted size/performance and we tried to save on creating new class files. The new GUI builder is far more conventional in that sense and with the 3.7 release coming Tuesday it’s getting a MAJOR facelift…\nManuel Tijerino — June 22, 2017 at 9:32 pm (permalink) Manuel Tijerino says:\nPlease let me know when these courses come out, would be very useful, thanks.\nShai Almog — June 23, 2017 at 4:36 am (permalink) Shai Almog says:\nI’ll send out an email so if you got my last couple of emails over the past few days this shouldn’t be a problem.\nIt’s launching on Monday and on Tuesday we have 3.7 which is shaping up as a pretty amazing release…\njames agada — June 23, 2017 at 12:16 pm (permalink) james agada says:\nwaiting of the course.\nLukman Javalove Idealist Jaji — June 23, 2017 at 11:16 pm (permalink) Lukman Javalove Idealist Jaji says:\nDo you already know how much the course will cost?\nShai Almog — June 24, 2017 at 5:12 am (permalink) Shai Almog says:\nWe’ll offer multiple options\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/how-does-it-work/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/how-does-it-work/build-real-world-full-stack-mobile-apps-in-java.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eYou know that feeling before going on stage to talk or perform. It’s a knot in your stomach but also an exhilarating sense of excitement about what’s to come…​ I’ve got that fidgety feeling of \u0026ldquo;can’t wait to get it out\u0026rdquo; and yet I feel there is so much more to do.\u003c/p\u003e\n\u003cp\u003eThanks for all the comments, questions, suggestions \u0026amp; votes for the \u003ca href=\"/blog/good-to-great.html\"\u003elast couple of posts\u003c/a\u003e. Those always help tremendously!\u003cbr\u003e\nOne of our bootcamp participants mentioned the length of my videos in the bootcamp and my response at the time was that I can’t possibly make the videos shorter as it would be far more work…​\u003c/p\u003e","title":"How does it Work?"},{"content":"\nThanks for all the great feedback on my last post, I got some wonderful app suggestions from some of you and some interesting questions. Overall, there were more than 100 comments and emails so I apologize if I took too long to answer some of you. I already mentioned the focus of these coming courses is to let you create apps in a more practical form: \u0026ldquo;cook book\u0026rdquo; style.\nBut while I talked a bit about the narrative and the course I didn’t explain exactly how or why this will work effectively.\nOne of the core capabilities of Codename One is control over every pixel in the screen. It’s a huge benefit and also a double edged sword…​\nWhen wielded properly you can leverage this ability to create custom, fluid UI’s that seamlessly match the native OS style and form. But with great power comes great responsibility and we can end up with apps that…​ I’m sure you can complete that sentence…​ We’ve all seen those apps and I don’t want you to be there.\nRecently I explained how we can create a gorgeous side menu design with very few steps. That’s one of the things I picked up from the bootcamp. Everyone had issues with something that should be as simple as a side menu. But that’s just the tip of the iceberg when you are building a full fledged app. That’s exactly what I aim to fix with this new material.\nFeedback After my last post I received a lot of questions \u0026amp; suggestions that I’d like to address:\nDo I need to Know Anything?\nYou need to know Java to a reasonable degree. You don’t need prior knowledge in Codename One though. I’d love to add an \u0026ldquo;introduction to Java\u0026rdquo; course to the mix but that might be stepping outside of my personal comfort zone.\nWill you use Youtube?\nOne of the questions focused on youtube mostly because of their excellent subtitle support which makes the videos more accessible to foreign language speakers and the hearing impaired.\nI’ll use the teachable platform which allows me to structure course material and provide solutions, presentations etc. as part of the course. In some of the presentations I also include a transcript of the video with the slides, this should help fill in the gaps. I’m not sure if I’ll be able to walk the way back and do that for the older videos but since it’s already done for a lot of the videos it shouldn’t be a problem.\nWhat sort of material will be covered?\nWe will launch with the restaurant and the \u0026ldquo;app builder\u0026rdquo; as part of the initial launch material. This is some of the material I developed for the bootcamp \u0026ldquo;remastered\u0026rdquo; to a more refined flow.\nA major focus of the material is refining the look of the application, working with themes and design. But this is just a tip of the iceberg as the material covers everything that you need to bring an app to production. From security, to application architecture, native interfaces, sql, ORM, backend VPS setup and everything in between.\nNotice I’ve made a specific distinction for \u0026ldquo;launch material\u0026rdquo;, for the next two years at least we will add a new module every month. Guaranteed!\nShouldn’t Codename One be Good Looking by Default?\nThis isn’t exactly a question that was asked but it was an underlying current.\nThe answer is yes. We are are working on improving the default look for applications so if you create a hello world and start adding components without knowing much you should get something that looks decent.\nThis material would still be valuable even as we improve the basic look, everything that I teach would be just as applicable in the future as it is now. I’ll also update materials with newer details as features and enhancements make their way out.\nReal Apps I’ve mentioned the importance of \u0026ldquo;real world\u0026rdquo; apps in my last post and asked for some feedback to get a sense of what sort of apps you are building. You really came through with a lot of great suggestions!\nI worked on them a bit to unify some of the ideas that are similar and came up with a set of initial suggestions:\nTaxi hailing app (Uber clone)\nInstant messaging app (whatsapp clone)\nSocial media app (instagram/facebook style)\nSide scrolling game (mario style)\nPoint of sale app (charging and invoicing)\nImage editor app (finger paint style app)\nKids puzzle game\nClient Server business management app with database synchronization\nClient Server business management app with Parse backend\nMusic player app\nVideo player app\nCamera app – photos with overlay images on top\nIf you can think of other ideas for such apps that you would like to see please use the comments section below for ideas.\nI’ve narrowed this list down to the top 4 most requested apps and I’ve made a voting form you can use to select the apps that you think I should add first to the course click here to select the app.\nBefore I sign Off Today we entered the code freeze and released a release candidate of Codename One 3.7 plugins. That means you should be able to update the plugins for all major IDE’s and get the latest version of Codename One. Please bang on it a bit and let us know if there are major regressions.\nSo What’s Next? In the next piece I’ll explain the details of how the whole thing will work and why I chose to go with exactly 3 courses…​\nAs always I really appreciate the comments and feedback, if you have thoughts or questions please let me know. And please don’t forget to vote! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDalvik — June 21, 2017 at 11:22 am (permalink) Dalvik says:\nDo we get an \u0026ldquo;I voted\u0026rdquo; badge on our account 😉\n+1 for the Uber demo.\nDownloading 3.7 RC right now!\nShai Almog — June 21, 2017 at 11:41 am (permalink) Shai Almog says:\nBased on the first few votes, the Uber clone looks like it will win in a landslide…\nKolawole Tajudeen — June 21, 2017 at 11:43 am (permalink) Kolawole Tajudeen says:\nPoint of sale app sounds great\nAndrew Ughonu — June 21, 2017 at 11:55 am (permalink) Andrew Ughonu says:\nSocial media app (instagram/facebook style) will juust do it. Thanks\nsalah Alhaddabi — June 21, 2017 at 12:54 pm (permalink) salah Alhaddabi says:\nDear Shai, in general if you can have one business app and one social app will be great. Your listed apps also look great and thanks a lot for your interaction with your customers as i have never seen this being done anywhere with other development platforms. Thanks a lot!!!\nDalvik — June 21, 2017 at 12:58 pm (permalink) Dalvik says:\nI second that!\nShai Almog — June 21, 2017 at 1:27 pm (permalink) Shai Almog says:\nThanks. Would love to do that but it’s probably something that will have to wait for a while.\nShai Almog — June 21, 2017 at 1:29 pm (permalink) Shai Almog says:\nBased on current voting it’s 3rd by a narrow margin behind whatsapp style app. I initially expected this to be a tighter race but Uber style app is so far ahead I doubt this will change. But I’ve been surprised by these things before.\nShai Almog — June 21, 2017 at 1:31 pm (permalink) Shai Almog says:\nThanks!\nCompanies that originate from open source projects tend to have a relatively open culture.\nFrancesco Galgani — June 21, 2017 at 2:12 pm (permalink) Francesco Galgani says:\nI voted for the social app 🙂\nAre the new courses free or with fee?\n3lix — June 21, 2017 at 2:48 pm (permalink) 3lix says:\nI think there are lot of materials covering social style app even though it is spread across the documentation, blog, stackoverflow, google groups etc…\nBut there aren’t any materials detailing an Uber style app.\n+1 Uber (style)\nShai Almog — June 21, 2017 at 3:09 pm (permalink) Shai Almog says:\nThis is the current status of the votes, Uber style has a solid lead but it’s narrowing from a 80%. I still think it will come on top…\nhttps://uploads.disquscdn.c…\nShai Almog — June 21, 2017 at 3:10 pm (permalink) Shai Almog says:\nAgreed, it is indeed a missing piece.\nRoman H. — June 21, 2017 at 4:05 pm (permalink) Roman H. says:\nOne more for Client Server business management, I am just investigating now to build up a mobile reporting prototype. @Shai regarding the data processing please focus on JSON and CVS and let the companies backend guys to build their own API to handle their conversion from SQL to CVS / JSON. It will strip you multiple DB engine handling while you can focus on chart and graph implementation.\nJohn Barrett — June 21, 2017 at 4:53 pm (permalink) John Barrett says:\nThanks Shai. These look great! I’m very interested in the Client server business apps. I look forward to learning more about all of these, though!\nShai Almog — June 22, 2017 at 4:19 am (permalink) Shai Almog says:\nWe focus only on the things necessary in the client. In the online course the server code is designed as a simple instruction tool and not meant to replace proper training in server development tools. The main reason we have it is for small shops/teams that need to do everything. I think having decent understanding of what the server guys do is important for mobile developers just like it’s important for us to understand what a UI designer does and his process.\nNotice we have SQL on the device itself (sqlite) and we use it for some storage and processing.\nShai Almog — June 22, 2017 at 4:22 am (permalink) Shai Almog says:\nThe material launches with 2 applications which are the restaurant app and builder app. Technically both are client server app and I spend a lot of time discussing the communication, responsibility, webservices etc.\nIn the final segments I cover it all the way to the deployment of the server in the VPS.\nRiper3-3 — June 22, 2017 at 7:42 am (permalink) Riper3-3 says:\nHello! I think an awesome app would be something to do with IoT, connecting to something like an arduino with Bluetooth, and then sending it relevant data. This would probably have to work with only one type of IoT device… or the possibilities would be too many.\nShai Almog — June 22, 2017 at 9:45 am (permalink) Shai Almog says:\nThanks.\nI love these demos when I go to shows as it’s really cool to see something physical working. But for an online course they are a huge problem as you can’t possibly get hardware out to people.\nI thought about getting a BluetoothLE app but even there the hardware is a bit problematic and I’m not exactly sure what I’ll do.\nThis is indeed interesting especially for me as a guy with heavy background in robotics I just love this stuff and would love to build something cool with mindstorms and my kids. But it might be a bit too much.\nAnyway, if more people ask for it I’m game. We had a lot of interest over bluetooth and IoT recently but it was all over the place so it’s hard for me to know for sure what will work and for whom.\nSibasish Mohanty — June 22, 2017 at 11:06 am (permalink) Sibasish Mohanty says:\nHi Shai,Gr8 line of apps you suggested. I will go with the uber app as the main thing in that is map interface.And if possible can you plz give a demo chat app on firebase? And Will the uber clone will on Mapbox or Gmap?\nAndrew Nyago — June 22, 2017 at 11:31 am (permalink) Andrew Nyago says:\nsome of us from less accessible places would appreciate if some time is given for us to get access to the hardware…\nShai Almog — June 22, 2017 at 2:55 pm (permalink) Shai Almog says:\nThanks. That’s pretty much the winner so far. We will use Google Maps as that is the integration we already have.\nWe don’t currently support firebase. We have two chat demos already in the tutorials section.\nJohn Barrett — June 22, 2017 at 3:33 pm (permalink) John Barrett says:\nSounds great! Thank you sir…\nnasznjoka — June 22, 2017 at 3:48 pm (permalink) nasznjoka says:\nSports feed apps. Real time broadcasting of sports events like live score\nShai Almog — June 22, 2017 at 5:52 pm (permalink) Shai Almog says:\nThanks. I’m not really familiar with that field (not big on sports), what would that include technically?\nRSS? Audio/video streaming?\nAre there public sources I can use without violating rights? One of the problems with sports is digital rights and I don’t want to step into that mess. An RSS newsreader and streaming is interesting but I’ll need good sources/concepts for that.\nadhiguna mahendra — June 23, 2017 at 3:25 am (permalink) adhiguna mahendra says:\nDefinitely. Uber Style Taxi hailing app with complex backend logic! if you can develop this kind of app, you can build anything! me and my team developed realtime Transport Management Platform www.sealtrax.com using native Android. It’s pain. Codenameone should make our job easier.\nShai Almog — June 23, 2017 at 4:35 am (permalink) Shai Almog says:\nThat’s pretty much decided by the numbers already so it will be an Uber clone. I’m not going to do complex backend logic. I’ll keep it relatively simple in the backend. I think a lot of startups fail because they try to \u0026ldquo;build to scale\u0026rdquo; before they learn to walk…\nMy goal is to show how off the shelf stuff can be used to make something like that, but obviously on the server side once you start to scale you would also scale that architecture.\nAmuche Chimezie — June 23, 2017 at 2:07 pm (permalink) Amuche Chimezie says:\nPlease can you share any major detailed link on the social style app that can be useful to me? I seem to be lost somehow on my project.\nAmuche Chimezie — June 23, 2017 at 2:08 pm (permalink) Amuche Chimezie says:\nOpen Source please?\nAmuche Chimezie — June 23, 2017 at 2:10 pm (permalink) Amuche Chimezie says:\nCan we please consider a touch on the Social media app a little? 🙂\nShai Almog — June 24, 2017 at 5:14 am (permalink) Shai Almog says:\nThe second app after the Uber app might be a social media app based on the current voting.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/good-to-great/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/good-to-great/deep-dive-into-mobile.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThanks for all the great feedback on my \u003ca href=\"/blog/thats-great-looking-app.html\"\u003elast post\u003c/a\u003e, I got some wonderful app suggestions from some of you and some interesting questions. Overall, there were more than 100 comments and emails so I apologize if I took too long to answer some of you. I already mentioned the focus of these coming courses is to let you create apps in a more practical form: \u0026ldquo;cook book\u0026rdquo; style.\u003cbr\u003e\nBut while I talked a bit about the narrative and the course I didn’t explain exactly how or why this will work effectively.\u003c/p\u003e","title":"Getting from Good to Great"},{"content":"\n3.7 is almost here…​ Later today we will enter the week long code freeze where only critical issues are fixed. We’ll publish the plugin release candidate for 3.7 soon and it will include some interesting new things that I haven’t discussed at all!\nI’m too busy with the new courses but I hope I’ll be able to go into details with the release announcement.\nThe birthday of 3.7 will be on Tuesday June 27th…​ Up to then all new commits to git need to go thru code reviews and must match a P1 bug.\nAssuming the release candidate will become the final release all will be well, but we might need to push additional updates to fix regressions or issues so this week might include several server updates. Because of that we will skip the next two Friday releases and will push as needed. We should get back to our regular Friday updates by July 7th.\nWe might release several plugin updates in the near future to iron out bugs and regressions with the release so bare with us during this tumultuous week. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nsalah Alhaddabi — June 21, 2017 at 4:51 am (permalink) salah Alhaddabi says:\nWe are all with you and support your excellent vision Shai.\nFrancesco Galgani — June 21, 2017 at 5:22 pm (permalink) Francesco Galgani says:\nI’ve just installed the 3.7 in Netbeans.\nAt the moment is there any detailed announcement of the changes compared to the previous version?\nShai Almog — June 22, 2017 at 4:24 am (permalink) Shai Almog says:\nWe will have a release announcement with itemized details on Tuesday the 27th.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/code-freeze-for-3-7/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/code-freeze-for-3-7/codenameone-3-7.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e3.7 is almost here…​ Later today we will enter the week long code freeze where only critical issues are fixed. We’ll publish the plugin release candidate for 3.7 soon and it will include some interesting new things that I haven’t discussed at all!\u003c/p\u003e\n\u003cp\u003eI’m too busy with the new courses but I hope I’ll be able to go into details with the release announcement.\u003c/p\u003e\n\u003cp\u003eThe birthday of 3.7 will be on Tuesday June 27th…​ Up to then all new commits to git need to go thru code reviews and must match a P1 bug.\u003c/p\u003e","title":"Code Freeze for 3.7"},{"content":"\nI talk to a lot of mobile developers or those who are starting out in the field and by far the number one problem is getting a refined sublime app. There are too many difficulties and pitfalls along the way and the end result is often \u0026ldquo;sub par\u0026rdquo; in terms of the UI you want to achieve.\nWe too bare responsibility for that. We focus too much on the technology and too little on making \u0026ldquo;gorgeous\u0026rdquo; easy. I want you to join me in changing that narrative…​\nThe narrative is very common: \u0026ldquo;you can’t have it all\u0026rdquo;. You will pay for cross platform by sub par UX or UI. You will \u0026ldquo;write once debug everywhere\u0026rdquo;.\nSometimes, that narrative is true. However, when you wield the tools effectively you can get better results than any other approach…​ You can design your app once and instantly adapt it to all OS’s with native feel. You can debug \u0026amp; optimize your app once and have a more stable/faster app across all OS’s.\nIt’s not a magic bullet though. You need to learn how to wield these tools just like any tool within your toolbox and that’s where we failed you.\nWe provided JavaDocs but they are too low level and assume you already know everything.\nWe have a better developer guide but it doesn’t explain how to design a real app despite having 1000 pages of content…​\nSomething Better That’s why I started the bootcamp, I needed to learn from the participants about the pain points and difficulties. Despite having a very wide skill set disparity between the participants I saw the advanced developers and beginners run into the exact same set of difficulties.\nI’ve learned a lot. I learned how to build better course material, I understood where the main pitfalls lie in Codename One and I’ve condensed all of that together. You can see some of that work in my recent video tutorials, which are better looking and more concise.\nI’ve applied this approach into the coming course material which is already completely different from everything I did in the past.\nReal Apps This is probably the most important piece. Up until now none of our tutorials focused on creating real apps to the full extent and mostly stopped short. The closest we got was with the chat app tutorial and property cross both of which are two of our most popular tutorials.\nI think that this is the biggest missing piece in our educational stack and I think this is the piece that will help you transform your applications from good to great!\nSo here are the questions:\nWhat apps are you working on?\nWhat sort of UI or functionality are you aiming at but can’t get right?\nI want this material to be \u0026ldquo;driven\u0026rdquo; by your real world needs, not by my guessing. So please help me out with some suggestions.\nI’ve got something going and will write more about it during the week. We also have the code freeze for 3.7 which is just around the corner and we have some pretty huge surprises there! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — June 19, 2017 at 12:36 pm (permalink) Francesco Galgani says:\n«What apps are you working on?»\nA social network with all its complexities and functionallities. I need to learn how to develop both the app and the server side code.\n«What sort of UI or functionality are you aiming at but can’t get right?»\nI’m at beginning, however everything seems to me very difficult. You wrote that «We provided JavaDocs but they are too low level and assume you already know everything. We have a better developer guide but it doesn’t explain how to design a real app despite having 1000 pages of content»: it’s true. I hope that the new courses will make me able to do a real social network (like Facebook).\nDalvik — June 19, 2017 at 12:46 pm (permalink) Dalvik says:\nI’m working on a business app right now but a friend is nagging me to build an app to track the trucks for a local shipping company. I’ve done some Codename One work in the past but looking at the map API’s I’m not sure I can do that easily…\nShai Almog — June 19, 2017 at 1:15 pm (permalink) Shai Almog says:\nThanks for the feedback!\nBuilding a social network style app is indeed something I’d like to address within the course as it’s a common type of app.\nI do hope this work will make the ramp up easier.\nShai Almog — June 19, 2017 at 1:18 pm (permalink) Shai Almog says:\nThanks!\nI’ve thought about building an Uber style taxi hailing app as part of this. It sounds like this would be something similar to what you’re describing right?\nMaps are indeed a bit challenging to get into but with the new z-ordering support it should be much easier…\nDalvik — June 19, 2017 at 1:36 pm (permalink) Dalvik says:\nThanks, that sounds interesting. I remember seeing something you mentioned about z-ordering in the past. I’ll take a look at that.\nsalah Alhaddabi — June 19, 2017 at 1:38 pm (permalink) salah Alhaddabi says:\nDear Shai,\nI am planning an app to connect local customers with local merchants (somehow a mix between a social app and an eCommerce app that will help the local community nourishes their local business through requests tracking and chatting, making advance or full payments)\nfunctionalities expected:\nreal time update through web sockets, a global payment api, server push notifications, integration with Instagram, Facebook, whats app, etc…, and of course beautiful and slick design that resembles the smoothness of use of popular applications such as Yahoo Mail or Alibaba.com…\nShai Almog — June 19, 2017 at 2:04 pm (permalink) Shai Almog says:\nThanks!\nSocial style app is indeed something I’d like to introduce. I already have some discussion on websockets in the material but the current app isn’t ideal for it. I might make better use of them in an upcoming app, in fact my biggest problem wasn’t with using websockets in Codename One (that was trivial) the problem was using them in Spring Boot, it worked but it was very hard to leverage their power properly.\nI do want to build a whatsapp style chat app as one of the apps, as I said our existing chat app tutorial is one of our most popular tutorials.\nThe basic app that I already have working within the course includes payments with braintree which uses the native SDK to do so.\nmbruner63 — June 19, 2017 at 2:05 pm (permalink) mbruner63 says:\nI’m developing a BLE application to support my medical hardware. UI is the most difficult thing for me.\nCarlos — June 19, 2017 at 2:23 pm (permalink) Carlos says:\n— What apps are you working on?\nI’m working on an app for publishing companies, so they can have their magazines available with full multimedia capabilities. They optionally can take advantage of a new section with localized events.\nThis is something similar to the Restaurant app buider you have developed, but for publishing bussiness.\nThis is a working app\nAndroid: https://play.google.com/sto…\niOS: https://itunes.apple.com/us…\n— What sort of UI or functionality are you aiming at but can’t get right?\nSo far, I think I’ve got it, although the app still need some refiniment.\nMaybe transitions are sometimes difficult to get right. Ie, you have to flush a previous transitions before the next one comes into place or you can have troubles, and this is not always obvious. If the user change tabs for instance, and there is a transition going on, the app might fail.\nOther transitions are not easy to figure out. I wanted a zoom effect, something similar to bubble transition, but that is for Dialog mostly. I ended up creating a custom layout to place the zoomed component (yes, I needed absolute positioning) and animating with animateLayout. I’m happy with the results.\nOther than that, I think some elements should be modernized. The pull to refresh feature is a bit outdated and now all apps I see just bring down a styled infinite progress.\nAnd you can see cool transitions effect on modern Android apps, When swiping pictures on Whatsapp, the upcomming picture emerges from the background while sliding. I whish I could do something similar.\nShai Almog — June 19, 2017 at 4:09 pm (permalink) Shai Almog says:\nThanks for the feedback, that’s very helpful.\nI actually had that exact requirement for zoom effect. I used the morph transition which isn’t ideal but it got me something reasonable. It’s in the later portions of the course so hopefully I’ll cover that too.\nI totally agree we need better native themes especially with material design but also newer iOS elements. If you notice something specific that you feel should be modernized please just file an issue with screenshots and what you’d expect. It helps us place priorities on what we need to do otherwise we just guess about what’s important.\nShai Almog — June 19, 2017 at 4:11 pm (permalink) Shai Almog says:\nI agree. UI is a MAJOR focus here.\nMr Emma — June 19, 2017 at 4:30 pm (permalink) Mr Emma says:\nhi am almost done with an app which users would use to save money , the feature i would say we need but couldn’t implement was being able to send notifications after the app has been closed like every other android app\nShai Almog — June 19, 2017 at 7:09 pm (permalink) Shai Almog says:\nDid you try push notification?\nWe cover it in the course as well.\nSteven Mark — June 19, 2017 at 8:02 pm (permalink) Steven Mark says:\nHi there\n— What apps are you working on?\nI have an app that uses networking functionality. It fires json test requests at our API’s and receives a response.\nI then evaluate the response to determine the health of our API’s.\n— What sort of UI or functionality are you aiming at but can’t get right?\nMy app has a very basic UI – there is no animation or transition effects etc. It is just basic text fields that are populated with values which I store and fire off in the request. You would think that such an app would have no UI challenges … but it does. For example when I open a screen that contains the BODY of a POST request (which is read from a properties file), the text field appears blank. However it is not blank because when I drag my mouse over the text it highlights. And then when I click off, I can see the text.\nStill – CN1 is a great tool and I know that it is probably my lack of knowledge that is limiting me. But I am changing that!!! 🙂\nKeep up the great work\nShai Almog — June 19, 2017 at 8:47 pm (permalink) Shai Almog says:\nThanks, I highly appreciate your taking the time to comment.\nI agree that we have a lot of room to improve, especially for first time usage, default theming and learning materials.\nI think our core product is far more elaborate than many tools in our field which sometimes means we end up putting out fires in one place while not improving these things enough. Unfortunately, we depend on the community to point out some of these things and nag us to do them but since those are things that bother new users they just don’t get done…\nThe main app that will be a part of the launch is the restaurant ordering app which is an eCommerce app with payment powered by braintree. Uber, whatsapp and a social network/image manipulation app are definitely the types of applications we are looking to create in the course moving forward.\nShai Almog — June 19, 2017 at 8:48 pm (permalink) Shai Almog says:\nThanks!\nWe discuss webservices and form based UI a lot in the material.\nWhat you are describing sounds a lot like an EDT issue, we discuss that a lot in the course as well. It’s a guess though as it’s hard to tell. Try turning on the EDT violation detection in the simulator menu.\nNick Koirala — June 19, 2017 at 10:15 pm (permalink) Nick Koirala says:\nWhat apps are you working on?\nI work on a range of apps, most of the time they have relatively ‘standard’ and simple UI and I use the Flat Blue theme or similar. I like how it looks clean and simple to start with and customers and usually happy with it but I don’t like how many UIIDs need to be edited to change colours etc., (some inheritance would make it more user friendly for other UI).\nFor more complex designs provided by graphic designers I’ve only used the old GUI Designer and found it takes a lot of patience but did get a handle on how it works and can usually get a good outcome.\nWhat sort of UI or functionality are you aiming at but can’t get right?\nRecently I’ve had to make a web app which means taking a break from Codename One for one project. For this I used Vue and Vue Material and was impressed with how quick and easy it is to get a very polished material design UI using those components.\nComing back to Codename One (and trying the new Gui Builder for the first time) I notice that not only is the GUI Builder ‘quirky’ it is also complex to get the same polish and the quirks (particularly around selecting components or adding them in the right place) make it time consuming to get things right so sometimes I just give up short of the outcome I’d like. For example for I use BorderLayout and BoxLayout Y more often than any other type of layout, but all new Forms and Containers in the GUI Builder default to FlowLayout, and the highlighted component in the tree isn’t always the one that is actually selected (GUI Builder bug) so it involves a lot of clicking and fiddling around just to get layouts set, moving a component in and out of a BorderLayout container changes the layout constraints of all the other elements. The upshot of this is that when on a time and budget the layouts have to be done right and then nice polish aspects sometimes get neglected.\nI realise that this complexity in the Codename One GUI system is due to the flexibility (Vue Material can ONLY do material design components – even down to enforcing colours from the Material Design specifications) – I’m sure Codename One can produce any type of UI given time and patience.\nPerhaps a module could be developed that allows for material design components that clearly match the standards and have them as optional – I know most of my clients on Android and iOS want clean and tidy modern looking applications but don’t have extensive design requirements beyond that, simple drop in material design components would make this a breeze in Codename One, and would produce apps for me at least that would be a step up from the current theme options without adding a lot of work to each project. Its very difficult to replicate material design appearance and interactivity using the current tools.\nShai Almog — June 20, 2017 at 3:38 am (permalink) Shai Almog says:\nI very much agree with everything you said. Keep your eye open for our 3.7 announcement next week… We have big news regarding the gui builder…\nI agree we need to refine the default look/themes and bring them to the modern age. A lot of the work we did such as the RoundBorder and gradient performance improvements were infrastructure work so we can go back to the themes and remove the usage of hardcoded images within.\nMaterial design components is one of the top features in my list. Some of the developers I talked to specifically mentioned the pull to refresh component which has an outdated look. Others mentioned the OnOffSwitch and there are components that are completely missing.\nYou can help by filing issues, providing screenshots of how default apps look today or a component looks today and a screenshot of how you would expect it to look. There are so many tasks and issues we get thru every release that it’s really hard to keep an eye on the ball and these are probably the most important and relatively easy to address issues… But we need you to actually ask for that!\nShai Almog — June 20, 2017 at 3:40 am (permalink) Shai Almog says:\nI would hope you would 🙂\nJust keep an eye on what we do and help us improve by asking for things. If the look of specific things suck we would appreciate issues in the issue tracker to help us keep track of it: http://github.com/codenameo… ideally with screenshots of how the UI looks today and how it should look\nSimphiwe Twala — June 20, 2017 at 5:09 am (permalink) Simphiwe Twala says:\nI would like to know if it’s possible that when I select a new theme, the old theme and it’s related images get deleted from the GUI Builder. It’s a tedious task to get to remove these manually.\nShai Almog — June 20, 2017 at 6:15 am (permalink) Shai Almog says:\nTry Images -\u0026gt; Delete Unused Images\nSee https://www.codenameone.com…\nbryan — June 20, 2017 at 7:30 am (permalink) bryan says:\nIn terms of the whole UI/theme thing, I think you really should make it more clear to new users that the \u0026ldquo;native theme\u0026rdquo; is NOT actually native components, but a CN1 generated \u0026ldquo;look a like\u0026rdquo;. (I know you can call native, but that’s a slightly different animal). Personally, I like the fact that I can have a UI design that is invariant across platforms – I don’t really understand why people perceive that Google’s L\u0026amp;F of the month or Apple’s is the \u0026ldquo;one right way\u0026rdquo;, and people think that CN1 leads to a \u0026ldquo;lowest common denominator\u0026rdquo;, which it doesn’t because all the widgets are light weight anyway.\nnasznjoka — June 20, 2017 at 7:39 am (permalink) nasznjoka says:\nI wanted to build an app for my client. My client is a major football team and they wanted android only app but thinking ahead I rhought it would be better to do it cross platform. Then codenameone disappointed in UI so I had to go back and do a normal android app. But I’m still interested maybe you can take alook of it to see what type of UI but it’s surely material based and modern. So those are things to consider .. just like xamarin limited apis and tools for designing. My app https://play.google.com/sto…\nShai Almog — June 20, 2017 at 10:53 am (permalink) Shai Almog says:\nThanks, we try to be clear with messaging but it gets too nuanced really quickly.\nIf we say we’re not native that isn’t true because we use native themes. If we say we don’t use native widgets that’s also not true because we support embedding native widgets e.g. text edit, browser, maps, video etc. It’s really hard to explain this in a way that isn’t confusing without going into inaccurate generalizations.\nI used to refer to our approach as a \u0026ldquo;highest common denominator\u0026rdquo; where we can do stuff that’s kind of difficult to do in the regular native platform e.g. control every pixel in the screen. But that doesn’t really explain anything.\nI think we need to seriously overhaul our native themes and this is indeed a high priority moving forward.\nShai Almog — June 20, 2017 at 10:56 am (permalink) Shai Almog says:\nThanks.\nI don’t see anything special that should be hard in Codename One although the default theming might now be as nice and might require a bit of design work.\nE.g. this app was built in Codename One and has a pretty nice UI although I can think of some things I would have done differently there too: https://www.codenameone.com…\nMr Emma — June 20, 2017 at 11:17 am (permalink) Mr Emma says:\nPush Notification is very good but not exactly what we want, we want to run a service in the background that wait for the user to receive an sms when that is done a notification is sent by our app to the user to save money using our app. I hope you understand\nHousseini Moussa — June 20, 2017 at 12:11 pm (permalink) Housseini Moussa says:\nHi Shai\nWhat apps are you working on?\nI am working on an eCommerce app for pre ordering food. Here are some screen shot off the\nhttps://uploads.disquscdn.c… https://uploads.disquscdn.c… https://uploads.disquscdn.c… https://uploads.disquscdn.c… https://uploads.disquscdn.c… https://uploads.disquscdn.c… https://uploads.disquscdn.c…\nWhat sort of UI or functionality are you aiming at but can’t get right?\nMy aim is to upload image on the server side and save the image inside my database using codenameone client.(i am using glassfish 4.1 as application server and mysql as database) . If you can provide a sample that upload image and save it inside a database with java it can be gratefull for me.\nShai Almog — June 20, 2017 at 1:19 pm (permalink) Shai Almog says:\nBackground services are an Android only feature, so is grabbing SMS’s. iOS doesn’t allow those (it has background modes which is pretty different). We have some support for that but it won’t work for your use case. You can use native interfaces to do it but it doesn’t make sense in our framework as it’s purely for Android.\nShai Almog — June 20, 2017 at 1:22 pm (permalink) Shai Almog says:\nThat’s a nice looking app. Did you see this post: https://www.codenameone.com…\nThis will be the first app I’m teaching and the second app will be the builder app. It will cover image upload and mysql but I’m using Spring Boot not glassfish.\nMr Emma — June 20, 2017 at 3:47 pm (permalink) Mr Emma says:\nOur target users right now are android users so if you have any tutorial i would love to have a look at how to implement at least being able to send a notification to users via a background service . Thank you\nHousseini Moussa — June 20, 2017 at 4:32 pm (permalink) Housseini Moussa says:\nshai\nthe tutorial your are preparing is free or it was a paying bootcamp ?\nAndres Lopez — June 20, 2017 at 6:57 pm (permalink) Andres Lopez says:\nHi, I would like to see an example of how to make an app with a cloud backend. The project I was trying to do was an app that its content can be uploaded from a Web App (an admin) and the customers can see that info on mobile. Thanks!!!\nShai Almog — June 21, 2017 at 4:23 am (permalink) Shai Almog says:\nHi,\nboth of the apps at launch have a backend in the cloud. It’s unclear if you mean cloud as in server or as MBaaS like Parse. It’s something I’m thinking about discussing as well.\nShai Almog — June 21, 2017 at 4:24 am (permalink) Shai Almog says:\nWe have a native interfaces tutorial, you can proceed from there.\nShai Almog — June 21, 2017 at 4:24 am (permalink) Shai Almog says:\nBoth\nSimphiwe Twala — June 21, 2017 at 5:45 am (permalink) Simphiwe Twala says:\nThanks Shai. That just simplifies my life\nLúthien — June 21, 2017 at 8:29 am (permalink) Lúthien says:\n(Sorry – just saw that this was posted as reply on another post. Can you please move it? Thanks)\nWhat I’m working on (going to work on) is a front-end for this database: https://github.com/aduial/e…\nEldamo, the parent project, is a comprehensive dictionary of all the languages described by JRR Tolkien including grammar, phonetics and internal history. It’s being created and maintained by Paul Strack and exists basically in XML. The goal of our subproject is to parse this XML into a relational database (done) and to build a client app to use both as dictionary and utility to maintain the database with.\nI’ve considere a few different options to create this front-end. I want something cross-platform or in any case, something that’s easily recompilable for different target platforms. I’m currently considering Python \u0026amp; Divi and Java \u0026amp; Codenameone (mobile) + Java \u0026amp; Javafx (desktop).\nUnless codenameone doesn’t support embedded databases (H2 / HSQLDB / SQLite / Derby) I’ll give it a try when I’m ready.\nMr Emma — June 21, 2017 at 10:26 am (permalink) Mr Emma says:\nThank you shai, and have been a FAN of yours since LWUIT\nShai Almog — June 21, 2017 at 10:50 am (permalink) Shai Almog says:\nSure we’ve supported SQLite since 2012 and have a few tutorials on this. There is also a section in the online course about using SQLite.\nManuel Tijerino — June 22, 2017 at 6:02 pm (permalink) Manuel Tijerino says:\nHi Shai, codename one is great, some new things I would like to make is augmented reality, but need support for video stream and playback at same time. I don’t know Android or IOS so I don’t understand native code implementation too well. Thanks\nShai Almog — June 22, 2017 at 8:27 pm (permalink) Shai Almog says:\nHi,\nThis wasn’t possible in the past but is now possible thanks to peer component z-ordering. It’s mostly a matter of building a peer component that will encapsulate camera views. I’ve looked into it a bit and while it’s doable there is a lot of nuance. Since this isn’t something you can do in PhoneGap there is no plugin we can reference for ideas and it does take some work.\nI thought about doing something like this in one of the modules just teach how to build a cn1lib for camera. I looked at it and it’s got a lot of low level OS complexities so I have some concerns that this will become an iOS and Android internals tutorial but it might be worth hitting this if there is interest.\nManuel Tijerino — June 22, 2017 at 9:31 pm (permalink) Manuel Tijerino says:\nI believe developers would love this. Thank you.\nElArrepentido — June 24, 2017 at 1:39 am (permalink) ElArrepentido says:\nHello Shai:\nI am working on a consumer application that allows users to find stores and browse products. Its status is advanced but I still do not get the functionality I’m looking for.\nThe problems or needs I have are:\n–\nThe integration with Google Maps does not yet reproduce the most useful\nfeatures of that api such as Clustering, setMaxzoom, etc. Personally, I consider that CN1 has \u0026ldquo;a little bit of everything\u0026rdquo; but does not end up tackling an issue in its entirety. The interaction with Maps is very important and I consider that it\ndoes not contain all the functionalities that are necessary to develop a\ncomplete application.\n– Error control when the terminal goes offline is still rough and I do not find it very intuitive to handle such errors\n–\nIt would be very useful if they made a manual of common development\npractices with CN1 to optimize the performance and to reduce the\ndevelopment time. For example: standardize processes, have general guides of how you develop.\n– The control of font size I consider to be rather cumbersome.\n– The control of proportions in certain cases is not very friendly. For example when in the item of a list you need to establish that an\nimage adapts its height and width to the top of the item or if the item\nadapts its height to that of the image.\n– Bluetooth LE: not even if it works.\nIn summary: CN1 is a great tool and that’s why I am still subscribed\nuser, but I think that it still lacks a bit to mature and that it is\nnecessary that in its functionalities manage to simplify what with other\ncomplicated tools.\nKeep in that way!\nShai Almog — June 24, 2017 at 5:11 am (permalink) Shai Almog says:\nThanks, that’s very helpful!\n– Yes, we map the basic common use cases and move to the next task. If we’d map every potential use case for Google Maps we might not reach other tasks and might be wasting our time mapping functionality no one actually needs.\nWe implemented the original maps based on a request from an enterprise customer, Features that came later are based on user demand. If people don’t ask for stuff it will never get done and the way to ask for stuff is file an RFE in the project.\nAn even more effective way is pull request, you just implement the features you want and have them integrated into the library. One of the nice things about the maps library is that it’s relatively small and standalone. You could probably implement these features yourself in the code without knowing too much because the code is so small. If you run into issues doing it that’s exactly why we are here and we can help you with that. There were several pull requests to that library and that’s probably the best way to get a feature integrated. The whole value of a library like this is the extensibility and ability to implement stuff without our help. I know of a user who forked this lib and converted it to use a China based mapping service since Google Maps doesn’t work well there. Unfortunately he didn’t publish his work.\nI’ll be working on an Uber clone as part of these courses and if something is necessary for that common type of use case I’ll probably implement this.\n– When you go offline you can handle errors globally or locally. Our simulator includes an option to simulate slow connection and offline as well. If you have a specific example of a problem just post a question on stackoverflow and we’ll try to help you.\n– We have a performance section in the developer guide but yes I agree that the developer guide is structured more as a reference than a guide or cookbook. That’s something I hope to change with the courses which try to be more pragmatic.\n– Are you using millimeters for sizing fonts?\nWe have a lot of legacy there so the UX is awful. Select one of the native fonts and select millimeter size.\n– I’m not sure I follow the issue with the \u0026ldquo;proportions\u0026rdquo;. Are you referring to multi image, background image behaviors, scale behavior or layout. There are some nuances and they are partially mixed with legacy. We’re trying to simplify that.\n– I don’t understand the point about Bluetooth LE – that cn1lib has some issues. I think it was a mistake leaving the code too close to the original Cordova implementation as it has some issues. It’s also problematic because it doesn’t work in the simulator.\nI think there are two potential solutions one is to implement the JavaSE version of the native interfaces so it works in the simulator and the second is on device debugging. We’re working on on-device-debugging but it’s hard to know when that will launch as it’s pretty damn big.\nImplementing the JavaSE native interfaces for Bluetooth LE so you can debug in the simulator is something that community members can probably help with similarly to the work with google maps.\nI agree we could use more maturity but I think the biggest things we need to focus on are:\n– Good looking UI by default\n– GUI builder\n– Instructional materials \u0026amp; resources\n– Debugging and error handling tools\nThe cn1libs are a perfect space for the community to fill in the gaps, if we try to do too much there we end up in constant maintenance mode instead of moving the product forward as a whole.\nsao — June 24, 2017 at 6:50 pm (permalink) sao says:\nAt the moment , I am not working on any app. Though, I feel that perhaps the ones I worked on before could be improved-as regards the UI.\nThomas McNeill — September 7, 2017 at 10:01 pm (permalink) Thomas McNeill says:\nI am working on apps for athletic activities that integrate with BlueTooth. I came back to testing with CN1 when the new guibuilder came out and I think I will stick with CN1 now. Guibuilder does have some issues with navigation but it is so much better. I would like to see more themes. Even a market place for themes would be nice. I would typically purchase my app themes online via themeforest. Maybe you could work with them to create a market for them or sell them directly via this site.\nShai Almog — September 8, 2017 at 6:04 am (permalink) Shai Almog says:\nWe tried to work with themeforest but it’s a bit of a challenge as a seller in that particular marketplace.\nI think that once we improve our native themes implementing themes will become easier and we can offer a wider selection.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/thats-great-looking-app/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/thats-great-looking-app/java-for-mobile-devices1024.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI talk to a lot of mobile developers or those who are starting out in the field and by far the number one problem is getting a refined sublime app. There are too many difficulties and pitfalls along the way and the end result is often \u0026ldquo;sub par\u0026rdquo; in terms of the UI you want to achieve.\u003cbr\u003e\nWe too bare responsibility for that. We focus too much on the technology and too little on making \u0026ldquo;gorgeous\u0026rdquo; easy. I want you to join me in changing that narrative…​\u003c/p\u003e","title":"That's a Great Looking App"},{"content":"\nNetworking in Codename One includes so many different options and some very complex capabilities. This tutorial doesn’t cover all the options but it tries to clarify the logic of why we have both URL and ConnectionRequest. It also explains the socket API types and which one makes sense in which situation.\nWe also provide a couple of simple examples of REST API calls and an overview of the different ways in which REST can be implemented.\nThe recent tutorials covered a lot of basics, we’ll get into more advanced stuff in the courses and eventually after we cover the basics in these tutorials.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-networking-webservices/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-networking-webservices/learn-codenameone-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eNetworking in Codename One includes so many different options and some very complex capabilities. This tutorial doesn’t cover all the options but it tries to clarify the logic of why we have both \u003ccode\u003eURL\u003c/code\u003e and \u003ccode\u003eConnectionRequest\u003c/code\u003e. It also explains the socket API types and which one makes sense in which situation.\u003c/p\u003e\n\u003cp\u003eWe also provide a couple of simple examples of REST API calls and an overview of the different ways in which REST can be implemented.\u003c/p\u003e","title":"Tutorial: Networking and Webservices"},{"content":"\nIn the bootcamp we didn’t build just one big app, we built two…​ Or infinity…​ The first app was a restaurant ordering system that allows you to pick dishes from a menu and add them to a shopping cart. The second app was an \u0026ldquo;app builder\u0026rdquo; that allows you to customize the first app and then generate a native app based on that for your specific restaurant.\nI kept that under wraps because I wanted to do a big \u0026ldquo;launch\u0026rdquo; and release the app to the wild based on that but I ended up being so busy after the bootcamp completed that this just didn’t materialize. So instead of doing a big launch I’m doing the softest possible launch for this app. This is how the restaurant app looks, I cover its creation in the upcoming courses too:\nFigure 1. Main menu selection\nFigure 2. Edit order UI\nFigure 3. Contact us form\nWhat Next? If you own a restaurant or know someone who does and is interested in this or giving feedback by joining the beta please let us know in the website chat. Just add the email there and we’ll follow up with you.\nI’d like to make this into a real world application and part of doing that is gathering feedback from real users. Notice that billing is done thru braintree directly to your account. Since braintree only works in some countries you need to verify if works for yours, it doesn’t work for mine!\nTo check if you qualify see the braintree faq, currently these are the supported countries: United States, Canada, Australia, Europe, Singapore, Hong Kong, Malaysia, and New Zealand.\nHopefully with good feedback this app will reach production grade and serve as a good tutorial plus help restaurants get more customers. Since the code is available within the upcoming courses you could adapt this concept to build app builders for any field or product whatsoever…​ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nRoman H. — June 21, 2017 at 3:40 pm (permalink) Is this an open source project. Can we contribute ?\nShai Almog — June 22, 2017 at 4:16 am (permalink) No. It was developed as part of the bootcamp where we walked thru every step of the process.\nIt will soon be featured in the coming course material we are launching Monday\nAmuche Chimezie — June 23, 2017 at 2:40 pm (permalink) Hi Shai, Is this available now? If so, how can one access the material?\nRoman H. — June 23, 2017 at 4:11 pm (permalink) Roman H. says:\nPlease point me to a page with that course, so I can gather further info for my self.\nShai Almog — June 24, 2017 at 5:13 am (permalink) Shai Almog says:\nWe will post an announcement this Monday\nGareth Murfin — July 5, 2020 at 6:33 am (permalink) Gareth Murfin says:\nHi Shai, could you post a link to the course that contains this app? I want to sign up 🙂 Also did you link up actual payment, can users of this app actually purchase anything with their credit card? And if not what needs to be done to complete that bit? Thanks.\nShai Almog — July 6, 2020 at 5:37 am (permalink) Shai Almog says:\nIt’s here: https://codenameone.teachable.com/p/build-real-world-full-stack-mobile-apps-in-java\nThe payment is implemented on top of the braintree cn1lib \u0026lt;/blog/braintree-paypal-cn1lib/\u0026gt;\nGareth Murfin — August 4, 2020 at 5:01 pm (permalink) Gareth Murfin says:\nThanks Shai, it’s a real shame braintree only operate in a few countries. Are there any other cn1 libs that we can use that operate all over? or even http based apis that could easily be used from other companies (requiring no lib).\nShai Almog — August 5, 2020 at 2:36 am (permalink) Shai Almog says:\nIt accepts charges everywhere. However it (and stripe et. al) only work for companies in very limited locales.\nThe workaround is to open an account in the US/EU and use that for your billing. This can be done relatively easily using foreign banks operating in your country.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/restaurant-app-builder/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/restaurant-app-builder/full-stack-java-bootcamp.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIn the bootcamp we didn’t build just one big app, we built two…​ Or infinity…​ The first app was a restaurant ordering system that allows you to pick dishes from a menu and add them to a shopping cart. The second app was an \u0026ldquo;app builder\u0026rdquo; that allows you to customize the first app and then generate a native app based on that for your specific restaurant.\u003c/p\u003e\n\u003cp\u003eI kept that under wraps because I wanted to do a big \u0026ldquo;launch\u0026rdquo; and release the app to the wild based on that but I ended up being so busy after the bootcamp completed that this just didn’t materialize. So instead of doing a big launch I’m doing the softest possible launch for this app. This is how the restaurant app looks, I cover its creation in the \u003ca href=\"/blog/new-online-courses-coming-soon.html\"\u003eupcoming courses\u003c/a\u003e too:\u003c/p\u003e","title":"Restaurant App Builder"},{"content":"\nWe received some interest related to Kotlin over the past couple of years and this has risen noticeably in the past month or so. Up until now we tried to be very focused on Java which is why we didn’t add support to other JVM languages even though this shouldn’t be too hard. But Kotlins similarity to Java and its special relationship to Android make it an ideal second language for us.\nWe plan to implement Kotlin support in the \u0026ldquo;right way\u0026rdquo; and offer all the Codename One supported platforms as it would just be a Codename One project for our build process. This should work in a similar way to the Android support by allowing you to mix Kotlin sources and Java sources in a single project.\nRight now the beta is planned in the 3.8 time frame. The 3.8 release is planned for December so this will probably be out sooner.\nObviously this work will be open source and a part of our project just like the rest of Codename One.\nWhat do we Need from You? We don’t announce features so far ahead under normal circumstances but we decided to make an exception here as we will need alpha testers and we would like some feedback before we begin prototyping.\nIf you use Kotlin or are interested in picking it up we’d appreciate a few minutes to fill out this survey. You can also signup for the alpha of this support if you are interested.\nLet us know what you think in the comments. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nkutoman — June 13, 2017 at 2:20 pm (permalink) kutoman says:\ngreat news!\nChad Elofson — June 13, 2017 at 6:17 pm (permalink) Chad Elofson says:\nI would be interested in helping out.\nDon\u0026rsquo;t Bother — June 13, 2017 at 7:31 pm (permalink) Don\u0026rsquo;t Bother says:\nFrankly speaking I don’t understand how this will help you to increase adoption of C1. I mean it is still not possible to debug C1 app on iPhone and java.time is not available for C1. There are other features I would consider as more important but this is only my personal point of view.\nShai Almog — June 13, 2017 at 7:50 pm (permalink) Shai Almog says:\nThanks!\nShai Almog — June 13, 2017 at 7:59 pm (permalink) Shai Almog says:\nYou can debug on device with xcode (the generated source) which I do a lot and it’s relatively easy. We actually planned to release on device debugging for 3.7 (from Java IDE’s) but it got delayed. On device debugging is a feature that would probably take far more manpower than kotlin support. Java time is on my personal wish list too but it’s pretty low, if you want it just port this which should be pretty trivial: https://github.com/JakeWhar…\nFar more important work IMO is working on good looking UI by default and better tutorials/guides. I’m currently spending most of my time on both of those things which is why Kotlin is scheduled for later and not right now. It’s also why on device debugging isn’t getting out.\nNick Apperley — June 14, 2017 at 1:20 am (permalink) Nick Apperley says:\nSince Kotlin support will be added eventually it will be EXTREMELY IMPORTANT that the support is Kotlinic (idiomatic Kotlin/the Kotlin way of doing things). Highly recommend getting into contact with Vert.x (http://vertx.io/)) on how to add Kotlin support to a Java project. The head of the Vert.x project is Julien Viet who occasionally hangs out in Kotlin Slack on the vertx channel. Also note that Vert.x use a documentation generation system (is language agnostic), which can also generate code examples in the documentation.\nPivotal would also be another company to contact in relation to their extensive use of Kotlin, on the server-side (especially micro services) and Android throughout the company since around 2015. Currently Pivotal is the biggest Enterprise adopter of Kotlin who are similar in size to Google. Sébastien Deleuze heads the Kotlin group at Pivotal and can be found hanging out in Kotlin Slack on the spring channel.\nShai Almog — June 14, 2017 at 4:06 am (permalink) Shai Almog says:\nThanks. I’m not versed enough in Kotlin beyond the basic tutorials but won’t we get it implicitly by going thru the Kotlin compiler to bytecode and adding support for the Kotlin libraries?\nSince the starting point in Java the effort seems relatively small.\nDon\u0026rsquo;t Bother — June 15, 2017 at 4:23 am (permalink) Don\u0026rsquo;t Bother says:\nCompletely agree about nice looking UI. And kotlin support is not bringing any improvements in this area.\nI know that I can debug generated c code. However in this case the whole point of C1 is lost imho. I mean if I am comfortable with xcode and c++ I may not need another language and tools(c1). And I believe that on device debugger is more complex. My point is that adding features like kotlin support (which is not a deal breaker at all at the moment) you keep pushing on device debugger and UI improvements more and more. And imho absence of on device debugger is a deal breaker for some cases.\nShai Almog — June 16, 2017 at 6:58 am (permalink) Shai Almog says:\nYou lose a lot of the point of cn1 when you reach the actual need to debug on the device… It’s there for emergencies and should be used very rarely if at all. That’s why we have an enterprise account so when an enterprise developer runs into an issue on device we can help with that.\nNotice that when you debug the C code in xcode it’s still Java. You can see the line numbers of the Java source and map that directly, you can see the stack traces and get a picture of what failed and you can use the wonderful xcode profiling tools and see which Java method is taking up CPU/GPU/RAM. The thing is you don’t need to know C or objective-c to still get a lot from the debugger in xcode and Codename One.\nI understand your point, but it’s flawed…\n1. It assumes that if we didn’t do this then the other things we can do would be delivered quicker. That’s probably not the case. Different people, different complexities and tasks.\n2. It assumes that what’s important to you is the same as other developers. A lot of our developers are Android developers looking to migrate existing code to iOS. The moment Kotlin became an official language they want to know there is a path.\nSince Swift and Kotlin are very similar this is something we need to support to prevent leakage.\nI’m sorry if an on-device-debugger is a deal breaker for you. Unfortunately people aren’t willing to put their money where their mouth is and help support projects so they can move in the direction that they want. I’m not saying that you are like that… but here’s the thing:\nEvery single time someone said to us: \u0026ldquo;I like Codename One but I’ll use it if you just add feature X\u0026rdquo;. That person didn’t back that up…\nWe actually conducted an experiment, we picked a big feature that a lot of people asked for and got written commitments from developers saying they would upgrade if we add that feature.\nNot a single developer upgraded, not one!!!\nWhen someone says \u0026ldquo;I will buy your product if…\u0026rdquo; it’s bullshit. You might be the exception shining star on the hill that will actually take up Codename One when we do finally add on device debugging but I have no way of knowing it. So we implement features based on market research and feedback from people who are paying.\nPlease don’t be offended by this, I don’t know who you are so I have absolutely no way of qualifying your statements. It’s business practices we had to learn the hard way when running the company.\nDon\u0026rsquo;t Bother — June 16, 2017 at 2:19 pm (permalink) Don\u0026rsquo;t Bother says:\nNo worries. First of all I never wrote you that if you have feature x I will do something :-). I wrote that for some people including me ability to debug actuall application on real device is a serious concern.\nLooks like you got offended. Yes, I wrote critical remarks but I was hoping that it will not offend you. Sorry if it did.\nShai Almog — June 17, 2017 at 7:03 am (permalink) Shai Almog says:\nNo, I’m sorry. I’m just exhausted and sometimes my prickly personality comes out in a bad way.\nNot offended and I appreciate your taking the time. I do agree with most of your points 😉\nTom Tantisalidchai — June 17, 2017 at 7:30 am (permalink) Tom Tantisalidchai says:\nAwesome news!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/kotlin-wora-ios-iphone-windows-android/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/kotlin-wora-ios-iphone-windows-android/kotlin_800x320.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe received some interest related to Kotlin over the past couple of years and this has risen noticeably in the past month or so. Up until now we tried to be very focused on Java which is why we didn’t add support to other JVM languages even though this shouldn’t be too hard. But Kotlins similarity to Java and its special relationship to Android make it an ideal second language for us.\u003c/p\u003e","title":"Kotlin WORA for iOS (iPhone), Windows \u0026 Android"},{"content":"\nText input is a very special case. Besides mixing the native and Java code we also need to deal with the appearance of the virtual keyboard which doesn’t act consistently across platforms. This creates many complex edge cases that are just as problematic on native OS platforms as they are in Codename One.\nWhen we show a virtual keyboard there are two main scenarios that can take place:\nThe screen can resize to show only the relevant area\nScrolling size can increase to allow us to scroll all the way down\nBoth of these are problematic in a Dialog. The dialog can’t be properly moved once it is shown. This means that a screen resize can leave the dialog without enough space. Increased scrolling might not be enough since a dialog starts from a cramped position.\nThis is a problem that is often observed in native Android applications (not as much on iOS) where a field is unreachable when the virtual keyboard is showing.\nThese issues apply to other UI types where the text field is stuck in a position that doesn’t work well with scrolling or resizing. So you should pay attention to the behavior of the app on resize. A good approach to testing this is rotating a phone simulator which limits the height by a similar ratio. If the field isn’t easily reachable when you rotate the phone you might have a problem with a virtual keyboard too. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMartin Grajcar — November 28, 2018 at 7:06 pm (permalink) Martin Grajcar says:\nI can see that you’re right, but I can’t see any good alternative. In a form of mine, there are some 3-5 groups of 4-8 fields, which some users may want to edit, but most of the time, they won’t. So I’m planning to let the user click on a group and then edit its fields. Popping up a dialog with 4-8 text edits seems to be the natural choice. What’s the alternative? A form, which \u0026ldquo;disposes\u0026rdquo; by showBack the previous form (in exactly the same state just with the changes applied)?\nShai Almog — November 29, 2018 at 7:37 am (permalink) Shai Almog says:\nApps like Uber and other apps send you to a deeper form in the hierarchy where you can edit those specific fields. You can then save or cancel to return to the parent form. It’s a pretty common UI paradigm in mobile. You would still have the same state, you don’t need a dialog here as long as you keep the form instance.\nMartin Grajcar — November 29, 2018 at 10:30 pm (permalink) Martin Grajcar says:\nI’ve tried it, and it’s really good, except for the need to pass a Consumer\u0026lt;t\u0026gt; resultConsumer instead of getting the result directly. But I guess, there’s no other way and I can get used to it.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-dont-put-text-fields-in-dialogs/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-dont-put-text-fields-in-dialogs/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eText input is a very special case. Besides mixing the native and Java code we also need to deal with the appearance of the virtual keyboard which doesn’t act consistently across platforms. This creates many complex edge cases that are just as problematic on native OS platforms as they are in Codename One.\u003c/p\u003e\n\u003cp\u003eWhen we show a virtual keyboard there are two main scenarios that can take place:\u003c/p\u003e","title":"TIP: Don't Put Text Fields in Dialogs"},{"content":"\nStorage is one of the big subjects we can delve into and never come out. Even without going into offshoots such as parsing, networking etc. it’s still a pretty huge subject. We tried to simplify a lot of these problems by splitting file system from storage in Codename One but this often caused a different type of confusion.\nBecause I tried to keep the video very simple I also didn’t get into too many samples or variations e.g. no externalization or other interesting discussions. I specifically avoided those as with properties this becomes far easier but I also think these might make the video harder/longer.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-storage-file-system-sql/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-storage-file-system-sql/learn-codenameone-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/manual/files-storage-networking.html\"\u003eStorage\u003c/a\u003e is one of the big subjects we can delve into and never come out. Even without going into offshoots such as parsing, networking etc. it’s still a pretty huge subject. We tried to simplify a lot of these problems by splitting file system from storage in Codename One but this often caused a different type of confusion.\u003c/p\u003e\n\u003cp\u003eBecause I tried to keep the video very simple I also didn’t get into too many samples or variations e.g. no externalization or other interesting discussions. I specifically avoided those as with properties this becomes far easier but I also think these might make the video harder/longer.\u003c/p\u003e","title":"Tutorial: Storage, File System and SQL"},{"content":"\nYou might have noticed that I haven’t been committing as much code recently. It’s because I’ve been working on 3 new online Codename One courses. One of my main goals with the bootcamp was to improve my video skills and modernize course materials. I’m well on my way with both and created pretty exhaustive materials so far.\nSince these courses require a lot of work it’s hard to provide a set date for their release but I hope I’ll be able to publish at least the first two soon…​ Currently the plan is to release an introductory course, an advanced course \u0026amp; a professional app building course.\nI’m not sure if the availability announcement of these courses will be mixed with the 3.7 release announcement which we will launch by the end of June but that might be something we’ll mash together to produce the maximum effect.\nOn to 3.7 Version 3.7 will launch by the end of the month, I have high hopes that we’ll have a new GUI builder overhaul for that release although this is still under heavy development so it’s touch and go.\nThere are some things I was hoping for such as on-device-debugging which we just don’t have time to finalize for 3.7. We do have a proof of concept showing this running but it also demonstrates rather succinctly why this is a challenging feature. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMichael Lindvall — June 7, 2017 at 1:34 pm (permalink) Michael Lindvall says:\ncan’t wait for the new videos. Will this be a course on Udemy?\nShai Almog — June 7, 2017 at 2:06 pm (permalink) Shai Almog says:\nWe’re using teachable which has some advantages over Udemy. I used it in the bootcamp and generally liked it although it has its pain points. We might publish to Udemy too in the future although currently I’m inclined against that as it’s a lot of work to maintain both.\nMichael Lindvall — June 7, 2017 at 2:12 pm (permalink) Michael Lindvall says:\nawesome. I’ve never heard of teachable. I’m going to create an account so I can watch the videos when they become available.\nsalah Alhaddabi — June 12, 2017 at 5:34 am (permalink) salah Alhaddabi says:\nDear Shai, very nice to have these three courses by end of june. It will make CN1 development much easier.\nFrancesco Galgani — June 14, 2017 at 5:25 pm (permalink) Francesco Galgani says:\nI hope that the new courses will be on Youtube 🙂\nI’m a new Codename One developer, in my opinion the new GUI Builder is still unusable: thanks for your efforts to make it better 🙂\nShai Almog — June 15, 2017 at 5:15 am (permalink) Shai Almog says:\nYoutube isn’t built for that as we can’t attach additional materials, determine/track sequence and update lessons. We’ll use teachable which I used in the bootcamp and is pretty much the standard here.\nFrancesco Galgani — June 15, 2017 at 12:01 pm (permalink) Francesco Galgani says:\nOk, I get it.\nI’m watching a lot of your teaching videos on Youtube about Codename One. I need subtitles, so I use the automatic ones provided by Youtube: they are not perfect, but good and very useful for me. Could you try to enable a similar functionality on the platform in which you will publish the new courses, please?\nShai Almog — June 16, 2017 at 7:01 am (permalink) Shai Almog says:\nI don’t think most platforms have that. Some of the newer videos I’m making include slides and a transcript of my talk so you can read the text as well. Some of the things I did earlier don’t include that.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-online-courses-coming-soon/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-online-courses-coming-soon/java-for-mobile-devices1024.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eYou might have noticed that I haven’t been committing as much code recently. It’s because I’ve been working on 3 new online Codename One courses. One of my \u003ca href=\"/blog/why-bootcamp.html\"\u003emain goals with the bootcamp\u003c/a\u003e was to improve my video skills and modernize course materials. I’m well on my way with both and created pretty exhaustive materials so far.\u003c/p\u003e\n\u003cp\u003eSince these courses require a lot of work it’s hard to provide a set date for their release but I hope I’ll be able to publish at least the first two soon…​ Currently the plan is to release an introductory course, an advanced course \u0026amp; a professional app building course.\u003c/p\u003e","title":"New Online Courses – Coming Soon"},{"content":"\nA common request over the past couple of years has been to add a text field that supports a clear button in the end, we used to have a common answer on how this can be implemented but we didn’t have an actual implementation builtin despite this being a relatively common request.\nAt first I thought this is something we should implement natively but it turns out that this doesn’t exist natively in Android so we just implemented this as a wrapper to the TextField e.g. replace this:\ncnt.add(myTextField); With this:\ncnt.add(ClearableTextField.wrap(myTextField)); You can also specify the size of the clear icon if you wish. This is technically just a Container with the text field style and a button to clear the text at the edge.\nGlobal Context Update After posting about the new CN class last week we added a lot of new features into it. The API now supports capabilities from FileSystemStorage \u0026amp; Storage both of which should allow easier storage.\nWe are still a bit conflicted about some of the more elaborate API’s such as database, contacts etc.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/clearable-text-field/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/clearable-text-field/new-features-6.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA common request over the past couple of years has been to add a text field that supports a clear button in the end, we used to have a common answer on how this can be implemented but we didn’t have an actual implementation builtin despite this being a relatively common request.\u003c/p\u003e\n\u003cp\u003eAt first I thought this is something we should implement natively but it turns out that this doesn’t exist natively in Android so we just implemented this as a wrapper to the TextField e.g. replace this:\u003c/p\u003e","title":"Clearable Text Field"},{"content":"\nOne of my favorite things about Mac OS is something subtle that took me a while to notice: it doesn’t ask stupid questions. If you delete a file on a Mac it goes to the trashcan immediately, no question. Even though other OS’s copied the trashcan concept they didn’t embrace it in the same way, most of them still ask whether you are sure about this action even though the action is reversible.\nPart of the problem is in the way other OS’s work, restoring some files is not as smooth as it is in Mac OS. So I understand the timidness even though I don’t like it. There is a middle of the road approach, letting the user choose between safety and minor annoyance. It’s not the ideal approach but when you are afraid to take the full plunge of \u0026ldquo;not asking\u0026rdquo; you can use something like this to show a dialog that prompts the user but provides a \u0026ldquo;don’t ask again\u0026rdquo; checkbox:\nForm current = new Form(\u0026quot;Don't Ask Again\u0026quot;, BoxLayout.y()); Button clear = new Button(\u0026quot;Clear\u0026quot;); Button show = new Button(\u0026quot;Show Dialog\u0026quot;); clear.addActionListener(e -\u0026gt; Preferences.set(\u0026quot;dontShowDialog\u0026quot;, false)); show.addActionListener(e -\u0026gt; { boolean b = Preferences.get(\u0026quot;dontShowDialog\u0026quot;, false); if(!b) { CheckBox areYouSure = new CheckBox(\u0026quot;Don't ask again\u0026quot;); areYouSure.setUIID(\u0026quot;DialogBody\u0026quot;); SpanLabel body = new SpanLabel(\u0026quot;Are you sure you want to do this thing?\u0026quot;, \u0026quot;DialogBody\u0026quot;); Command ok = new Command(\u0026quot;OK\u0026quot;); Command cancel = new Command(\u0026quot;Cancel\u0026quot;); Command result = Dialog.show(\u0026quot;Are you Sure?\u0026quot;, BoxLayout.encloseY(body, areYouSure), new Command[] {cancel, ok}); if(result == ok) { ToastBar.showMessage(\u0026quot;OK Pressed...\u0026quot;, FontImage.MATERIAL_INFO); Preferences.set(\u0026quot;dontShowDialog\u0026quot;, areYouSure.isSelected()); } } else { ToastBar.showMessage(\u0026quot;Skipped dialog\u0026quot;, FontImage.MATERIAL_INFO); } }); current.addAll(clear, show); current.show(); This results in:\nFigure 1. Dialog with check box\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-dont-ask-again/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-dont-ask-again/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of my favorite things about Mac OS is something subtle that took me a while to notice: it doesn’t ask stupid questions. If you delete a file on a Mac it goes to the trashcan immediately, no question. Even though other OS’s copied the trashcan concept they didn’t embrace it in the same way, most of them still ask whether you are sure about this action even though the action is reversible.\u003c/p\u003e","title":"TIP: Don't Ask Again"},{"content":"\nI’ve discussed properties a couple of times before but never in a condensed video tutorial like the one we have here. In this video we review the value proposition behind properties as a step by step process.\nI hope to create more elaborate properties demos that would show off the full capabilities of this API.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-properties/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-properties/learn-codenameone-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve \u003ca href=\"/blog/properties-are-amazing.html\"\u003ediscussed properties\u003c/a\u003e a couple of times before but never in a condensed video tutorial like the one we have here. In this video we review the value proposition behind properties as a step by step process.\u003c/p\u003e\n\u003cp\u003eI hope to create more elaborate properties demos that would show off the full capabilities of this API.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"discussion\"\u003eDiscussion\u003c/h2\u003e\n\u003cp\u003e\u003cem\u003eJoin the conversation via GitHub Discussions.\u003c/em\u003e\u003c/p\u003e\n\u003cdiv class=\"cn1-giscus\"\u003e\n  \u003cscript\n    src=\"https://giscus.app/client.js\"\n    data-repo=\"codenameone/CodenameOne\"\n    data-repo-id=\"MDEwOlJlcG9zaXRvcnkzMjk3MzQ2Nw==\"\n    data-category=\"General\"\n    data-category-id=\"DIC_kwDOAfcim84B-_xx\"\n    data-mapping=\"pathname\"\n    data-strict=\"0\"\n    data-reactions-enabled=\"1\"\n    data-emit-metadata=\"0\"\n    data-input-position=\"top\"\n    data-theme=\"preferred_color_scheme\"\n    data-lang=\"en\"\n    data-loading=\"lazy\"\n    crossorigin=\"anonymous\"\n    async\u003e\n  \u003c/script\u003e\n\u003c/div\u003e","title":"Tutorial – Properties"},{"content":"\nSVG (Scalable Vector Graphics) is an XML based image format that represents an image as vectors instead of pixels (raster). An SVG file is represented by the set of lines \u0026amp; shapes that make it and can thus be rendered at any resolution without quality degradation due to scaling. It has some other neat tricks up its sleeve but I’m only going to discuss that specific feature today.\nThere was a time where everyone believed SVG will take the world by storm. It found a niche but never really created the revolution everyone expected. Still it’s a pretty valuable tool but unfortunately mobile device support is \u0026ldquo;spotty\u0026rdquo; at best…​\nAll mobile devices support SVG in the browser since it is a web standard. However, in the native layer SVG doesn’t work because of too many nuances related to the web that make it really hard to support the full spec in a native app. Android has partial SVG support where it can convert an SVG file to a native drawable during development time and that’s actually a pretty good idea as it removes the overhead of parsing SVG and the need to support the full spec.\nThis isn’t a new idea. Swing had a third party tool from Kirill Grouchnikov who implemented a static translator to generate Java2D code from the given SVG. This tool went thru a couple of forks and recently I chose to fork it myself to create a Codename One version which was surprisingly easy. Unlike the Swing version I created an Image subclass so the generated code can be used anywhere images are used.\nYou can check out my fork here it’s very experimental but if there is interest we can probably enhance it significantly. Gradients aren’t supported currently which can impact a lot of things. I think they should be doable though if we put some time into it.\nI converted a standard SVG of duke waving and showed it using this code:\nForm current = new Form(\u0026quot;SVG\u0026quot;, new BorderLayout()); current.add(CENTER, new ScaleImageLabel(new Duke_waving())); current.show(); Figure 1. Duke waving image\nYou will notice that Dukes nose isn’t red, that’s because it’s a radial gradient in the source SVG.\nThe generated Duke_waving class looks like this:\npublic class Duke_waving extends com.codename1.ui.Image implements Painter { private int width, height; public Duke_waving() { super(null); width = getOrigWidth(); height = getOrigHeight(); } public Duke_waving(int width, int height) { super(null); this.width = width; this.height = height; } @Override public int getWidth() { return width; } @Override public int getHeight() { return height; } @Override public void scale(int width, int height) { this.width = width; this.height = height; } @Override public Image fill(int width, int height) { return new Duke_waving(width, height); } @Override public Image applyMask(Object mask) { return new Duke_waving(width, height); } @Override public boolean isAnimation() { return true; } @Override public boolean requiresDrawImage() { return true; } @Override protected void drawImage(Graphics g, Object nativeGraphics, int x, int y) { drawImage(g, nativeGraphics, x, y, width, height); } @Override protected void drawImage(Graphics g, Object nativeGraphics, int x, int y, int w, int h) { float hRatio = ((float)w) / ((float)getOrigWidth()); float vRatio = ((float)h) / ((float)getOrigHeight()); int origX = g.getTranslateX(); int origY = g.getTranslateY(); g.translate(-origX, -origY); g.scale(hRatio, vRatio); int tx = (int)(((float)x) / hRatio); int ty = (int)(((float)y) / vRatio); g.translate(tx, ty); paint(g); g.resetAffine(); g.translate(origX - g.getTranslateX(), origY - g.getTranslateY()); } private static void paint(Graphics g) { int origAlpha = g.getAlpha(); Stroke baseStroke; Shape shape; g.setAntiAliased(true); g.setAntiAliasedText(true); // // _0 // _0_0 shape = new GeneralPath(); ((GeneralPath) shape).moveTo(48.859, 43.518); ((GeneralPath) shape).curveTo(57.283, 61.158, 51.595, 184.35, 41.731003, 227.55); ((GeneralPath) shape).curveTo(31.867002, 270.822, 22.003002, 325.83002, 19.699003, 372.126); ((GeneralPath) shape).curveTo(18.691004, 391.854, 21.715004, 399.63, 34.603004, 399.63); ((GeneralPath) shape).curveTo(57.355003, 399.63, 86.227005, 351.678, 122.443, 352.758); ((GeneralPath) shape).curveTo(158.731, 353.83798, 170.251, 407.766, 187.24301, 407.406); ((GeneralPath) shape).curveTo(204.23502, 407.04602, 217.91501, 401.142, 218.059, 348.654); ((GeneralPath) shape).curveTo(218.563, 191.981, 87.235, 64.973, 48.859, 43.518); ((GeneralPath) shape).lineTo(48.859, 43.518); ((GeneralPath) shape).lineTo(48.859, 43.518); ((GeneralPath) shape).lineTo(48.859, 43.518); ((GeneralPath) shape).closePath(); g.setColor(0); g.fillShape(shape); // _0_1 shape = new GeneralPath(); ((GeneralPath) shape).moveTo(162.763, 168.726); ((GeneralPath) shape).curveTo(170.755, 182.19, 191.131, 171.82199, 191.995, 156.63); ((GeneralPath) shape).curveTo(192.859, 141.438, 190.627, 122.286, 180.763, 121.56601); ((GeneralPath) shape).curveTo(170.899, 120.84601, 163.843, 110.98201, 153.979, 110.26201); ((GeneralPath) shape).curveTo(144.115, 109.54201, 133.531, 119.406006, 128.923, 106.30201); ((GeneralPath) shape).curveTo(124.315, 93.19801, 141.307, 87.65401, 153.979, 85.56601); ((GeneralPath) shape).curveTo(142.675, 74.26201, 136.05101, 61.73401, 131.08301, 48.70201); ((GeneralPath) shape).curveTo(126.115005, 35.670013, 122.44301, 23.718012, 136.339, 18.60601); ((GeneralPath) shape).curveTo(150.235, 13.494011, 149.08301, 39.77401, 164.99501, 51.79801); ((GeneralPath) shape).curveTo(160.31502, 34.086014, 158.587, 26.742012, 158.947, 16.44601); ((GeneralPath) shape).curveTo(159.307, 6.150009, 158.587, -1.6979885, 173.203, 0.31801033); ((GeneralPath) shape).curveTo(187.819, 2.3340104, 181.483, 32.71801, 192.85901, 45.102013); ((GeneralPath) shape).curveTo(196.315, 33.366013, 198.40302, 18.462013, 206.755, 12.342014); ((GeneralPath) shape).curveTo(215.107, 6.2220154, 234.115, 6.0780144, 222.01901, 31.206015); ((GeneralPath) shape).curveTo(209.92302, 56.334015, 225.54701, 69.94202, 221.87502, 89.74201); ((GeneralPath) shape).curveTo(218.20302, 109.54201, 206.82701, 105.94202, 201.93102, 118.68601); ((GeneralPath) shape).curveTo(197.03502, 131.43001, 204.81102, 160.44601, 195.59502, 173.47801); ((GeneralPath) shape).curveTo(186.37901, 186.51001, 184.72302, 206.52602, 190.69902, 222.51001); ((GeneralPath) shape).curveTo(172.339, 205.374, 162.763, 168.726, 162.763, 168.726); ((GeneralPath) shape).lineTo(162.763, 168.726); ((GeneralPath) shape).lineTo(162.763, 168.726); ((GeneralPath) shape).lineTo(162.763, 168.726); ((GeneralPath) shape).closePath(); g.fillShape(shape); // _0_2 shape = new GeneralPath(); ((GeneralPath) shape).moveTo(48.355, 185.646); ((GeneralPath) shape).curveTo(40.939, 236.478, 15.162998, 242.526, 13.867001, 263.622); ((GeneralPath) shape).curveTo(12.571001, 284.71802, 20.707, 286.734, 20.203001, 306.246); ((GeneralPath) shape).curveTo(19.699001, 325.758, 2.3470001, 333.678, 0.25900078, 344.262); ((GeneralPath) shape).curveTo(-1.8289986, 354.84598, 9.187001, 358.22998, 15.595001, 358.22998); ((GeneralPath) shape).curveTo(22.003002, 358.22998, 28.411001, 330.15, 31.003002, 312.29398); ((GeneralPath) shape).curveTo(33.595, 294.43796, 22.507002, 283.92596, 22.507002, 271.68597); ((GeneralPath) shape).curveTo(22.507002, 259.44598, 38.563004, 237.05397, 35.611, 256.70996); ((GeneralPath) shape).curveTo(48.931, 235.686, 55.268, 208.901, 48.355, 185.646); ((GeneralPath) shape).lineTo(48.355, 185.646); ((GeneralPath) shape).lineTo(48.355, 185.646); ((GeneralPath) shape).lineTo(48.355, 185.646); ((GeneralPath) shape).closePath(); g.fillShape(shape); // _0_3 shape = new GeneralPath(); ((GeneralPath) shape).moveTo(58.292, 205.013); ((GeneralPath) shape).curveTo(52.676, 232.517, 17.612, 386.09302, 35.468002, 388.037); ((GeneralPath) shape).curveTo(53.324005, 389.981, 78.740005, 340.517, 120.356, 340.87698); ((GeneralPath) shape).curveTo(162.044, 341.23697, 178.46, 396.317, 188.612, 395.95697); ((GeneralPath) shape).curveTo(198.764, 395.597, 205.45999, 399.55698, 206.54, 337.49298); ((GeneralPath) shape).curveTo(207.62, 275.429, 169.74799, 196.15698, 147.35599, 161.23698); ((GeneralPath) shape).curveTo(116.971, 163.181, 84.283, 187.518, 58.292, 205.013); ((GeneralPath) shape).lineTo(58.292, 205.013); ((GeneralPath) shape).lineTo(58.292, 205.013); ((GeneralPath) shape).lineTo(58.292, 205.013); ((GeneralPath) shape).closePath(); g.setColor(0xffffff); g.fillShape(shape); // _0_4 // _0_4_0 // _0_4_1 shape = new GeneralPath(); ((GeneralPath) shape).moveTo(147.082, 171.533); ((GeneralPath) shape).curveTo(145.42, 154.33801, 132.675, 143.545, 116.187, 140.906); ((GeneralPath) shape).curveTo(100.263, 138.35701, 82.927, 145.904, 71.77899, 157.052); ((GeneralPath) shape).curveTo(59.24099, 169.59, 58.73999, 187.03, 67.51899, 201.88501); ((GeneralPath) shape).curveTo(76.17999, 216.542, 95.36599, 221.38602, 111.081985, 217.72002); ((GeneralPath) shape).curveTo(132.588, 212.705, 148.48, 193.896, 147.082, 171.533); g.setColor(0); g.fillShape(shape); // _0_4_2 shape = new GeneralPath(); ((GeneralPath) shape).moveTo(139.162, 177.941); ((GeneralPath) shape).curveTo(137.669, 193.568, 125.215004, 206.12299, 110.218, 209.765); ((GeneralPath) shape).curveTo(94.348, 213.619, 76.825, 207.508, 71.122, 191.189); ((GeneralPath) shape).curveTo(68.21, 182.857, 68.752, 174.31, 73.759, 166.991); ((GeneralPath) shape).curveTo(77.982, 160.81999, 84.792, 155.991, 91.538, 152.925); ((GeneralPath) shape).curveTo(105.462006, 146.599, 125.37, 145.896, 135.069, 160.002); ((GeneralPath) shape).curveTo(138.744, 165.348, 139.387, 171.641, 139.162, 177.941); g.setColor(0xffffffff); g.fillShape(shape); g.setColor(0); baseStroke = new Stroke(1, 0, 0, 4); g.drawShape(shape, baseStroke); g.setAlpha(origAlpha); g.resetAffine(); } /** * Returns the X of the bounding box of the original SVG image. * * @return The X of the bounding box of the original SVG image. */ public static int getOrigX() { return 0; } /** * Returns the Y of the bounding box of the original SVG image. * * @return The Y of the bounding box of the original SVG image. */ public static int getOrigY() { return 0; } /** * Returns the width of the bounding box of the original SVG image. * * @return The width of the bounding box of the original SVG image. */ public static int getOrigWidth() { return 226; } /** * Returns the height of the bounding box of the original SVG image. * * @return The height of the bounding box of the original SVG image. */ public static int getOrigHeight() { return 408; } @Override public void paint(Graphics g, Rectangle rect) { drawImage(g, null, rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()); } } SVG vs. Font Icons/Material Fonts You can’t color SVG’s dynamically and they will probably never match the speed/convenience of font icons. For most use cases you should probably use the font icons or material icons. However, if you need a design element or icon that is vector based and has multiple colors this might be an interesting option.\nIn terms of performance it’s hard to know how well SVG will perform. If you have an image with a fixed size on device you can just convert it to a raster in runtime and use that to avoid potential performance overhead.\nMoving Forward This depends a lot on demand/pull requests and needs. Supporting gradients will open up a lot of use cases.\nIt might be interesting to allow manipulation of some SVG object states as well…​ This might be required if we want to support SVG animations which would provide a great deal of benefit e.g. for animations in the style of Androids menu button animating to a back button etc. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — November 20, 2017 at 4:56 pm (permalink) I’m interested in converting an svg scalable logo to Codename One code, but… is the link you provided correct? There is no mention of Codename One:\nhttps://github.com/ebourg/f…\nShai Almog — November 21, 2017 at 12:33 pm (permalink) Ugh, thanks! It’s http://github.com/codenameo…\nI’ll fix it in the post.\nAngelo — June 23, 2020 at 5:31 pm (permalink) Angelo says:\nIf I understand, the utility converts an SVG file that uses a reduced set of features to real Java code. Is it possible just to create a XML file to be loaded from resources with curves, lines, moves and so on? You could create a class like ImageFromSVGSubset and instances would be created with sort of new ImageFromSVGSubset(\u0026ldquo;id\u0026rdquo;). The xml has not to be an official format, just used by developers in Codename One that want to use the transcoder and that know what they are doing. I think it should take just one hour of development for you, starting from the current fork.\nShai Almog — June 24, 2020 at 2:45 am (permalink) Shai Almog says:\nNo it’s harder.\nAngelo — June 24, 2020 at 7:11 am (permalink) Angelo says:\nI take the occasion to inform you about a bug. In the code this line is encountered:\nshape = new Rectangle2D.Double(0.008569182828068733, 0.0054579987190663815, 6.3905863761901855, 6.390747547149658);\nSome characters from a method signature went into the output.\nI had to manually fix it but it is a minor thing.\nI had problems in some cases with the paint method that is annotated @Override\nThank you.\nDurank — October 21, 2020 at 3:20 pm (permalink) Durank says:\nPlease provide a solutions to use SVG images more easy.\nDurank — October 21, 2020 at 4:33 pm (permalink) Durank says:\nI did all steps in the flamingo page and I can’t see the generated java code to my svg image\nShai Almog — October 22, 2020 at 10:48 am (permalink) Shai Almog says:\nDoes it print out that it’s processing the SVGs? What’s printed?\nDuran k — October 22, 2020 at 3:10 pm (permalink) Duran k says:\nnothing\nMicrosoft Windows [Version 10.0.19041.572]\n(c) 2020 Microsoft Corporation. All rights reserved.\nC:Usersdesarrollo1\u0026gt;cd F:data_kdpprogramsCodenameOneutils_programssvg\nC:Usersdesarrollo1\u0026gt;f:\nF:data_kdpprogramsCodenameOneutils_programssvg\u0026gt;dir\nVolume in drive F is data_kdp\nVolume Serial Number is 48F9-3B10\nDirectory of F:data_kdpprogramsCodenameOneutils_programssvg\n21/10/2020 12:38 p. m. .\n21/10/2020 12:38 p. m. ..\n20/10/2020 10:47 a. m. 38,154 automobile_automotive_car.svg\n21/10/2020 12:38 p. m. ebourg-flamingo-svg-transcoder-1.2-3-gc12f421\n21/10/2020 12:38 p. m. 398,372 ebourg-flamingo-svg-transcoder-1.2-3-gc12f421.zip\n21/10/2020 11:25 a. m. 2,948,454 flamingo-svg-transcoder-core-1.2-jar-with-dependencies.jar\n21/10/2020 11:35 a. m. 4,642,088 fondo.svg\n21/10/2020 12:06 p. m. 50,833 method-draw-image.svg\n21/10/2020 12:23 p. m. myfiles\n5 File(s) 8,077,901 bytes\n4 Dir(s) 111,844,356,096 bytes free\nF:data_kdpprogramsCodenameOneutils_programssvg\u0026gt;java -jar flamingo-svg-transcoder-core-1.2-jar-with-dependencies.jar /myfiles fondo.svg\nF:data_kdpprogramsCodenameOneutils_programssvg\u0026gt;\nShai Almog — October 23, 2020 at 6:53 am (permalink) Shai Almog says:\nThe arguments should be the current directory followed by package name. So something like:\n\u0026ldquo; . com.mypackage.svg \u0026quot;\nDuran k — October 23, 2020 at 6:30 pm (permalink) Duran k says:\nI don’t know what is the package name that you said. This documentation isn’t very clear. Please provide a Documentation more clear.\nShai Almog — October 24, 2020 at 5:38 am (permalink) Shai Almog says:\nIt’s your package name. This is a code generator. It generates source code to a specific package name.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/flamingo-svg-transcoder/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/flamingo-svg-transcoder/uidesign.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSVG (Scalable Vector Graphics) is an XML based image format that represents an image as vectors instead of pixels (raster). An SVG file is represented by the set of lines \u0026amp; shapes that make it and can thus be rendered at any resolution without quality degradation due to scaling. It has some other neat tricks up its sleeve but I’m only going to discuss that specific feature today.\u003c/p\u003e","title":"Flamingo SVG Transcoder"},{"content":"\nA developer recently asked me why Display is called Display when it has such a broad purpose?\nThe reason is historic with roots in Codename One’s origin back in 2007, when we formed the company Chen advocated for a rename of that class and I disagreed. In retrospect I was wrong, the name doesn’t work.\nThis isn’t something we can easily fix but it’s something we can replace and improve…​\nStatic Context When we released Codename One’s first beta almost everything was different but two huge differences matter for this post:\nWe only supported JDK 1.3 era CLDC subset\nWe used XMLVM which didn’t implement static methods very efficiently\nBoth of these are no longer correct. Under ParparVM static methods perform better than instance methods (as they should) and we always use Java 8 syntax. This means that classes like Display which works as a singleton are at a disadvantage when compared to a class where all the methods are static. In such a class the performance will be faster:\nWe remove the getInstance() call\nA single static call is faster than an instance method call\nBut there is another advantage of shorter syntax, e.g. instead of doing something like:\nint width = Display.getInstance().getDisplayWidth(); We could (theoretically) do:\nint width = Display.getDisplayWidth(); But that’s not all, static methods have the advantage of newer Java static import syntax which allows us to add one import statement:\nimport static com.codename1.ui.Display.*; Then write something like:\nint width = getDisplayWidth(); Why do it in Display? Adding something like this into Display doesn’t make sense…​ It would make that class huge and just persist a design mistake from years ago. It’s better to start with a new global context class that will provide us static methods for all the common things we need where it’s common constants or NetworkManager methods etc.\nThis doesn’t deprecate Display (yet), it provides a better approach for doing the things we do today in Display with the new CN class. It also adds common methods \u0026amp; constants from several other classes so Codename One code will feel more terse e.g. once we do:\nimport static com.codename1.ui.CN.*; __ That’s optional, if you don’t like static imports you can just write CN. for every element From that point on you can write code that looks like this:\ncallSerially(() -\u0026gt; runThisOnTheEDT()); Instead of:\nDisplay.getInstance().callSerially(() -\u0026gt; runThisOnTheEDT()); The same applies for most network manager calls e.g.:\naddToQueue(myConnectionRequest); Some things were changed so we won’t have too many conflicts e.g. Log.p or Log.e would have been problematic so we now have:\nlog(\u0026quot;my log message\u0026quot;); log(myException); Instead of Display.getInstance().getCurrent() we now have getCurrentForm() since getCurrent() is too generic. But for most methods you should just be able to remove the NetworkManager or Display access and it should \u0026ldquo;just work\u0026rdquo;.\nI ported the Kitchen Sink to use this new convention, to see a sample of how this can cut down on code clutter check of this diff of my commit.\nThe motivation for this change is three fold:\nTerse code\nSmall performance gain\nCleaner API without some of the baggage in Display or NetworkManager\nBoth of these classes will probably be around and won’t be deprecated any time soon. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDiamond — May 30, 2017 at 3:13 pm (permalink) Diamond says:\nGreat improvement! How about changing CN to CN1 to actually read more like the platform name?…since this is a major class most CN1 developers will be calling to perform some generic tasks.\nShai Almog — May 31, 2017 at 4:41 am (permalink) Shai Almog says:\nI actually started with CN1 as I had a similar thought process. After wrestling with it a bit I eventually settled on CN. My reasoning for this is 4 fold:\n1. Not a fan of numbers in class names.\n2. It’s slightly shorter which isn’t much but still…\n3. It’s not about the brand name it’s just a class name and calling it CN keeps it simple\n4. We might change our name under a future rebrand. E.g. on iOS NSString is cemented because of NextStep. I don’t mind having a CN class to mark the history but a CN1 class might be too much.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/static-global-context/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/static-global-context/new-features-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA developer recently asked me why \u003ccode\u003eDisplay\u003c/code\u003e is called \u003ccode\u003eDisplay\u003c/code\u003e when it has such a broad purpose?\u003cbr\u003e\nThe reason is historic with roots in Codename One’s origin back in 2007, when we formed the company Chen advocated for a rename of that class and I disagreed. In retrospect I was wrong, the name doesn’t work.\u003c/p\u003e\n\u003cp\u003eThis isn’t something we can easily fix but it’s something we can replace and improve…​\u003c/p\u003e","title":"Static Global Context"},{"content":"\nImage masking allows us to adapt an image which we acquired from an external source to fit our design e.g. if we want to show an image cropped to a circle we could apply a mask to it in order to get an intelligent crop. This is a very powerful tool as a designer can supply a hardcoded mask image and build some pretty complex shapes that include an alpha channel as well (making it superior to shape clipping).\nThe most simple type of image masking can be achieved using code like this taken from this old post:\ntry { int width = Display.getInstance().getDisplayWidth(); Image capturedImage = Image.createImage(Capture.capturePhoto()).fill(width, width); Image roundMask = Image.createImage(width, capturedImage.getHeight(), 0xff000000); Graphics gr = roundMask.getGraphics(); gr.setColor(0xffffff); gr.setAntiAliased(true); gr.fillArc(0, 0, width, width, 0, 360); Object mask = roundMask.createMask(); capturedImage = capturedImage.applyMask(mask); result.setIcon(capturedImage); } catch(IOException err) { Log.e(err); } __ I made some minor improvements to the code Masking Approaches There are several other ways to implement masking besides the low level approach illustrated above\nURLImage Masking URLImage can be created with a mask. Since masking replaces the underlying image with the masked image if you would use it with a URLImage you would effectively lose the implicit download functionality of the URLImage. The builtin masking allows us to workaround that behavior and still apply a mask to an image that is fetched implicitly.\nTo paraphrase the previous example this can be used like:\nImage roundMask = Image.createImage(placeholder.getWidth(), placeholder.getHeight(), 0xff000000); Graphics gr = roundMask.getGraphics(); gr.setColor(0xffffff); gr.setAntiAliased(true); gr.fillArc(0, 0, placeholder.getWidth(), placeholder.getHeight(), 0, 360); URLImage.ImageAdapter ada = URLImage.createMaskAdapter(roundMask); Image i = URLImage.createToStorage(placeholder, \u0026quot;fileNameInStorage\u0026quot;, \u0026quot;http://xxx/myurl.jpg\u0026quot;, ada); Theme Masking Label and its subclasses can have a mask associated with an icon thru a theme constant. This means that all images set to the given icon will be implicitly masked within the set method. That can be very convenient as it allows us to decouple the masking behavior into the theme rather than code it into the application. However, as stated above this won’t work with tools such as URLImage.\nTo apply a theme mask we define a theme constant image representing the mask and then invoke Label.setMaskName(String) with the name of the theme constant. We can also set the mask object directly into the label which can be very beneficial.\nThe SocialBoo demo uses this approach to round up the images of the avatars using rounded borders…​\nPerformance Tradeoffs Masking is expensive, it works by literally reviewing every pixel in the mask against every pixel in the image to apply alpha. Applying a mask during rendering is prohibitively expensive.\nURLImage solves this by applying the mask as the image data is downloaded. It saves an image object with the mask already applied thus removes the cost of masking from future usage. It does make a tradeoff of encoding and saving the image which is more expensive than just saving the image but that benefits future executions. Other mask types don’t have that level of seamless usage. E.g. when we use the mask builtin to label we might run into a performance overhead if we call setIcon on more than one occasion.\nWe might also trigger a performance issue when invoking setIcon in a performance critical section of the code. E.g. if we optimize performance by lazily loading images while scrolling this masking might produce an overhead. It’s important to be vigilant when you apply masking to elements so you don’t do it more than once. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nClipping Creations India — January 11, 2018 at 11:18 am (permalink) Clipping Creations India says:\nHi Shai Almog, you have mentioned important tips about image masking. Great job.\nAR Khan — February 9, 2018 at 8:12 am (permalink) AR Khan says:\nThis is a very good and more necessary idea that you have explained here. thank you for this best resources\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-understand-image-masking-performance/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-understand-image-masking-performance/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/blog/round-at-codemotion.html\"\u003eImage masking\u003c/a\u003e allows us to adapt an image which we acquired from an external source to fit our design e.g. if we want to show an image cropped to a circle we could apply a mask to it in order to get an intelligent crop. This is a very powerful tool as a designer can supply a hardcoded mask image and build some pretty complex shapes that include an alpha channel as well (making it superior to shape clipping).\u003c/p\u003e","title":"TIP: Understand Image Masking Performance"},{"content":"\nTheming allows us to adapt the look of an application in a similar way to CSS while styling allows us to do so within the code. In this tutorial I cover only a small fraction of the subject matter but after going thru it you should have a decent understanding of the forces at play and the tools you can use.\nI didn’t cover many crucial subjects such as borders (9-piece or otherwise), backgrounds, in place style editing or many other things. All of these things are worth knowing and understanding and hopefully will be covered in a future video individually.\n__ We already have a relatively old 9-piece border video What I did cover is the basics of how theming works across platforms. How to apply various styles, colors, fonts etc. I explain padding/margin and a few other things:\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-theming-basics/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-theming-basics/learn-codenameone-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eTheming allows us to adapt the look of an application in a similar way to CSS while styling allows us to do so within the code. In this tutorial I cover only a small fraction of the subject matter but after going thru it you should have a decent understanding of the forces at play and the tools you can use.\u003c/p\u003e\n\u003cp\u003eI didn’t cover many crucial subjects such as borders (9-piece or otherwise), backgrounds, \u003ca href=\"/blog/edit-styles-simulator.html\"\u003ein place style editing\u003c/a\u003e or many other things. All of these things are worth knowing and understanding and hopefully will be covered in a future video individually.\u003c/p\u003e","title":"Tutorial – Theming Basics"},{"content":"\nUntil this weeks release push notification was registered using Display.registerPush(Hashtable, boolean) the thing is that both of these arguments to that method are no longer used or not the best way to implement registration. So we deprecated that method and introduced a new version of the method Display.registerPush().\nSince push fallback hasn’t been supported since we migrated to the new API it’s going away isn’t a big deal but up until recently the Hashtable argument was used to pass the GCM push ID.\n__ This is pretty old code from before our migration to Java 5 so it used Hashtable, we since migrated all the way to Java 8 To include the Android push id we should now use the build hint gcm.sender_id which will work for Chrome JavaScript builds too and is probably the better approach overall.\nSplitPane Steve recently introduced a cool new split pane component to Codename One which is a long time request from many users:\nWe didn’t add it in the past because it’s so desktop specific but now that we have the JavaScript port and it makes more sense. To get the video above I changed SalesDemo.java in the kitchen sink by changing this:\nprivate Container encloseInMaximizableGrid(Component cmp1, Component cmp2) { GridLayout gl = new GridLayout(2, 1); Container grid = new Container(gl); gl.setHideZeroSized(true); grid.add(encloseInMaximize(grid, cmp1)). add(encloseInMaximize(grid, cmp2)); return grid; } To:\nprivate Container encloseInMaximizableGrid(Component cmp1, Component cmp2) { return new SplitPane(SplitPane.VERTICAL_SPLIT, cmp1, cmp2, \u0026quot;25%\u0026quot;, \u0026quot;50%\u0026quot;, \u0026quot;75%\u0026quot;); } This is mostly self explanatory but only \u0026ldquo;mostly\u0026rdquo;. We have 5 arguments the first 3 make sense:\nSplit orientation\nComponents to split\nThe last 3 arguments seem weird but they also make sense once you understand them, they are:\nThe minimum position of the split – 1/4 of available space\nThe default position of the split – middle of the screen\nThe maximum position of the split – 3/4 of available space\nThe units don’t have to be percentages they can be mm (millimeters) or px (pixels).\nMouse Cursor You might have noticed the video above was shot in the simulator, one of the tell tale signs is the mouse cursor.\nIf you paid attention you might have noticed the cursor changed its appearance when I was hovering over specific areas to indicate resizability on the Y axis. This is a new feature in Codename One that’s available in the desktop and JavaScript port. It’s off by default and needs to be enabled on a Form by Form basis using Form.setEnableCursors(true);. If you are writing a custom component that can use cursors such as SplitPane you can use:\n@Override protected void initComponent() { super.initComponent(); getComponentForm().setEnableCursors(true); } Once this is enabled you can set the cursor over a specific region using cmp.setCursor() which accepts one of the cursor constants defined in Component.\nFuture Desktop We have a lot of plans for improving the desktop/web support in Codename One moving forward but these specific features are a part of a specific set of changes going into the new GUI builder.\nI don’t think this is the time to share too much but Steve has been working on some GUI builder changes that we are all pretty excited about. We want these changes to be great on launch and not something we constantly tune so they might take some time. I hope they will land in 3.7 but I’d rather we launch them after if we can’t get them to the place where they should be…​ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nNick Koirala — May 24, 2017 at 10:13 pm (permalink) Nick Koirala says:\nI like the simplified push registration with a build hint as the old way wasn’t intuitive enough for me to implement without looking it up every time. Is there a way to set then sender id programatically? One of my projects uses the process described here: https://www.codenameone.com… and currently the gcm sender id is also set in the overridden code.\nShai Almog — May 25, 2017 at 4:28 am (permalink) Shai Almog says:\nIf you do that then having the gcm value within the properties will easily allow you to adapt everywhere. The main motivation for using the build hint is chrome where is needed in a separate file whose loading we can’t control.\nRaffic — July 26, 2017 at 1:38 pm (permalink) Raffic says:\nHello Shai,\nIt seems the Android SDK does not support firebase Analytics. i am building an android application that uses the firebase analytics.When will the SDK be upgraded to support firebase.\nShai Almog — July 28, 2017 at 4:28 am (permalink) Shai Almog says:\nHi,\nfirebase is currently not on our priority list. Supporting analytics or any other API from there will require some effort and limit us to Android/iOS only. Unfortunately Google has a proven track record of canceling projects they were previously bullish on so we have serious reservations on support for firebase.\nArticles like this don’t exactly raise the confidence level https://medium.com/@contact…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/splitpane-cursors-push-registration/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/splitpane-cursors-push-registration/new-features-6.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eUntil this weeks release push notification was registered using \u003ccode\u003eDisplay.registerPush(Hashtable, boolean)\u003c/code\u003e the thing is that both of these arguments to that method are no longer used or not the best way to implement registration. So we deprecated that method and introduced a new version of the method \u003ccode\u003eDisplay.registerPush()\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eSince push fallback hasn’t been supported since we migrated to the new API it’s going away isn’t a big deal but up until recently the \u003ccode\u003eHashtable\u003c/code\u003e argument was used to pass the GCM push ID.\u003c/p\u003e","title":"SplitPane, Cursors and Push Registration"},{"content":"\nOne of the key takeaways I have from the bootcamp is the need to work on TDD in Codename One. We had a test framework and test recording framework for years, but it wasn’t picked up by many developers and as such it stagnated. As we launched the Toolbar API we didn’t even check that framework and some basic stuff stopped working.\nThis was something several attendants in the bootcamp mentioned as important as well as a couple of enterprise customers so I knew we had to revisit this feature. With this weeks update commands should be handled correctly even with a toolbar and features such as \u0026ldquo;wait for title\u0026rdquo; should work for a form with a Toolbar. I’d still recommend using setName() for any component you want to test as this will make the generated code far clearer to the human observer when you record a test.\nBut first lets take a step back and review the process to record a test again. If you have an app you wish to test you can just open the test recorder thru the Test Recorder menu option:\nFigure 1. Test recorder menu option\nFigure 2. The test recorder UI during recording\nWhen you press the record button in the test recorder UI you will instantly see the skeleton test class generated. You can then just use the app as normal and most of the features should instantly generate themselves into the test case.You can use the assert buttons to generate assertions of values and press the save button when you are done.\nOnce the file is saved you can edit it the tests directory and run it via the Run Tests option in the Codename One menu or the standard Test option (this is IDE dependent).\nWhile we fixed a lot of things in the test recorder it might still generate problematic code especially in the \u0026ldquo;wait for X\u0026rdquo; logic which might cause a test to fail because we don’t wait enough for something to occur. If you run into such issues or inexplicable failures please let us know.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/test-recorder-toolbar/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/test-recorder-toolbar/quality.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the key takeaways I have from the bootcamp is the need to work on TDD in Codename One. We had a test framework and test recording framework for years, but it wasn’t picked up by many developers and as such it stagnated. As we launched the \u003ccode\u003eToolbar\u003c/code\u003e API we didn’t even check that framework and some basic stuff stopped working.\u003c/p\u003e\n\u003cp\u003eThis was something several attendants in the bootcamp mentioned as important as well as a couple of enterprise customers so I knew we had to revisit this feature. With this weeks update commands should be handled correctly even with a toolbar and features such as \u0026ldquo;wait for title\u0026rdquo; should work for a form with a \u003ccode\u003eToolbar\u003c/code\u003e. I’d still recommend using \u003ccode\u003esetName()\u003c/code\u003e for any component you want to test as this will make the generated code far clearer to the human observer when you record a test.\u003c/p\u003e","title":"Test Recorder and Toolbar"},{"content":"\nTracking \u0026amp; logging errors is crucial for a stable application. There are several tools we offer in Codename One both in the seamless level (crash protection) and in the lower level inner workings of Codename One. I’ll try to explain both and how they interact.\nWhen you create a new Codename One application you might notice this line of code:\nLog.bindCrashProtection(true); This code binds the pro crash protection feature that will implicitly send you an email whenever the app crashes or has an exception. This email will include the stack trace and other output you wrote to the console using Log.p().\nThe argument to that method indicates whether the error should be swallowed or kept. When set to true the error is consumed and the user will be unaware that an exception occurred, this can be problematic in some cases as failure might be hard to track.\nHow does it Work? The code for bindCrashProtection looks like this:\npublic static void bindCrashProtection(final boolean consumeError) { if(Display.getInstance().isSimulator()) { return; } Display.getInstance().addEdtErrorHandler(new ActionListener() { public void actionPerformed(ActionEvent evt) { if(consumeError) { evt.consume(); } p(\u0026quot;Exception in \u0026quot; + Display.getInstance().getProperty(\u0026quot;AppName\u0026quot;, \u0026quot;app\u0026quot;) + \u0026quot; version \u0026quot; + Display.getInstance().getProperty(\u0026quot;AppVersion\u0026quot;, \u0026quot;Unknown\u0026quot;)); p(\u0026quot;OS \u0026quot; + Display.getInstance().getPlatformName()); p(\u0026quot;Error \u0026quot; + evt.getSource()); if(Display.getInstance().getCurrent() != null) { p(\u0026quot;Current Form \u0026quot; + Display.getInstance().getCurrent().getName()); } else { p(\u0026quot;Before the first form!\u0026quot;); } e((Throwable)evt.getSource()); sendLog(); } }); crashBound = true; } The first interesting thing you will notice above is: addEdtErrorHandler which is a listener on the Display class. It allows us to to receive an event when the EDT catches an exception. All exceptions on the EDT are caught, we try to recover from them.\nThe default behavior is to show an error dialog but if we consume the event that error dialog won’t show.\nThe second interesting piece of code is sendLog();, this method sends the log to the email of the user who built the app. This method will only work for a pro account. You can invoke that method manually and create custom versions of this error handling logic.\nNotice that we also add implicit calls to send log if you get an exception in other threads if crash protection is bound, that means that some other unexpected crashes might be detected by such code.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-handle-edt-errors/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-handle-edt-errors/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eTracking \u0026amp; logging errors is crucial for a stable application. There are several tools we offer in Codename One both in the seamless level (crash protection) and in the lower level inner workings of Codename One. I’ll try to explain both and how they interact.\u003c/p\u003e\n\u003cp\u003eWhen you create a new Codename One application you might notice this line of code:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eLog.bindCrashProtection(true);\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis code binds the pro crash protection feature that will implicitly send you an email whenever the app crashes or has an exception. This email will include the stack trace and other output you wrote to the console using \u003ccode\u003eLog.p()\u003c/code\u003e.\u003c/p\u003e","title":"TIP: Handle EDT Errors"},{"content":"\nLayouts are one of the hardest subjects to grasp in Codename One, there is a lot of nuance in getting layouts \u0026ldquo;right\u0026rdquo;. Since the subject is so vast and complex this video only scratches the surface and is still relatively long for an introductory video. It’s crucial to go thru this material though if you are not familiar with layouts or find them confusing.\nIdeally, I’ll follow up with a more \u0026ldquo;pragmatic\u0026rdquo; video of layouts that will build on top of this video to explain how common layouts are achieved.\nTo learn more about layouts you can check out the layout gallery in the JavaDocs and dig into an individual layout. Because this is very heavily documented I didn’t add additional writeup besides the video.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-layout-basics/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-layout-basics/learn-codenameone-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eLayouts are one of the hardest subjects to grasp in Codename One, there is a lot of nuance in getting layouts \u0026ldquo;right\u0026rdquo;. Since the subject is so vast and complex this video only scratches the surface and is still relatively long for an introductory video. It’s crucial to go thru this material though if you are not familiar with layouts or find them confusing.\u003c/p\u003e\n\u003cp\u003eIdeally, I’ll follow up with a more \u0026ldquo;pragmatic\u0026rdquo; video of layouts that will build on top of this video to explain how common layouts are achieved.\u003c/p\u003e","title":"Tutorial – Layout Basics"},{"content":"\nRecently I sent a build and had an issue installing it. It was late at night and I just forgot to add the build hint ios.debug.archs=armv7 for installation on the 3rd gen iPad I was testing with. So we can all trip over basic mistakes when it comes to iOS installs. So for your convenience I made a list of common pitfalls you might run into if your iOS build won’t install on your device.\nIf you have access to a Mac you can connect a cable and open xcode where you can use the device explorer console to look at messages which sometimes give a clue about what went wrong. If not here is a laundry list of a few things that might fail:\nMake sure you built the debug version and not the appstore version. The appstore version won’t install on the device and can only be distributed via Apple’s store or testflight\nVerify that you are sending a 32 bit build in the build hints using the build hint ios.debug.archs=armv7. It’s only necessary if you have an older 32 bit device, see this. Notice that this only applies for debug builds, release builds include both 32 and 64 bit versions\n__ Devices prior to iPad Air \u0026amp; iPhone 5s were 32 bit devices so iPhone 5s won’t need that flag but iPhone 5 or iPhone 5c will need it Check the the UDID is correct – if you got the UDID from an app then it’s probably wrong as apps don’t have access to the device UDID anymore. The way to get the UDID is either thru iOS Settings app or itunes\nMake sure the device isn’t locked for installing 3rd party apps. I’ve had this when trying to install on my kids tablet which I configured to be child safe. This is configured in the settings as parental controls\nCheck that you \u0026ldquo;own\u0026rdquo; the package name. E.g. if you previously installed an app with the same package name but a different certificate a new install will fail (this is true for Android too). So if you installed the kitchen sink from the store then built one of your own and installed it there will be a collision.\nNotice that this might be problematic if you use overly generic package names as someone else might have used them which is why you must always use your own domain\nMake sure the device has a modern enough version of iOS for the dependencies. I think the current minimum for hello world is 6.0.1 but some apps might require a newer version e.g. Intercom requires OS 8 or newer\nVerify that you are using Safari when installing on the device (if you tried via cable that’s not a problem), some developers had issues with firefox not launching the install process\nCheck that the build hint ios.includePush is set in a way that matches your iOS provisioning. So it must be false if you don’t have push within the provisioning profile\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/my-ios-build-wont-install/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/my-ios-build-wont-install/generic-java-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eRecently I sent a build and had an issue installing it. It was late at night and I just forgot to add the build hint \u003ccode\u003eios.debug.archs=armv7\u003c/code\u003e for installation on the 3rd gen iPad I was testing with. So we can all trip over basic mistakes when it comes to iOS installs. So for your convenience I made a list of common pitfalls you might run into if your iOS build won’t install on your device.\u003c/p\u003e","title":"My iOS Build Won't Install"},{"content":"\nThis feature is still undergoing development but I wanted to share the progress here so we can start getting bug reports and suggestions. One of the frequent requests for the side menu UI is to provide a way for it to render on top of the UI instead of shift the UI. The old side menu was written when the facebook app was the chief application that used that UI paradigm so it was built to match that approach.\nThe chief problem with the old side menu is that it was written prior to the Toolbar. As a result it was based on the Menu class which was designed in the age of feature phones. Many assumptions that were true back then no longer hold and as a result the side menu has a few elaborate hacks in place to make it feel fluid. When we started looking into the process of rendering the side menu on top we hit a wall.\nThere are multiple conflicting places in the code that position the side menu and do so in elaborate and unintuitive ways. The current side menu implementation is held back by legacy that makes even a seemingly simple change like this challenging. As a result we decided to take a completely different direction for the \u0026ldquo;on top\u0026rdquo; sidemenu.\nA New Direction When the original side menu was designed we didn’t have a layered pane and no InteractionDialog as a result the options for implementing the side menu were limited. When we ran into difficulty with implementing the \u0026ldquo;on top\u0026rdquo; mode in the same way as the regular side menu we decided to shift our focus into the Toolbar class. The on-top side menu is implemented entirely within the Toolbar.\nThe on-top side menu is based on the work we did for the permanent side menu and as a result some incompatibilities and different behaviors will occur when you use that approach. This side menu is placed into an interaction dialog and we use pointer event listeners to track the drag motion to expand and collapse it.\nThis means a few behaviors of the current side menu will be different:\nCurrently the on-top side menu appears below the Toolbar – We have a fix for this but it’s a bit \u0026ldquo;buggy\u0026rdquo; see the discussion below\nOn-top Side menu isn’t a separate form – the original side menu was a separate form. That means the existing UI was de-initialized \u0026amp; some subtle behaviors were different. The underlying UI would still be \u0026ldquo;live\u0026rdquo;\nShadow isn’t supported, however the underlying form is \u0026ldquo;darkened\u0026rdquo; gradually as we drag\nPerformance might not be as smooth at this time – we optimized the hell out of the old side menu, this isn’t as refined\nThe menu button is simply added to the left side – the old side menu had a special case we can’t use\nMany of the theme constants aren’t supported yet, this is work in progress\nThis is how the new side menu looks in the kitchen sink:\nWe’d appreciate if you try the new side menu and let us know where you run into issues, to try is just add the following line to your init method:\nToolbar.setOnTopSideMenu(true); In the future we will add a theme constant for this and might flip it to be the default.\nAnother Layered Pane One of the problems with the new side menu is that it doesn’t cover the entire form due to the fact that InteractionDialog can’t render on the whole form. That is because the layered pane which the InteractionDialog depends on wraps the content pane and not the full Form.\nThat’s not a bad decision as the content pane is where we want most of our UI but there are special cases. Up until now our only option was glass pane but it’s too \u0026ldquo;low level\u0026rdquo;. To solve this we added a new layer into Codename One with getFormLayeredPane which is semantically identical to getLayeredPane but is on top of the entire Form not just the content pane.\nTo prevent potential overhead we only add the form layered pane as needed based on user requests. Internally the form has a hidden border layout that you can’t normally access. It places the title area into its right place as well as the content pane etc. Adding another layer might have impacted compatibility or performance in a way that is too disruptive so we chose to use a rather creative approach…​\nWe added a new constraint to BorderLayout named OVERLAY which you can use as:\nmyBorderLayoutContainer.add(BorderLayout.OVERLAY, placeThisContainerOnTop); This just places the component on top (or below) all of the elements within the Container so the overlay element will literally span the full size of the border layout regardless of all the other elements.\n__ Z-ordering in Codename One is determined by the order of the elements so the last added element is on top by default The InteractionDialog now has a special mode of working on the form layer which works for simple cases but has some rendering artifacts probably due to existing assumptions in the code regarding the Form which has some special cases. That’s why it isn’t enabled by default for the on-top side menu.\nIdeally as we improve this and fix the issue we’ll flip the switch to use the form layered pane.\nFinally This is a bit of a big change, ideally this side menu should be the default but that probably won’t happen for 3.7 as the stability needs to improve. Once this is more stable we will probably flip the switch so developers can get the benefit of a more modern and simpler architecture facilitated by this new side menu. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nCarlos — May 17, 2017 at 1:28 pm (permalink) Carlos says:\nThanks, this is a huge advance. Some problems I’ve seen:\n– If you have a button in the form with a action listener and tap over the side panel, the button below will still work, which is a problem. Everything in the form should be disabled when the side panel is open.\n– The animation when tapping the icon is fine, but dragging the panel is a bit ugly, because the side commands shrink instead of just moving left.\n– And this is me being clumsy: how on earth do you change the hamburger icon color? I can’t see any theme entry, and the side icon constant still doesn’t work.\nShai Almog — May 18, 2017 at 5:20 am (permalink) Shai Almog says:\nThanks for the feedback!\n– Thanks I’ll fix that. It’s a pretty easy fix just make the side menu content pane focusable which means it will grab events in the hierarchy.\n– I’m not sure I can do much about it. There are some deeply held assumptions that prevent me from placing a dialog or interaction dialog \u0026ldquo;offscreen\u0026rdquo;. It might be something worth addressing.\nAlternatively, a hack might be possible here where the Container \u0026ldquo;thinks\u0026rdquo; it has the final size during drag. I’m not sure how hard this will be to address.\n– It should now use the standard TitleCommand UIID instead of the MenuCommand UIID. Since I used the addMaterialCommandToSideMenu call. I did use the menuImageSize theme constant though which currently defaults to 4.5.\nKlug Gauvain — May 18, 2017 at 2:37 pm (permalink) Klug Gauvain says:\nHello, found another bug: If your sidemenu need to be scrolled, with the on top menu it’s impossible ! The menu expand or retracts itself when trying to scroll.\nShai Almog — May 19, 2017 at 4:55 am (permalink) Shai Almog says:\nThanks, I see this. It missed the deadline for this week but I’ll try to do it for next weeks update. Can you file an issue so it doesn’t get lost?\nKlug Gauvain — May 19, 2017 at 7:19 am (permalink) Klug Gauvain says:\nIssue submitted\nbeck — June 24, 2017 at 3:54 am (permalink) beck says:\nIt seems nice but it’d have been better if the side menu covers whole screen (on top of the toolbar as well) though the problem was discussed above. I hope it’ll cover the whole screen in future.\nShai Almog — June 24, 2017 at 4:39 am (permalink) Shai Almog says:\nNotice the content of the section titled \u0026ldquo;Another Layered Pane\u0026rdquo;\nGareth Murfin — January 9, 2018 at 7:26 pm (permalink) Gareth Murfin says:\nHow do you turn this off? It appears on all my forms after my splash and I dont need it.\nShai Almog — January 10, 2018 at 5:26 am (permalink) Shai Almog says:\nToolbar.setOnTopSideMenu(false);\nGareth Murfin — January 10, 2018 at 8:00 am (permalink) Gareth Murfin says:\ndoesnt seem to have any effect here Shai, any other things I need to do? Im using old gui builder project, but its a new project.\nShai Almog — January 12, 2018 at 7:06 am (permalink) Shai Almog says:\nIt disables this feature when used in the init(Object) method. You are probably seeing something else\nYaakov Gesher — January 21, 2018 at 8:53 pm (permalink) Yaakov Gesher says:\nHi, I’m having trouble styling the side menu. How can I make the commands in the side menu render right-to-left? I tried getToolbar().getMenuBar().setRTL(true); but it didn’t seem to have an effect. Also, I wanted to make the side menu wider than just the width of the command texts, but the constants that worked with the older version don’t do anything any more. I tried editing the TitleCommand style, but it didn’t help. Thanks!\nShai Almog — January 22, 2018 at 4:23 am (permalink) Shai Almog says:\nIt should be seamless for an RTL app once we actually implement it and you wouldn’t need to do anything.\nUnfortunately we didn’t implement RTL yet or the right hand sidemenu in the on-top mode. It’s somewhere on our todo list hopefully we’ll be able to address it before 4.0.\nYaakov Gesher — January 22, 2018 at 10:35 pm (permalink) Yaakov Gesher says:\nSorry, maybe it wasn’t clear what I wanted to accomplish: I know that the menu currently can’t be made to open from the right, but I at least wanted the text on the commands to be right-aligned. Eventually I accomplished this by adding components rather than Commands to the menu. But is there a way to give the menu a fixed width?\nShai Almog — January 23, 2018 at 6:42 am (permalink) Shai Almog says:\nI suggest using screenshots to illustrate a question as it would make it easier to answer. Components determine their size based on preferred size. It should \u0026ldquo;just work\u0026rdquo; and if you manipulate it this might break.\nYou can use RTL on a command by using toolbar.findCommandComponent(cmd) and setting the RTL flag on that component explicitly.\nFrancesco Galgani — March 15, 2018 at 5:09 am (permalink) Francesco Galgani says:\nAre the BorderLayout.OVERLAY and the LayeredLayout equivalent? Can I use them in the same cases?\nShai Almog — March 16, 2018 at 5:11 am (permalink) Shai Almog says:\nYou always have a layered layout as there is one in the form. Layouts are constrained to their own container and are unaware of the existence of other layouts.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/sidemenu-on-top/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/sidemenu-on-top/new-features-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis feature is still undergoing development but I wanted to share the progress here so we can start getting bug reports and suggestions. One of the frequent requests for the side menu UI is to provide a way for it to render on top of the UI instead of shift the UI. The old side menu was written when the facebook app was the chief application that used that UI paradigm so it was built to match that approach.\u003c/p\u003e","title":"Sidemenu On Top"},{"content":"\nI’m a bit conflicted about this tip. The AutoCompleteTextField is a problematic class that is in dire need of a rewrite. When we created it we still didn’t accept that lists \u0026ldquo;need to go\u0026rdquo;. It also predated features like the InteractionDialog which would have made this component much easier to use.\nCheck out a live preview of the demo on the right here thanks to our JavaScript port!\nHowever, we have other priorities and rewriting AutoCompleteTextField isn’t even in the top 100…​ So we need to still live with it and with the renderer that it exposes.\nOne question I got a few times is \u0026ldquo;How do you customize the results of the auto complete field\u0026rdquo;?\nThis sounds difficult to most people as we can only work with Strings so how do we represent additional data or format the date correctly?\nThe answer is actually pretty simple, we still need to work with Strings because auto-complete is first and foremost a text field. However, that doesn’t preclude our custom renderer from fetching data that might be placed in a different location and associated with the result.\nThe source below is annotated with a few comments below and you can see the \u0026ldquo;full repository\u0026rdquo; (which isn’t much more than that) in github.\nfinal String[] characters = { \u0026quot;Tyrion Lannister\u0026quot;, \u0026quot;Jaime Lannister\u0026quot;, \u0026quot;Cersei Lannister\u0026quot;, \u0026quot;Daenerys Targaryen\u0026quot;, \u0026quot;Jon Snow\u0026quot;, \u0026quot;Petyr Baelish\u0026quot;, \u0026quot;Jorah Mormont\u0026quot;, \u0026quot;Sansa Stark\u0026quot;, \u0026quot;Arya Stark\u0026quot;, \u0026quot;Theon Greyjoy\u0026quot; // snipped the rest for clarity }; Form current = new Form(\u0026quot;AutoComplete\u0026quot;, BoxLayout.y()); AutoCompleteTextField ac = new AutoCompleteTextField(characters); final int size = Display.getInstance().convertToPixels(7); final EncodedImage placeholder = EncodedImage.createFromImage(Image.createImage(size, size, 0xffcccccc), true); final String[] actors = { \u0026quot;Peter Dinklage\u0026quot;, \u0026quot;Nikolaj Coster-Waldau\u0026quot;, \u0026quot;Lena Headey\u0026quot;}; __**(1)** final Image[] pictures = { URLImage.createToStorage(placeholder, \u0026quot;tyrion\u0026quot;,\u0026quot;http://i.lv3.hbo.com/assets/images/series/game-of-thrones/character/s5/tyrion-lannister-512x512.jpg\u0026quot;), URLImage.createToStorage(placeholder, \u0026quot;jaime\u0026quot;,\u0026quot;http://i.lv3.hbo.com/assets/images/series/game-of-thrones/character/s5/jamie-lannister-512x512.jpg\u0026quot;), URLImage.createToStorage(placeholder, \u0026quot;cersei\u0026quot;,\u0026quot;http://i.lv3.hbo.com/assets/images/series/game-of-thrones/character/s5/cersei-lannister-512x512.jpg\u0026quot;) }; ac.setCompletionRenderer(new ListCellRenderer() { private final Label focus = new Label(); __**(2)** private final Label line1 = new Label(characters[0]); private final Label line2 = new Label(actors[0]); private final Label icon = new Label(pictures[0]); private final Container selection = BorderLayout.center( BoxLayout.encloseY(line1, line2)).add(BorderLayout.EAST, icon); @Override public Component getListCellRendererComponent(com.codename1.ui.List list, Object value, int index, boolean isSelected) { for(int iter = 0 ; iter \u0026lt; characters.length ; iter++) { if(characters[iter].equals(value)) { line1.setText(characters[iter]); if(actors.length \u0026gt; iter) { line2.setText(actors[iter]); icon.setIcon(pictures[iter]); } else { line2.setText(\u0026quot;\u0026quot;); __**(3)** icon.setIcon(placeholder); } break; } } return selection; } @Override public Component getListFocusComponent(com.codename1.ui.List list) { return focus; } }); current.add(ac); current.show(); __1 I have duplicate arrays that are only partial (I was lazy) this is a separate list of data element but you can fetch the additional data from anywhere __2 I create the renderer UI instantly in the fields with the helper methods for wrapping elements which is pretty cool \u0026amp; terse __3 In a renderer it’s important to always set the value especially if you don’t have a value in place Figure 1. Auto complete with images Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\ndavidwaf — January 15, 2018 at 2:45 pm (permalink) Months later, this came in handy. Would be great to know how to implement the list-less version.\nShai Almog — January 16, 2018 at 6:47 am (permalink) Shai Almog says:\nWe’ll need to write a new component to implement that but technically it should be pretty easy to do similarly to some of the options highlighted in https://www.codenameone.com…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-auto-complete-renderer/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-auto-complete-renderer/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’m a bit conflicted about this tip. The \u003ccode\u003eAutoCompleteTextField\u003c/code\u003e is a problematic class that is in dire need of a rewrite. When we created it we still didn’t accept that \u003ca href=\"/blog/avoiding-lists.html\"\u003elists \u0026ldquo;need to go\u0026rdquo;\u003c/a\u003e. It also predated features like the \u003ccode\u003eInteractionDialog\u003c/code\u003e which would have made this component much easier to use.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eCheck out a live preview of the demo on the right here thanks to our JavaScript port!\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eHowever, we have other priorities and rewriting \u003ccode\u003eAutoCompleteTextField\u003c/code\u003e isn’t even in the top 100…​ So we need to still live with it and with the renderer that it exposes.\u003c/p\u003e","title":"TIP: Auto Complete Renderer"},{"content":"\nOne of the biggest challenges facing new Codename One developers is the challenge of creating an elegant looking UI. This isn’t trivial in any tool but we don’t make it easy enough in some cases. In the tutorial below I’m focusing on one of the most important UI elements: the side menu.\nI chose to use a very simple design so this will be easy to follow, you can easily build on top of this to create highly customized styles.\nThe code from the video above is below, you can check out the full repository on github.\nThe Side Menu Figure 1. Side Menu final result\nA side menu is a crucial piece of an elegant application. I’ll explain how one creates a simple side menu that’s elegant, portable and easy to build. This is a good \u0026ldquo;starting point\u0026rdquo; side menu from which you can build more elaborate designs.\nTo get this result we will start from a native theme and a bare bones application to keep things simple.\nThe code for the side menu is this:\nForm hi = new Form(\u0026quot;Hi World\u0026quot;); Toolbar tb = hi.getToolbar(); Image icon = theme.getImage(\u0026quot;icon.png\u0026quot;); __**(1)** Container topBar = BorderLayout.east(new Label(icon)); topBar.add(BorderLayout.SOUTH, new Label(\u0026quot;Cool App Tagline...\u0026quot;, \u0026quot;SidemenuTagline\u0026quot;)); __**(2)** topBar.setUIID(\u0026quot;SideCommand\u0026quot;); tb.addComponentToSideMenu(topBar); tb.addMaterialCommandToSideMenu(\u0026quot;Home\u0026quot;, FontImage.MATERIAL_HOME, e -\u0026gt; {}); __**(3)** tb.addMaterialCommandToSideMenu(\u0026quot;Website\u0026quot;, FontImage.MATERIAL_WEB, e -\u0026gt; {}); tb.addMaterialCommandToSideMenu(\u0026quot;Settings\u0026quot;, FontImage.MATERIAL_SETTINGS, e -\u0026gt; {}); tb.addMaterialCommandToSideMenu(\u0026quot;About\u0026quot;, FontImage.MATERIAL_INFO, e -\u0026gt; {}); hi.addComponent(new Label(\u0026quot;Hi World\u0026quot;)); hi.show(); __1 This is the icon which was used in lieu of a logo it appears in the top right of the side menu __2 This is the top bar containing the tagline and the icon it’s styled as if it’s a command but you can put anything here e.g. an image etc. __3 The commands are added as usual to the side menu with no styling or functionality, the entire look is determined by the theme Next we’ll open the designer tool to style the UI\nFigure 2. Open the side menu so we will get the right values in the combo box on add\nNow when we press Add the side menu entries will appear in the combo box (you can type them but this is more convenient). We’ll start with the SideNavigationPanel style:\nFigure 3. The SideNavigationPanel has an opaque white background\nThe SideCommand style is a bit more elaborate, we start with a white foreground and an opaque bluish/purple color:\nFigure 4. The SideCommand has a white foreground and opaque bluish background\nWe’ll set padding to 3 millimeters which gives everything a good feel and spacing. This is important for finger touch sensitivity.\nFigure 5. Padding is 3mm so it will feel spacious and touch friendly\nWe’ll set margin to 0 except for the bottom one pixel which will leave a nice white line by showing off the background. This means the commands will have a space between them and the white style we gave to the SideNavigationPanel will appear thru that space.\nFigure 6. Margin is 0 except for a thin line below each command\nSetting the border to empty is crucial!\nThe iOS version of the side command inherits a border style so we must \u0026ldquo;remove\u0026rdquo; it by defining a different border in this case an empty border. Since borders take precedence over color this would have prevented the color changes we made from appearing.\nFigure 7. Border must be defined as Empty\nNext we need to pick a good looking font and make sure it’s large enough. We use millimeters size it correctly for all OS’s and override the derived text decoration which has a value in the iOS native theme so it can impact the final look.\nFigure 8. Pick a good looking font for the side command\nNext we need to move to the selected tab and add a new side command entry that derives from the unselected version. We’ll pick a new color that’s slightly deeper and will make the selected style appear selected. We’ll also copy and paste this selected style to the pressed style.\nFigure 9. Selected \u0026amp; Pressed SideCommand\nFigure 10. Color for the Selected/Pressed SideCommand\nThe SidemenuTagline is just a SideCommand style that was slightly adapted. We’ll remove the padding and margin because the whole section is wrapped in a side command and we don’t want double padding. We’ll leave 1mm padding at the top for a bit of spacing from the logo.\nFigure 11. Padding of the SidemenuTagline\nWe’ll also update the font to a smaller size and italic styling so it will feel like a tagline.\nFigure 12. Font for the SideMenuTagline is slightly smaller and italic\nThe last change for the theme is for the StatusBarSideMenu UIID which is a spacing on the top of the sidemenu. This spacing is there for iOS devices which render the clock/battery/reception symbols on top of the app. We’ll set the padding to 0.\nFigure 13. StatusBarSideMenu padding for the top of the side menu\nFinally, we’ll add the icon image (or a logo if you have it) into the theme as a multi image so we can use it within the side menu as a good looking logo. A relatively large icon image works as a 2HD multi-image but you can use many strategies to get a fitting image for this spot.\n__ Rounded images work well here, you can round images dynamically using masking These steps produce the UI above as a side menu, they might seem like a long set of steps but each step is pretty simple as you walk thru each one. This does show off the versatility and power of Codename One as a change to one step can create a radically different UI design.\nFinal Word This is my first tutorial installment and I hope you enjoy it, be sure to leave feedback/thoughts/questions as I’d like to create more tutorials like this moving forward.\nI would like to focus extensively on UI design/layout as it seems to be a stumbling point for many Codename One developers. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nCarlos — May 12, 2017 at 12:07 pm (permalink) Great!!\nIt would be awesome if the hamburger icon could morph into a back arrow, like most apps do.\nAnd would be even better if the side panel could open on top.\nShai Almog — May 13, 2017 at 5:33 am (permalink) Thanks, we already implemented an on-top side menu (although it’s experimental) it’s been in the repo for 2 weeks by now but I didn’t get around to blogging about it. Will do that next week. The icon animations is something I’d like but it’s not trivial to do that right\nKerllon Andrade — November 20, 2018 at 4:06 pm (permalink) Is css?\nShai Almog — November 21, 2018 at 7:08 am (permalink) No.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tutorial-create-a-gorgeous-sidemenu/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tutorial-create-a-gorgeous-sidemenu/learn-codenameone-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the biggest challenges facing new Codename One developers is the challenge of creating an elegant looking UI. This isn’t trivial in any tool but we don’t make it easy enough in some cases. In the tutorial below I’m focusing on one of the most important UI elements: the side menu.\u003c/p\u003e\n\u003cp\u003eI chose to use a very simple design so this will be easy to follow, you can easily build on top of this to create highly customized styles.\u003c/p\u003e","title":"Tutorial – Create a Gorgeous Sidemenu"},{"content":"\nOne of the main reasons for the thread API I discussed yesterday is a new threadsafe Database API. This new API allows you to wrap your Database instance with a thread that will hide all access to the database and implicitly make it threadsafe by serializing all requests to a single database thread.\nThis also has the side effect of removing the hack of working with sqlite on the EDT which could sometimes cause a stutter in the UI when performing SQL. In fact, that was the chief motivation for this particular enhancement!\nYou can use the new threadsafe database API with a single line:\ndb = new ThreadSafeDatabase(db); It’s crucial that once you do this you never use the old db object again!\nThe reason we need this whole thing is that iOS has a builtin version of sqlite that is thread unsafe at a problematic level. E.g. the garbage collector runs on a separate thread and can cause issues if an object is left dangling.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/threadsafe-sqlite/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/threadsafe-sqlite/generic-java-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the main reasons for the thread API I discussed yesterday is a new threadsafe \u003ccode\u003eDatabase\u003c/code\u003e API. This new API allows you to wrap your \u003ccode\u003eDatabase\u003c/code\u003e instance with a thread that will hide all access to the database and implicitly make it threadsafe by serializing all requests to a single database thread.\u003c/p\u003e\n\u003cp\u003eThis also has the side effect of removing the hack of working with sqlite on the EDT which could sometimes cause a stutter in the UI when performing SQL. In fact, that was the chief motivation for this particular enhancement!\u003c/p\u003e","title":"Threadsafe SQLite"},{"content":"\nWorking with threads is usually ranked as one of the least intuitive and painful tasks in programming. This is such an error prone task that some platforms/languages took the route of avoiding threads entirely. I needed to convert some code to work on a separate thread but I still wanted the ability to communicate and transfer data from that thread.\nThis is possible in Java but non-trivial, the thing is that this is relatively easy to do in Codename One with tools such as callSerially I can let arbitrary code run on the EDT. Why not offer that to any random thread?\nThat’s why I created EasyThread which takes some of the concepts of Codeame One’s threading and makes them more accessible to an arbitrary thread. This way you can move things like resource loading into a separate thread and easily synchronize the data back into the EDT as needed…​\nEasy thread can be created like this:\nEasyThread e = EasyThread.start(\u0026quot;ThreadName\u0026quot;); You can just send a task to the thread using:\ne.run(() -\u0026gt; doThisOnTheThread()); But it gets better, say you want to return a value:\ne.run((success) -\u0026gt; success.onSuccess(doThisOnTheThread()), (myResult) -\u0026gt; onEDTGotResult(myRsult)); Lets break that down…​ We ran the thread with the success callback on the new thread then the callback got invoked on the EDT as a result. So this code (success) → success.onSuccess(doThisOnTheThread()) ran off the EDT in the thread and when we invoked the onSuccess callback it sent it asynchronously to the EDT here: (myResult) → onEDTGotResult(myRsult).\nThese asynchronous calls make things a bit painful to wade thru so instead I chose to wrap them in a simplified synchronous version:\nEasyThread e = EasyThread.start(\u0026quot;Hi\u0026quot;); int result = e.run(() -\u0026gt; { System.out.println(\u0026quot;This is a thread\u0026quot;); return 3; }); There are a few other variants like runAndWait and there is a kill() method which stops a thread and releases its resources. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChad Elofson — May 10, 2017 at 5:14 am (permalink) Chad Elofson says:\nThat’s pretty slick!\nJavier Anton — February 18, 2020 at 3:51 pm (permalink) Javier Anton says:\nReally good, but perhaps in the future a method similar to interrupt() could be added to cancel all the pending tasks (since kill() doesn’t cancel pending tasks)\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/easy-thread/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/easy-thread/new-features-5.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWorking with threads is usually ranked as one of the least intuitive and painful tasks in programming. This is such an error prone task that some platforms/languages took the route of avoiding threads entirely. I needed to convert some code to work on a separate thread but I still wanted the ability to communicate and transfer data from that thread.\u003c/p\u003e\n\u003cp\u003eThis is possible in Java but non-trivial, the thing is that this is relatively easy to do in Codename One with tools such as \u003ccode\u003ecallSerially\u003c/code\u003e I can let arbitrary code run on the EDT. Why not offer that to any random thread?\u003c/p\u003e","title":"Easy Thread"},{"content":"\nUsing toggle buttons in touch interfaces is very intuitive for many use cases. We implement them via RadioButton or CheckBox to indicate inclusive or exclusive selection. As a result I find myself using RadioButton quite a lot and ran into an ommission that frankly should have been there from day 1.\nUp until now you couldn’t listen to selection on the ButtonGroup only on the RadioButton itself which isn’t as convenient since for pretty much every case you had to bind listeners over and over. With the latest version of Codename One you can bind a listener to the button group directly like this:\nForm current = new Form(\u0026quot;Toggles\u0026quot;, BoxLayout.y()); ButtonGroup bg = new ButtonGroup(); RadioButton option1 = RadioButton.createToggle(\u0026quot;Option 1\u0026quot;, bg); RadioButton option2 = RadioButton.createToggle(\u0026quot;Option 2\u0026quot;, bg); RadioButton option3 = RadioButton.createToggle(\u0026quot;Option 3\u0026quot;, bg); current.addAll(option1, option2, option3); bg.addActionListener(e -\u0026gt; ToastBar.showMessage(\u0026quot;You selected \u0026quot; + (bg.getSelectedIndex() + 1), FontImage.MATERIAL_INFO)); current.show(); Figure 1. Toggle button selection\nYou will notice I used the selected index but I could have used the source component to get the radio button instance. This might not be useful for all cases but it was pretty convenient for several of my use cases.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-listen-on-all-radios/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-listen-on-all-radios/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eUsing toggle buttons in touch interfaces is very intuitive for many use cases. We implement them via \u003ccode\u003eRadioButton\u003c/code\u003e or \u003ccode\u003eCheckBox\u003c/code\u003e to indicate inclusive or exclusive selection. As a result I find myself using \u003ccode\u003eRadioButton\u003c/code\u003e quite a lot and ran into an ommission that frankly should have been there from day 1.\u003c/p\u003e\n\u003cp\u003eUp until now you couldn’t listen to selection on the \u003ccode\u003eButtonGroup\u003c/code\u003e only on the \u003ccode\u003eRadioButton\u003c/code\u003e itself which isn’t as convenient since for pretty much every case you had to bind listeners over and over. With the latest version of Codename One you can bind a listener to the button group directly like this:\u003c/p\u003e","title":"TIP: Listen on All Radios"},{"content":"\nI’ve been back from the bootcamp this past week and while I have committed many new changes I’m still taking things relatively easy after the hard work of the bootcamp. This will be the last Q\u0026amp;A Friday segment in the blog. Starting next week I’ll replace this segment with \u0026ldquo;tutorial of the week\u0026rdquo; which will focus on publishing/updating a \u0026ldquo;How do I?\u0026rdquo; video tutorial on a weekly basis.\nWe pushed an update to the libraries this week with a few interesting new features that we haven’t documented yet, I hope to have time during the week to write more about these new features and capabilities.\nOn stack overflow we had a lot of interesting questions while I was gone so it’s hard for me to go over everything and narrow down the important ones. Here are a couple I found interesting:\nKevin asked about using WebRTC in Codename One. This is frequently asked so I’m guessing this would be interesting to several developers…​ Steve reviewed this and came to the conclusion that it’s doable with a small change.\nGuillaume asked about reusing the generated certificate on iOS. The UX for this in our wizard doesn’t make this clear enough, we should probably give it an overhaul but Scott did provide the right answer that you can (and should) reuse the same P12 file.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-50/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-50/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been back from the bootcamp this past week and while I have committed many new changes I’m still taking things relatively easy after the hard work of the bootcamp. This will be the last Q\u0026amp;A Friday segment in the blog. Starting next week I’ll replace this segment with \u0026ldquo;tutorial of the week\u0026rdquo; which will focus on publishing/updating a \u0026ldquo;How do I?\u0026rdquo; video tutorial on a weekly basis.\u003c/p\u003e","title":"Questions of the Week 50"},{"content":"\nFingerprint scanners are pretty common in modern hardware both from Apple and some Android vendors. The problem is that the iOS and Android API’s for accessing them are a world apart. However, it’s possible to find some low level common ground which is exactly what our cn1lib for fingerprint scanning accomplished.\nThis is a very basic API that just validates the user as the owner of the device, it’s useful to lock off portions of the application from a 3rd party using code such as:\nFingerprint.scanFingerprint(\u0026quot;Use your finger print to unlock AppName.\u0026quot;, value -\u0026gt; { Log.p(\u0026quot;Scan successful!\u0026quot;); }, (sender, err, errorCode, errorMessage) -\u0026gt; { Log.p(\u0026quot;Scan Failed!\u0026quot;); }); Since the cn1lib is pretty simple it can probably be enhanced to support more elaborate functionality in the future. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nLukman Javalove Idealist Jaji — May 4, 2017 at 5:43 am (permalink) Lukman Javalove Idealist Jaji says:\nFantastic. To think this is what I have been researching all week. But I do want something not too complex but maybe complex for cn1 at this time. I am ordering external finger print scanners to use with my apps (for data collection). The only way to achieve that I guess is to delve into native code. I will like to see this in the future, take advantage of the inbuilt fingerprint hardware on devices to collect fingerprint data and stored. More like\nif(Display.getInstance().isFPSupported())\n{\n//Collect and store)\n}\nShai Almog — May 5, 2017 at 4:46 am (permalink) Shai Almog says:\nGreat. I don’t think that’s allowed on iOS but you can probably extend the Android code in the library to support some Android specific features and expose them in the API.\nGareth Murfin — July 6, 2017 at 11:36 pm (permalink) Gareth Murfin says:\nAwesome, but how does it know your finger print already? from the OS?\nShai Almog — July 7, 2017 at 4:17 am (permalink) Shai Almog says:\nThe devices already have scanned fingerprints within. You use the OS interface to scan.\nYishai Steinhart — July 6, 2018 at 7:37 pm (permalink) Yishai Steinhart says:\nNM\nShai Almog — July 7, 2018 at 4:50 am (permalink) Shai Almog says:\nFYI to your original question I suggest installing the cn1lib via the extension manager as you would get the latest version…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/fingerprint-touchid-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/fingerprint-touchid-support/fingerprint-scanner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eFingerprint scanners are pretty common in modern hardware both from Apple and some Android vendors. The problem is that the iOS and Android API’s for accessing them are a world apart. However, it’s possible to find some low level common ground which is exactly what our \u003ca href=\"https://github.com/codenameone/FingerprintScanner\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ecn1lib for fingerprint scanning\u003c/a\u003e accomplished.\u003c/p\u003e\n\u003cp\u003eThis is a very basic API that just validates the user as the owner of the device, it’s useful to lock off portions of the application from a 3rd party using code such as:\u003c/p\u003e","title":"Fingerprint/TouchID Support"},{"content":"\nAs part of the bootcamp we wrote a couple of cn1libs and the first one is the Braintree cn1lib which allows us to do credit card payments within an app. If you aren’t familiar with Braintree it’s a PayPal company that provides payment integration for mobile devices.\nNotice that this differs from In App Purchase which targets \u0026ldquo;virtual goods\u0026rdquo;. This is useful for things like paying for physical goods and services e.g. paying for a taxi.\nIn order to make a purchase with this API we can use code such as:\nPurchase.startOrder(new Purchase.Callback() { public String fetchToken() { // this method needs to return the token from the Brain tree server API. // You need to use this code to connect to your server or return the data // from a previous connection that fetched the token } public void onPurchaseSuccess(String nonce) { // this is a callback that will be invoked when the purchase succeeds } public void onPurchaseFail(String errorMessage) { // this is a callback that will be invoked when the purchase fails } public void onPurchaseCancel() { // this is a callback that will be invoked when the purchase is canceled } }); Notice that we don’t pass pricing or any other information within the code, this is all done in the server code that generates the token for the purchase. This allows our client code to remain \u0026ldquo;tamper proof\u0026rdquo;, all credit card collection and charge code is written by Braintree and is thus compliant with all the PCI level security restrictions and we can keep our code simple.\nMany basic and subtle hacks can be avoided, e.g. a common hack is to manipulate client side code to change charge pricing but since pricing is determined by our (your) server and communicated directly to the Braintree server this is 100% tamper proof.\nThis is one of those cn1libs where most of the work is done in the server and so I’m only showing you the tip of the iceberg and you would need to followup with the Braintree docs to understand how this is bound to your server then implement your server side logic. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJulien Sosin — May 2, 2017 at 8:58 pm (permalink) Julien Sosin says:\nLooks good !\nsalah Alhaddabi — May 3, 2017 at 1:39 pm (permalink) salah Alhaddabi says:\nExtremely Excellent Work Shai. You guys always keep CN1 ahead of the game!!!\nEdwin Quai Hoi — May 4, 2017 at 6:53 am (permalink) Edwin Quai Hoi says:\nhi is there a list of existing cn1libs anywhere\nShai Almog — May 5, 2017 at 4:44 am (permalink) Shai Almog says:\nSure. Right click project Codename One -\u0026gt; Codename One Settings -\u0026gt; Extensions.\nAlso mirrored to https://www.codenameone.com…\nsalah Alhaddabi — June 15, 2017 at 6:54 am (permalink) salah Alhaddabi says:\nDear Shai,\nI have quoted the followings from PayPal Mobile SDK developer site:\n\u0026ldquo;In countries where Braintree Direct is not available, or to access other features of the PayPal REST API from a mobile app, the native libraries of the PayPal Mobile SDKs enable you to build fast, responsive apps\u0026rdquo;\nit also states that \u0026ldquo;You can use PayPal’s SDKs in any country where PayPal is accepted\u0026rdquo;.\nSo the PayPal Mobile SDKs are accepted in more countries including my country \u0026ldquo;Oman\u0026rdquo;.\nis the CN1 library built using PayPal Mobile SDKs ??\nShai Almog — June 16, 2017 at 6:59 am (permalink) Shai Almog says:\nHi,\nit will fallback to paypal. The location restriction is for the payment receiver.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/braintree-paypal-cn1lib/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/braintree-paypal-cn1lib/new-features-3.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAs part of the bootcamp we wrote a couple of cn1libs and the first one is the \u003ca href=\"https://github.com/codenameone/BraintreeCodenameOne\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eBraintree cn1lib\u003c/a\u003e which allows us to do credit card payments within an app. If you aren’t familiar with \u003ca href=\"https://www.braintreepayments.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eBraintree\u003c/a\u003e it’s a PayPal company that provides payment integration for mobile devices.\u003c/p\u003e\n\u003cp\u003eNotice that this differs from \u003ca href=\"/blog/intro-to-in-app-purchase/\"\u003eIn App Purchase\u003c/a\u003e which targets \u0026ldquo;virtual goods\u0026rdquo;. This is useful for things like paying for physical goods and services e.g. paying for a taxi.\u003c/p\u003e","title":"Braintree (PayPal) cn1lib"},{"content":"\nThe bootcamp is winding down and I’m finally back to our usual scheduled posts. I’d like to open with a common practice that isn’t nearly documented enough: use the native main/EDT threads. Our EDT serves many purposes but one of it’s biggest roles is portability. By having an EDT we get consistent behavior across platforms.\niOS, Android \u0026amp; pretty much any modern OS has an EDT like thread that handles events etc. The problem is that they differ in their nuanced behavior. E.g. Android will usually respect calls off of the EDT and iOS will often crash. Some OS’s enforce EDT access rigidly and will throw an exception when you violate that…​\nNormally you don’t need to know about these things, hidden functionality within our implementation bridges between our EDT and the native EDT to provide consistent cross platform behavior. But when you write native code you need awareness.\nThis begs the question:\nWhy not Implicitly call Native Interfaces on the Native EDT? Good question and I’m glad you asked it!\nCalling into the native EDT includes overhead and it might not be necessary for some features (e.g. IO, polling etc.). Furthermore, some calls might work well with asynchronous calls while others might need synchronous results and we can’t know in advance which ones you would need.\nHow do we Access the Native EDT? Within your native code in Android do something like:\ncom.codename1.impl.android.AndroidNativeUtil.getActivity().runOnUiThread(new Runnable() { public void run() { // your native code here... } }); This will execute the block within run() asynchronously on the native Android UI thread. If you need synchronous execution we have a special method for Codename One:\ncom.codename1.impl.android.AndroidImplementation.runOnUiThreadAndBlock(new Runnable() { public void run() { // your native code here... } }); This blocks in a way that’s OK with the Codename One EDT which is unique to our Android port.\niOS On iOS this is pretty similar (if you consider objective-c to be similar). This is used for asynchronous invocation:\ndispatch_async(dispatch_get_main_queue(), ^{ // your native code here... }); You can use this for synchronous invocation, notice the lack of the a in the dispatch call:\ndispatch_sync(dispatch_get_main_queue(), ^{ // your native code here... }); The problem with the synchronous call is that it will block the caller thread, if the caller thread is the EDT this can cause performance issues and even a deadlock. It’s important to be very cautious with this call!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-use-native-edt/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-use-native-edt/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe bootcamp is winding down and I’m finally back to our usual scheduled posts. I’d like to open with a common practice that isn’t nearly documented enough: use the native main/EDT threads. Our EDT serves many purposes but one of it’s biggest roles is portability. By having an EDT we get consistent behavior across platforms.\u003c/p\u003e\n\u003cp\u003eiOS, Android \u0026amp; pretty much any modern OS has an EDT like thread that handles events etc. The problem is that they differ in their nuanced behavior. E.g. Android will usually respect calls off of the EDT and iOS will often crash. Some OS’s enforce EDT access rigidly and will throw an exception when you violate that…​\u003c/p\u003e","title":"TIP: Use the Native EDT"},{"content":"\nNext week we’ll resume the bootcamp so I might publish one last blog post after this and that’s it for another two weeks. It’s been ages since our last plugin update so we’ll take this opportunity to release a new plugin release for all the IDE’s together with the other fixes and enhancements coming in this update.\nAs a sidenote we have a long weekend on the western hemisphere this Friday so our support in the various channels will be a bit limited as a result.\nI can write a long post on the new features and enhancements we’ve had over the past couple of weeks that I didn’t cover yet in the previous blog posts this week but I’ll skip this for now. I will also discuss only a few of the stack overflow posts because I didn’t follow as closely as I should. Steve did an amazing job filling in for me over the past 3 weeks and will keep that until May 1st.\nGRV_Droid asked how to login with Linkedin and showing great initiative answered his own question with a solution that works…​ Well done!\nAndrew Snejovski had issues with logging into the certificate wizard. This is a pretty common problem due to two factor authentication which Steve explained while highlighting the workaround and long term solution.\nThere were many others but it’s hard to go thru the full list and dig thru each one…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-49/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-49/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eNext week we’ll resume the bootcamp so I might publish one last blog post after this and that’s it for another two weeks. It’s been ages since our last plugin update so we’ll take this opportunity to release a new plugin release for all the IDE’s together with the other fixes and enhancements coming in this update.\u003c/p\u003e\n\u003cp\u003eAs a sidenote we have a long weekend on the western hemisphere this Friday so our support in the various channels will be a bit limited as a result.\u003c/p\u003e","title":"Questions of the Week 49"},{"content":"\nI wrote about properties before but I got a sense most people didn’t understand how amazing they truly are. In this post I would like to show you something they can do that’s incredibly cool and practical for your every day usage.\nTo recap properties are high level attributes of an object that expose a mutable getter/setter which we can observe/introspect. I discussed these terms in the previous article so you can check there for a deeper recap. In this article I’ll show a cool demo and make it cooler with every stage!\nLets assume I have an object called Contacts which includes contact information of contact e.g.:\npublic class Contact implements PropertyBusinessObject { public final IntProperty\u0026lt;Contact\u0026gt; id = new IntProperty\u0026lt;\u0026gt;(\u0026quot;id\u0026quot;); public final Property\u0026lt;String, Contact\u0026gt; name = new Property\u0026lt;\u0026gt;(\u0026quot;name\u0026quot;); public final Property\u0026lt;String, Contact\u0026gt; email = new Property\u0026lt;\u0026gt;(\u0026quot;email\u0026quot;); public final Property\u0026lt;String, Contact\u0026gt; phone = new Property\u0026lt;\u0026gt;(\u0026quot;phone\u0026quot;); public final Property\u0026lt;Date, Contact\u0026gt; dateOfBirth = new Property\u0026lt;\u0026gt;(\u0026quot;dateOfBirth\u0026quot;, Date.class); public final Property\u0026lt;String, Contact\u0026gt; gender = new Property\u0026lt;\u0026gt;(\u0026quot;gender\u0026quot;); public final IntProperty\u0026lt;Contact\u0026gt; rank = new IntProperty\u0026lt;\u0026gt;(\u0026quot;rank\u0026quot;); public final PropertyIndex idx = new PropertyIndex(this, \u0026quot;Contact\u0026quot;, id, name, email, phone, dateOfBirth, gender, rank); @Override public PropertyIndex getPropertyIndex() { return idx; } public Contact() { name.setLabel(\u0026quot;Name\u0026quot;); email.setLabel(\u0026quot;E-Mail\u0026quot;); phone.setLabel(\u0026quot;Phone\u0026quot;); dateOfBirth.setLabel(\u0026quot;Date Of Birth\u0026quot;); gender.setLabel(\u0026quot;Gender\u0026quot;); rank.setLabel(\u0026quot;Rank\u0026quot;); } } For those of you who don’t recall something like this:\npublic final Property\u0026lt;String, Contact\u0026gt; name = new Property\u0026lt;\u0026gt;(\u0026quot;name\u0026quot;); Is roughly equivalent to this:\nprivate String name; public void setName(String name) { this.name = name; } public String getName() { return name; } And you use it like this:\ncontact.name.set(\u0026quot;MyName\u0026quot;); Log.p(\u0026quot;My name is: \u0026quot; + contact.name.get()); So what’s so great about it?\nSeamless persistence\nAutomatic UI Binding\nAutomatic UI generation\nSeamless parsing\nAll of that is made possible because we can query information about the properties from the parent object and we can observe changes on the properties!\nSeamless Serialization Normally to make a Codename One object serialize you need to implement our Externalizable interface and do some heavy lifting. You also need to register this object so the VM will be aware of it. Codename One business objects are seamlessly externalizable and you just need to register them.\nE.g. you can do something like this in your init(Object) method:\nnew Contact().getPropertyIndex().registerExternalizable(); After you do that once you can write/read contacts from storage if you so desire:\nStorage.getInstance().writeObject(\u0026quot;MyContact\u0026quot;, contact); Contact readContact = (Contact)Storage.getInstance().readObject(\u0026quot;MyContact\u0026quot;); This will obviously also work for things like List\u0026lt;Contact\u0026gt; etc…​\nBut this gets better!\nSeamless SQL Storage I don’t like writing SQL, I’d much rather work with objects as much as possible. Which is why SQLMap is such an important API for me in the properties support. SQLMap allows CRUD (Create Read Update Delete) operations on the builtin SQLite database using property objects.\nIf we continue the example from above to show persistence to the SQL database we can just do something like this:\nprivate Database db; private SQLMap sm; public void init(Object context) { theme = UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;); Toolbar.setGlobalToolbar(true); Log.bindCrashProtection(true); try { Contact c = new Contact(); db = Display.getInstance().openOrCreate(\u0026quot;propertiesdemo.db\u0026quot;); __**(1)** sm = SQLMap.create(db); __**(2)** sm.setPrimaryKeyAutoIncrement(c, c.id); __**(3)** sm.createTable(c); __**(4)** } catch(IOException err) { Log.e(err); } } In the above code we do the following:\n__1 Create or open an SQLite database using the standard syntax __2 Create a properties binding instance __3 Define the primary key for contact as id and set it to auto increment which will give it a unique value from the database __4 Call SQL’s createTable if the table doesn’t exist yet! __ Notice that at this time altering a created table isn’t possible so if you add a new property you might need to detect that and do an alter call manually We can then add entries to the contact table using:\nsm.insert(myContact); We can update an entry using:\nsm.update(myContact); And delete an entry using:\nsm.delete(myContact); Listing the entries is more interesting:\nList\u0026lt;PropertyBusinessObject\u0026gt; contacts = sm.select(c, c.name, true, 1000, 0); for(PropertyBusinessObject cc : contacts) { Contact currentContact = (Contact)cc; // ... } The arguments for the select method are:\nThe object type\nThe attribute by which we want to sort the result (can be null)\nWhether sort is ascending\nNumber of elements to fetch\nPage to start with – in this case if we have more than 1000 elements we can fetch the next page using sm.select(c, c.name, true, 1000, 1)\nThere are many additional configurations where we can fine tune how a specific property maps to a column etc.\nWhat’s Still Missing The SQLMap API is very simplistic and doesn’t try to be Hibernate/JPA for mobile. So basic things aren’t available at this time and just won’t work. This isn’t necessarily a problem as mobile databases don’t need to be as powerful as server databases.\nRelational Mappings/JOIN Right now we can’t map an object to another object in the database with the typical one-many, one-one etc. relationships that would could do with JPA. The SQLMap API is really simplistic and isn’t suited for that level of mapping at this time.\nIf there is demand for this it’s something we might add moving forward but our goal isn’t to re-invent hibernate.\nThreading SQLite is sensitive to threading issues especially on iOS. We mostly ignored the issue of threading and issue all calls in process. This can be a problem for larger data sets as the calls would usually go on the EDT.\nThis is something we might want to fix for the generic SQLite API so low level SQL queries will work with our mapping in a sensible way.\nAlter Right now we don’t support table altering to support updated schemas. This is doable and shouldn’t be too hard to implement correctly so if there is demand for doing it we’ll probably add support for this.\nComplex SQL/Transactions We ignored functions, joins, transactions and a lot of other SQL capabilities.\nYou can use SQL directly to use all of these capabilities e.g. if you begin a transaction before inserting/updating or deleting this will work as advertised however if a rollback occurs our mapping will be unaware of that so you will need to re-fetch the data.\nYou will notice we mapped auto-increment so we will generally try to map things that make sense for various use cases, if you have such a use case we’d appreciate pull requests and feedback on the implementation.\nCaching/Collision As mentioned above, we don’t cache anything and there might be a collision if you select the same object twice you will get two separate instances that might collide if you update both (one will \u0026ldquo;win\u0026rdquo;).\nThat means you need to pay attention to the way you cache objects to avoid a case of a modified version of an object kept with an older version.\nUI Binding One of the bigger features of properties are their ability to bind UI to a property. E.g. if we continue the sample above with the Contact class let’s say I have a text field on the form and I want the property (which I mapped to the database) to have the value of the text field. I could do something like this:\nmyNameTextField.setText(myNameTextField.getText()); myNameTextField.addActionListener(e -\u0026gt; myContact.name.set(myNameTextField.getText()); That would work nicely but what if I changed property, that wouldn’t be reflected back into the text field?\nAlso that works nicely for text field but what about other types e.g. numbers, check boxes, pickers etc. this becomes a bit more tedious with those.\nBinding makes this all seamless. E.g. the code above can be written as:\nUiBinding uib = new UiBinding(); uib.bind(myNameTextField, myContact.name); The cool thing is that this works with multiple component types and property types almost magically. Binding works by using an adapter class to convert the data to/from the component. The adapter itself works with a generic converter e.g. this code:\nuib.bind(myRankTextField, myContact.rank); Seems similar to the one above but it takes a String that is returned by the text field and seamlessly converts it to the integer needed by rank. This also works in the other direction…​\nWe can easily build a UI that would allow us to edit the Contact property in memory:\nContainer resp = new Container(BoxLayout.y()); UiBinding uib = new UiBinding(); TextField nameTf = new TextField(); uib.bind(c.name, nameTf); resp.add(c.name.getLabel()). __**(1)** add(nameTf); TextField emailTf = new TextField(); emailTf.setConstraint(TextField.EMAILADDR); uib.bind(c.email, emailTf); resp.add(c.email.getLabel()). add(emailTf); TextField phoneTf = new TextField(); phoneTf.setConstraint(TextField.PHONENUMBER); uib.bind(c.phone, phoneTf); resp.add(c.phone.getLabel()). add(phoneTf); Picker dateOfBirth = new Picker(); dateOfBirth.setType(Display.PICKER_TYPE_DATE); __**(2)** uib.bind(c.dateOfBirth, dateOfBirth); resp.add(c.dateOfBirth.getLabel()). add(dateOfBirth); ButtonGroup genderGroup = new ButtonGroup(); RadioButton male = RadioButton.createToggle(\u0026quot;Male\u0026quot;, genderGroup); RadioButton female = RadioButton.createToggle(\u0026quot;Female\u0026quot;, genderGroup); RadioButton undefined = RadioButton.createToggle(\u0026quot;Undefined\u0026quot;, genderGroup); uib.bindGroup(c.gender, new String[] {\u0026quot;M\u0026quot;, \u0026quot;F\u0026quot;, \u0026quot;U\u0026quot;}, male, female, undefined); __**(3)** resp.add(c.gender.getLabel()). add(GridLayout.encloseIn(3, male, female, undefined)); TextField rankTf = new TextField(); rankTf.setConstraint(TextField.NUMERIC); uib.bind(c.rank, rankTf); __**(4)** resp.add(c.rank.getLabel()). add(rankTf); __1 Notice I use the label of the property which allows better encapsulation __2 We can bind picker seamlessly __3 We can bind multiple radio buttons to a single property to allow the user to select the gender, notice that labels and values can be different e.g. \u0026ldquo;Male\u0026rdquo; selection will translate to \u0026ldquo;M\u0026rdquo; as the value __4 Numeric bindings \u0026ldquo;just work\u0026rdquo; Figure 1. Properties form for the contact\nBinding Object \u0026amp; Auto Commit I skipped a couple of fact about the bind() method. It has an additional version that accepts a ComponentAdapter which allows you to adapt the binding to any custom 3rd party component. That’s a bit advanced for now but I might discuss this later.\nHowever, the big thing I \u0026ldquo;skipped\u0026rdquo; was the return value…​ bind returns a UiBinding.Binding object when performing the bind. This object allows us to manipulate aspects of the binding specifically unbind a component and also manipulate auto commit for a specific binding.\nAuto commit determines if a property is changed instantly or on commit. This is useful for a case where we have an \u0026ldquo;OK\u0026rdquo; button and want the changes to the UI to update the properties only when \u0026ldquo;OK\u0026rdquo; is pressed (this might not matter if you keep different instances of the object). When auto-commit is on (the default which you can change via setAutoCommit in the UiBinding) changes reflect instantly, when it’s off you need to explicitly call commit() or rollback() on the Binding class.\ncommit() applies the changes in the UI to the properties, rollback() restores the UI to the values from the properties object (useful for a \u0026ldquo;reset changes\u0026rdquo; button).\nBinding also includes the ability to \u0026ldquo;unbind\u0026rdquo; this is important if you have a global object that’s bound to a UI that’s discarded. Binding might hold a hard reference to the UI and the property object might create a memory leak.\nBy using the disconnect() method in Binding we can separate the UI from the object and allow the GC to cleanup.\nUI Generation Up until now this was pretty cool but if you looked at the UI construction code above you would see that it’s pretty full of boilerplate code. The thing about boilerplate is that it shows where automation can be applied, that’s the exact idea behind the magical \u0026ldquo;InstantUI\u0026rdquo; class. This means that the UI above can be generated using this code:\nInstantUI iui = new InstantUI(); iui.excludeProperty(myContact.id); __**(1)** iui.setMultiChoiceLabels(myContact.gender, \u0026quot;Male\u0026quot;, \u0026quot;Female\u0026quot;, \u0026quot;Undefined\u0026quot;); __**(2)** iui.setMultiChoiceValues(myContact.gender, \u0026quot;M\u0026quot;, \u0026quot;F\u0026quot;, \u0026quot;U\u0026quot;); Container cnt = iui.createEditUI(myContact, true); __**(3)** __1 The id property is useful for database storage but we want to exclude it from the UI __2 This implements the gender toggle button selection, we provide a hint to the UI so labels and values differ __3 We create the UI from the screenshot above with one line and it’s seamlessly bound to the properties of myContact. The second argument indicates the \u0026ldquo;auto commit\u0026rdquo; status. This still carries most of the flexibilities of the regular binding e.g. I can still get a binding object using:\nUiBinding.Binding b = iui.getBindings(cnt); You might not have noticed this but in the previous vebose code we had lines like:\nemailTf.setConstraint(TextField.EMAILADDR); You might be surprised to know that this will still work seamlessly without doing anything, as would the picker component used to pick a date…​\nThe picker component implicitly works for date type properties, numeric constraints and numbers are implicitly used for number properties and check boxes are used for booleans.\nBut how do we know to use an email constraint for the email property?\nWe have some special case defaults for some common property names, so if your property is named email it will use an email constraint by default. If it’s named url or password etc. it will do the \u0026ldquo;right thing\u0026rdquo; unless you explicitly state otherwise. You can customize the constraint for a specific property using something like:\niui.setTextFieldConstraint(contact.email, TextArea.ANY); This will override the defaults we have in place. The goal of this tool is to have sensible \u0026ldquo;magical\u0026rdquo; defaults that \u0026ldquo;just work\u0026rdquo; so if you can think of other cases like this that make sense let us know!\nemail?\nThe Code \u0026amp; Final Word You can check out the code from this article here.\nI could go on, last time I discussed parsing (which is also seamless to/from JSON/XML) and there are many other features worth discussing. I can also go deeper into how this is all implemented and some of the history of this feature (it predated LWUIT, I started working on this back in 2005)…​\nThese will have to wait for another time and post when I can go more thoroughly into them or maybe I’ll do a video covering this. We used properties a lot in the bootcamp and so far I’m very happy that I brought them in.\nI think we can take this feature much further than what we have above, I think this is the \u0026ldquo;tip of the iceberg\u0026rdquo; that can bring Codename One to levels of productivity/RAD that we haven’t seen. I’d love to get feedback on all of these and how we can improve properties so you can leverage them better in your apps! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nkutoman — April 14, 2017 at 10:27 am (permalink) thanks for the post! The UI binding part was new to me 🙂\nShai Almog — April 15, 2017 at 4:26 am (permalink) Shai Almog says:\nIt’s new for everyone it was just released 😉\nSachin Shah — April 28, 2017 at 5:56 pm (permalink) Sachin Shah says:\nThe UI binding sounds amazing. Do you see this forming the basis of a \u0026ldquo;reactive\u0026rdquo; UI within CN1?\nShai Almog — April 29, 2017 at 6:17 am (permalink) Shai Almog says:\nI don’t know….\nI do agree we need to improve some processes such as tablet/phone code transferability, network/IO callback updates to the UI etc. It’s just hard for me to imagine the way a reactive pattern would fit here. If you have pseudo code you could imagine working (with some explanation of what it would do in theory) I’d be very interested in that.\njames agada — June 1, 2017 at 12:10 pm (permalink) james agada says:\nI think you just made my pet project possible. I will spend time on it and give more feedback. Fantastic.\njames agada — June 8, 2017 at 1:16 pm (permalink) james agada says:\nBeen playing with this a bit. My use case is simply a survey app. I define the app in JSON or similar format and render it for data collection and viewing. Will look at using InstantUI to implement but will have to find a way to work without predefined PropertyBusinessObject class.\nFrancesco Galgani — August 25, 2017 at 7:23 pm (permalink) Francesco Galgani says:\n(This is the third time that I try to post this comment… maybe there are technical problems)\nThank you for this article. I need some clarification, maybe I don’t understand how Java Generics are used with a Property. I’m in trouble with the Property syntax.\nLook at these two lines of code:\npublic final Property\u0026lt;Date, Contact\u0026gt; dateOfBirth = new Property\u0026lt;\u0026gt;(\u0026ldquo;dateOfBirth\u0026rdquo;, Date.class);\npublic final Property\u0026lt;String, Contact\u0026gt; gender = new Property\u0026lt;\u0026gt;(\u0026ldquo;gender\u0026rdquo;);\nMy questions:\n1. Why do you need to specify the \u0026ldquo;Contact\u0026rdquo; class inside the diamonds? Isn’t obvious that the Property dateOfBirth and the Property gender are referred to the parent class, that is Contact?\n2. Why do you need to pass \u0026ldquo;Date.class\u0026rdquo; in the Property constructor in the first row?\n3. Why do you used Log.p(\u0026ldquo;My name is: \u0026quot; + contact.get()); instead of Log.p(\u0026ldquo;My name is: \u0026quot; + contact.name.get());?\n4. Have \u0026ldquo;IntProperty\u0026rdquo; or \u0026ldquo;Property\u0026lt;Integer,Contact\u0026gt;\u0026rdquo; the same meaning exactly?\nShai Almog — August 26, 2017 at 4:45 am (permalink) Shai Almog says:\nI saw the emails but I assumed you deleted the comments. disqus is sometimes annoying, sorry about that.\n1. Unfortunately there is no way to get the \u0026ldquo;parent\u0026rdquo; declaring I explained the need for this here: https://www.codenameone.com…\nThe only reason this is needed is for chained set calls e.g. MyObject m = new MyObject().dateOfBirth.set(date).gender.set(\u0026ldquo;M\u0026rdquo;);\n2. Erasure. Generics are syntactic sugar. They are removed during compile and we have no idea what they were during runtime where we might need them e.g. for things like database mapping. The default mapping is string so that works. That’s also why we added DoubleProperty, IntProperty etc.\n3. Ugh. Because my brain had a compiler bug 😉\nThanks for the catch.\n4. Almost. There is also a getInt() method but this might change so I’d use IntProperty. I suggest checking out the code see https://github.com/codename…\nFrancesco Galgani — August 28, 2017 at 1:23 am (permalink) Francesco Galgani says:\nThank you 🙂\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/properties-are-amazing/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/properties-are-amazing/properties.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI wrote about \u003ca href=\"/blog/properties.html\"\u003eproperties\u003c/a\u003e before but I got a sense most people didn’t understand how amazing they truly are. In this post I would like to show you something they can do that’s \u003cstrong\u003eincredibly cool\u003c/strong\u003e and practical for your every day usage.\u003c/p\u003e\n\u003cp\u003eTo recap properties are high level attributes of an object that expose a mutable getter/setter which we can observe/introspect. I discussed these terms in the \u003ca href=\"/blog/properties.html\"\u003eprevious article\u003c/a\u003e so you can check there for a deeper recap. In this article I’ll show a cool demo and make it cooler with every stage!\u003c/p\u003e","title":"Properties are Amazing"},{"content":"\nOne of the biggest pain points in Codename One is theming, there are several things we did to alleviate the problem but it’s an inherently complex problem. One difficulty people have is in the disconnect between what we see in the UI and the styling in the designer. This creates a disconnect that is often hard to bridge.\nIn the past we added the Component Inspector tool to the simulator that allows you to discover the UIID’s of the various components and change the UIID’s to see the effect. This is very helpful for inspecting a running application and understanding what we see on the screen. Unfortunately, this is a half measure as we need to see something in the Component Inspector then open it in the designer restart the app rinse/repeat…​\nThat is until now!\nWith the update this week we added this:\nIf you don’t have the patience for the video or don’t understand what you just saw this tool allows you to edit any style within a running app (that you built) and instantly preview the changes!\nIt works with multiple res files/themes but might be \u0026ldquo;flaky\u0026rdquo; in such cases as it needs to re-apply the theme. You can open the Component Inspector by clicking Simulator → Component Inspector. You might want to use refresh when reviewing the UI.\n__ This changes the .res file so if you have it open in a designer you might overwrite changes made by this tool! How does it Work? A while back Chen wanted to add the ability to edit a style into the new GUI builder so he created a command line argument to the designer. He did that after I wrote that article so it isn’t documented there but you can effectively open the style editor for of the designer using something like:\njava -jar ~/.codenameone/designer_1.jar -style path-to-res-file.res UIID NameOfTheme So to edit the Button in theme.res in MyProject I would probably do:\njava -jar ~/.codenameone/designer_1.jar -style ~/MyProject/src/theme.res Button Theme Notice that unlike the dialog that opens in the designer tool this one allows you to select the style type you wish to edit using radio buttons on the bottom.\nThe edit function launches that command but it also has another function of refreshing the UI. So when editing completes we update the theme in RAM and refresh the current Form. This works well for some cases but might cause some odd conflicts. E.g. if you navigate back to a form created before it might still have the old theme.\nThere might also be issues with layered themes, e.g. if you have 2 themes layered one on top of the other this might trigger a conflict. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJérémy MARQUER — April 12, 2017 at 2:02 pm (permalink) Jérémy MARQUER says:\nGreat enhancement ! 🙂\nAvelblood — April 15, 2017 at 12:13 pm (permalink) Avelblood says:\nAwesome. The dream comes true =)\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/edit-styles-simulator/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/edit-styles-simulator/uidesign.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the biggest pain points in Codename One is theming, there are several things we did to alleviate the problem but it’s an inherently complex problem. One difficulty people have is in the disconnect between what we see in the UI and the styling in the designer. This creates a disconnect that is often hard to bridge.\u003c/p\u003e\n\u003cp\u003eIn the past we added the Component Inspector tool to the simulator that allows you to discover the UIID’s of the various components and change the UIID’s to see the effect. This is very helpful for inspecting a running application and understanding what we see on the screen. Unfortunately, this is a half measure as we need to see something in the Component Inspector then open it in the designer restart the app rinse/repeat…​\u003c/p\u003e","title":"Edit Styles in Simulator"},{"content":"\nSince I haven’t blogged in a while a lot of stuff has piled up on my desk and I’ll get it out in batches in this post I’ll go over a few of the bigger changes we did while I was away on the bootcamp and also give you a bit of an update on what we’ve been doing within the bootcamp itself.\nThe week before we launched the bootcamp our Mac build servers reached a very heavy workload, this was becoming disruptive to our general developer population as builds got queued at a high rate. After a bit of investigation it seems that this could usually be pinned to specific users with very long build times.\nNormally build time is divided as:\nUpload\nQueued\nBuild\nUpload result\nThe latter is pretty fast since our servers have a very fast connection, the first depends on your Internet speed however the queue is problematic…​\nWe have a limited number of servers, if the build time is too long our servers can become occupied and then people will remain in queue for quite a long time. Worse, because our queue system is biased based on grade if a paying or a few high ranking paying user send builds in succession this might create a situation where low ranking users (free or basic) might be denied access to the server as a higher rank user will constantly step ahead in line.\nSlow builds hurt everyone, up until now we always assumed people would align and try to avoid slow builds but I’m guessing that was naive. The incentive to do that isn’t enough. So we installed a timeout quota on a portion of the build phase which limited some builds.\nIt was a bad idea to do this right before the bootcamp but I felt some urgency due to the large amount of queuing. Initially we limited the time to 15 minutes on the xcode compile phase which is normally around 1.5-2 minutes. Due to some complaints I raised it to 25 minutes and some people still couldn’t get their builds thru (this should give you a sense of how problematic this traffic jam was). Finally Dave produced an idea for improvement in the build process that we implemented and deployed this weekend and it should produce faster builds for those use cases. I don’t see a difference with my builds but if your builds were taking 50 minutes they should be much faster now.\nThis change shouldn’t impact most users but since it changes the way headers are included some native code that relies on headers being included by VM generated code might fail.\nRead Response for Errors Another potentially disruptive change we released this weekend is a flipped default on readResponseForErrors. Normally when you get an error from the server (e.g. 404) the readResponse method of connection request isn’t invoked and you can’t read the error message.\nThis seems to make sense but it causes two big problems:\nWhen working with webservices you often get an error code and text describing the error which you would want to read\nThe network monitor won’t show the error response either…​\nSo we flipped the default to read the response for error codes. This shouldn’t impact most applications but if yours is impacted you can restore the old behavior either by using setReadResponseForErrors(false) on the connection request or do ConnectionRequest.setReadResponseForErrorsDefault(false); to disable this globally.\nBootcamp Update We just finished the first 2 weeks (10 missions) of the bootcamp and will resume the last 2 weeks on the 18th of April (at which point we will again suspend the blog posts).\nWe are covering a lot of material, in some regards more than I expected. I know I’ve personally learned a lot from interacting more closely with the developers in the bootcamp and I think I have a better sense of the pain points. I’ve already made a lot of commits to the project over the last few days to address some of the pain points I felt during the bootcamp but some are harder to fix with a few commits.\nOnce the bootcamp is over I plan to redo a lot of the videos in the site and rework some of our tools/tutorials. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nsalah Alhaddabi — April 18, 2017 at 3:40 pm (permalink) salah Alhaddabi says:\nVery nice Shai and hope the result of the bootcamp will be fruitful and lead to better tutorials/documentation\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/big-changes-bootcamp-updates/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/big-changes-bootcamp-updates/full-stack-java-bootcamp.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSince I haven’t blogged in a while a lot of stuff has piled up on my desk and I’ll get it out in batches in this post I’ll go over a few of the bigger changes we did while I was away on the bootcamp and also give you a bit of an update on what we’ve been doing within the bootcamp itself.\u003c/p\u003e\n\u003cp\u003eThe week before we launched the bootcamp our Mac build servers reached a very heavy workload, this was becoming disruptive to our general developer population as builds got queued at a high rate. After a bit of investigation it seems that this could usually be pinned to specific users with \u003cstrong\u003every\u003c/strong\u003e long build times.\u003c/p\u003e","title":"Big Changes and Bootcamp Updates"},{"content":"\nWe are on a mid-bootcamp break so the blog is back to life during this time (and there is so much to write!), more on that tomorrow but for now I’d like to write about fixing \u0026amp; tracking issues with the designer (resource editor) and the GUI builder.\nBoth of these tools have issues most of which resolve around their connection to the IDE. The reason for this is that they are external tools that aren’t a part of the IDE, this allows us to support all 3 IDE’s without too much of an effort but also creates some issues that are often hard to debug.\nWhen you open either the designer or the GUI builder we install a JAR file within your system. This JAR file is located under the .codenameone directory in your home directory. E.g. on Linux/Mac it would be ~ but for Windows it can be under several hierarchies, see this.\nOnce you locate the home directory peak inside, you should see two files: designer_1.jar \u0026amp; guibuilder_1.jar.\n__ Both will only exist if you opened the designer and GUI builder, also notice that the _1 part of the file name might be missing Command Line You can launch both tools from Command Line. These tools write errors to the system console and you would see errors if they occur. Notice that both tools need Java 8 to work…​ To launch the designer use:\njava -jar designer_1.jar path-to-file.res To launch the GUI builder use:\njava -jar guibuilder_1.jar If you see errors please look them over and let us know what the full set of errors is.\nProblem: Designer Won’t Launch This happens to some Eclipse users. The designer will launch from command line but not from Eclipse. Despite many attempts we failed to reproduce this.\nOur current working theory is that Java home and the Java in the system path are incompatible maybe due to 64/32 bit modes or an older version of Java. Another theory is that a path with spaces or invalid characters is causing this issue.\nIf you are experiencing this issue please review your environment:\nThe bin directory of the JDK (important, the JDK not the JRE) must be first in the system path. Before anything else! Especially before Windows as some versions of the JDK stick Java into the system directory\nJAVA_HOME must point at the JDK directory\nYou should have administrator privileges, I’m not sure if this is essential but please test this\nLook in eclipse.ini and verify that the JDK listed there matches the JDK from the path\nGUI Builder Issues There are several reasons for this and we try to address them with newer releases. To understand how this works check out the .guiBuilder directory in your home directory. In this directory you should see a file called guibuilder.input which is responsible for picking the right file to edit. This is mine:\n\u0026lt;?xml version=\u0026quot;1.0\u0026quot; encoding=\u0026quot;UTF-8\u0026quot;?\u0026gt; \u0026lt;con name=\u0026quot;GuiBuilderTutorial\u0026quot; formName=\u0026quot;MyGuiForm\u0026quot; file=\u0026quot;file:/Users/shai/temp/GuiBuilderTutorial/res/guibuilder/com/mycompany/myapp/MyGuiForm.gui\u0026quot; javaFile=\u0026quot;file:/Users/shai/temp/GuiBuilderTutorial/src/com/mycompany/myapp/MyGuiForm.java\u0026quot; resFile=\u0026quot;file:/Users/shai/temp/GuiBuilderTutorial/src/theme.res\u0026quot; outputFile=\u0026quot;file:/Users/shai/.guiBuilder/733a5319-ceeb-458c-abad-6e2a6a061e05.ouput\u0026quot; running=\u0026quot;file:/Users/shai/.guiBuilder/733a5319-ceeb-458c-abad-6e2a6a061e05\u0026quot; /\u0026gt; The important attributes here are file and javaFile. The former represents the XML gui file and the latter represents the Java source file related to that. If the path is invalid the GUI builder won’t find the right files and won’t know what to do.\nThe content of the .gui file might also be important if the GUI builder suddently stops working for a specific file.\nFinally Please use the comments section for additional tips/questions on how to track issues in the GUI builder \u0026amp; the designer. I’ll try to update this post with newer details for GUI builder \u0026amp; designer debugging.\nHopefully, having this as a good resource will allow us to improve the tools to a level that this resource will become obsolete. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nSeñor Sentinel — April 13, 2017 at 6:57 am (permalink) Señor Sentinel says:\nI can’t launch the GUI builder and would appreciate some help. The whole issue is described at Stack Overflow: http://stackoverflow.com/qu…\nShai Almog — April 14, 2017 at 4:29 am (permalink) Shai Almog says:\nThis will be fixed by today’s release\nSeñor Sentinel — April 14, 2017 at 6:29 am (permalink) Señor Sentinel says:\nHi Shai. Would that be version 3.6.2? My IntelliJ IDEA updated the plugin to that version, but I can’t find it on Jetbrains plugin page, which is a bit strange. Regardless, if you mean version 3.6.2 it didn’t solve anything for me. What’s the next step in trying to get this to work..?\nShai Almog — April 15, 2017 at 4:29 am (permalink) Shai Almog says:\nIt’s 3.6.2 we were in the process of releasing it when you posted so the jetbrains site took a while to update. Did you try the steps above?\nDoes launching from command line work?\nWhat’s in the XML launch file?\nSeñor Sentinel — April 15, 2017 at 7:27 am (permalink) Señor Sentinel says:\nYep, I tried it all. It works just fine launching the designer using \u0026ldquo;java -jar guibuilder.jar\u0026rdquo;. I don’t have an XML file in the .guiBuilder directory. The only file I got there is a file called \u0026ldquo;CN1Preferences\u0026rdquo;, a binary files 151 bytes. (Also, the .guiBuilder dir itself has rights 777.)\n(As a side note I find it confusing getting support from Codename One. It’s a mix of commenting on blog posts, Stack Overflow, Google Groups and Intercom chat. Plus that I’ve requested twice last week that someone email me regarding your service \u0026ldquo;Client side development\u0026rdquo; to help me make an app – I never hear back from anyone. It’s a bit frustrating.)\nShai Almog — April 16, 2017 at 4:43 am (permalink) Shai Almog says:\nDo you have a guibuilder.input file? What’s inside it?\nI’ve explained the free support process here: https://www.codenameone.com…\nI have no idea who you are but we got some contacts about app development over the past week which we answered. Either way our resources are pretty low at this time so if you need us to build your app for you we won’t be able to do anything before September.\nSeñor Sentinel — April 16, 2017 at 7:12 pm (permalink) Señor Sentinel says:\nNo, I only have a CN1Preferences file (binary, 151 bytes) in the .guiBuilder directory. Just to be sure I did a \u0026ldquo;find . ~ | grep -i guibuilder.input\u0026rdquo; and found nothing anywhere in my home path.\nShai Almog — April 17, 2017 at 5:38 am (permalink) Shai Almog says:\nThat sounds like a serious problem. Which OS are you using? Do you see anything in the intellij log after you try to launch the GUI builder?\nSeñor Sentinel — April 17, 2017 at 6:31 am (permalink) Señor Sentinel says:\nI’m on Debian Stable.\nHere’s the full log (106 lines) from me starting IntelliJ and trying to use the GUI Builder: https://www.dropbox.com/s/1….\n(In the log I see that you add a file monitor at ~/.codenameone/open.txt. I don’t know if it’s relevant or important, but that file isn’t there. Just to be sure it wasn’t placed somewhere else I searched home, and it’s nowhere to be found. But, like I said, I have no idea if this is relevant at all.)\nShai Almog — April 18, 2017 at 5:45 am (permalink) Shai Almog says:\nThat’s odd. Did you change something in the IntelliJ configuration?\nDid you add modules or changed the default project structure?\nSeñor Sentinel — April 18, 2017 at 6:32 am (permalink) Señor Sentinel says:\nNo, nothing, I don’t even know how to do that. I installed IntelliJ just to try Codename One. I haven’t even changed the colors of the editor.\n(I’ve used PyCharm for a while, but I can’t imagine their settings overlap. Besides, I’ve mostly adjusted colors and things like that, nothing deeply technical.)\nBasically, this is what I’ve done:\n1. Installed IntelliJ\n2. Installed CN1 from the built-in plugin repo\n3. Created a standard CN1 Hello World project, explored the old GUI Builder a bit. Discovered there was a new GUI Builder.\n4. Added a \u0026ldquo;Codename One Form\u0026rdquo; to the \u0026ldquo;src\u0026rdquo; folder (I remember getting an alert saying it should be in there).\n5. Right-clicked the new form and tried \u0026ldquo;Codename One \u0026gt; GUI Builder\u0026rdquo;. Failed with error in SO link, googled – found nothing other than the recent error with chars in paths, which seems not applicable here.\n6. Manually downloaded 3.5.3 from Jetbrains and installed using the function in IntelliJ (I didn’t copy files or anything – I have no idea where they go)\n7. Tried, failed, googled again – found nothing that seemed relevant.\n8. At next launch IntelliJ wanted to update plugin to 3.6.2, which I let it do.\n9. Tried, failed.\nshannah78 — April 18, 2017 at 5:46 pm (permalink) shannah78 says:\nLooks like there is another bug in the IntelliJ plugin that prevents you from opening GUI forms that are in the root namespace. If you place your form inside a package (not just directly in your src directory), it should work. We’ll have this bug fixed with the next plugin update.\nSeñor Sentinel — April 18, 2017 at 6:02 pm (permalink) Señor Sentinel says:\nOk, so I tried putting it inside a package instead, and now I didn’t get the same error anymore. But it did complain that my packagename couldn’t be found in the res/guibuilder/-path. So I created an empty directory there with the requested name and tried again. Now it complains \u0026ldquo;Couldn’t find GUI file matching: \u0026rdquo;. I’ve double checked the path in the error message, and that’s the exact file that I’m trying to use the GUI Builder on.\nkutoman — November 18, 2018 at 12:02 pm (permalink) kutoman says:\nmy saved states from the gui builder are not reflected on the respective java class. I’ve checked guibuilder.input, the paths are valid. There are also no errors printed when I run it over command line. I’ve recently initialized the codename one based project on IntelliJ IDEA. It’s the first time I’m using the (new) gui builder tool.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-track-designer-guibuilder-issues/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-track-designer-guibuilder-issues/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are on a mid-bootcamp break so the blog is back to life during this time (and there is so much to write!), more on that tomorrow but for now I’d like to write about fixing \u0026amp; tracking issues with the designer (resource editor) and the GUI builder.\u003c/p\u003e\n\u003cp\u003eBoth of these tools have issues most of which resolve around their connection to the IDE. The reason for this is that they are external tools that aren’t a part of the IDE, this allows us to support all 3 IDE’s without too much of an effort but also creates some issues that are often hard to debug.\u003c/p\u003e","title":"TIP: Track Designer \u0026 GUIBuilder Issues"},{"content":"\nThis is our last blog post for the next 2 weeks, during the bootcamp we won’t be blogging and won’t have Friday releases until April 10th where the blog should return. This comes at a bit of a bad time when there is so much to write!\nJust yesterday Steve committed many new Java API’s features such as support for exception chaining and a lot of other cool features. These should be in the Friday release that we are putting out today.\nWe also made a big change to density behavior in Android to workaround issues with some newer phones. Hopefully this version of the change will resolve this once and for all as we took a very generic approach.\nDuring my absence for the bootcamp Steve will handle most user facing support. Notice that if you use pro/enterprise email support be sure to do it from the actual account email. Otherwise he won’t be able to distinguish a valid email from one sent in error.\nOn stack overflow Propagandian asked about minimum size besides preferred size. This is one of those AWT/Swing concepts that seemed right in theory but were often problematic in practice. So we didn’t carry them into LWUIT or Codename One.\nAndrew asked about uploading to the itunes store which is annoyingly painful due to the need of a special tool instead of just a simple file upload tool. There is a workaround suggested by Paul but we would like to eventually automate this last piece as well removing the need for any OS dependent tool chain.\nThis is important even for developers who have a Mac as we would live to have better workflow automation. We need more enterprise subscribers who are interested in this so we can invest our energy working on these sort of tool chains.\nKevin asked about the right resolution for source images. Diamond gave a good answer here, personally I find I use images less and less and try to focus my designs on font images and solids. When I do use images it’s mostly for decoration and then the size isn’t crucial e.g. in the video I posted yesterday the image is just a JPEG and not even a multi image.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-48/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-48/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is our last blog post for the next 2 weeks, during the bootcamp we won’t be blogging and won’t have Friday releases until April 10th where the blog should return. This comes at a bit of a bad time when there is so much to write!\u003cbr\u003e\nJust yesterday Steve committed many new Java API’s features such as support for exception chaining and a lot of other cool features. These should be in the Friday release that we are putting out today.\u003c/p\u003e","title":"Questions of the Week 48"},{"content":"\nI was chatting with one of the bootcamp attendants on the one on one calls and he asked me a question that I didn’t think you’d care about but I’m guessing it would be interesting: \u0026ldquo;Why are you doing the bootcamp?\u0026rdquo;.\nI was so focused on explaining the benefit to you that I neglected to explain what Codename One will gain from this bootcamp.\nThis is probably something I should have explained before we closed registration as it would have explained why I have no intention of doing another bootcamp ever again. Bootcamps are hard work, they don’t scale \u0026amp; I need to take a lot of time off to get it done.\nI have several goals with the bootcamp:\nI hope to have a small team of super skilled developers who will put out apps at a step above the current visual level we have in the gallery\nI hope this will inspire other developers to improve the UI/UX of their apps\nI want to learn from hands on teaching about the areas in which we can improve. What’s hard to pick up in Codename One and what can we do better to serve developers\nI plan to improve my video skills. I hope the production deadlines will help me generate better videos at a much faster pace than I currently do. This is important for the general video production in the website\nThis will also force me to work on course materials which are in a dire straits and need replacements\nTo give you a sense, this is a part of the precourse material (before the bootcamp) it’s one of the tutorials I did about UI design and we built it from scratch:\nJust so I’m clear, this isn’t the app that we’ll be building. Just a small sample tutorial…​\nRegression in DST \u0026amp; new VM Changes The other day I wrote about a DST fix that we made. Turns out the fix failed on devices. We reissued the fix at the end of the day and it seems to be working now.\nBy now Friday is pretty close and we’ll issue our final full Friday release before the bootcamp.\nSteve also committed fixes for many long standing VM RFE’s which should land just now. Probably the most exciting of them is support for java.lang.Number which will simplify a lot of my code. But there are quite a few other VM fixes and enhancements including support for the CharSequence interface and quite a few other features. I’m not sure if I’ll remember to write a blog post about all of these changes during the bootcamp break. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nTur Tur der Scheinriese — March 23, 2017 at 3:05 pm (permalink) Tur Tur der Scheinriese says:\nIs there a chance to get the source code from the video?\nShai Almog — March 24, 2017 at 5:38 am (permalink) Shai Almog says:\nThe source is a part of the bootcamp so not in the near future see:\nhttps://www.codenameone.com…\nI used the same visual effect I used here: https://www.codenameone.com…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/why-bootcamp/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/why-bootcamp/full-stack-java-bootcamp.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI was chatting with one of the bootcamp attendants on the one on one calls and he asked me a question that I didn’t think you’d care about but I’m guessing it would be interesting: \u0026ldquo;Why are you doing the bootcamp?\u0026rdquo;.\u003cbr\u003e\nI was so focused on explaining the benefit to you that I neglected to explain what Codename One will gain from this bootcamp.\u003c/p\u003e\n\u003cp\u003eThis is probably something I should have explained before we closed registration as it would have explained why I have no intention of doing another bootcamp ever again. Bootcamps are hard work, they don’t scale \u0026amp; \u003ca href=\"/blog/changes-2017-milestones-dst-hotfix.html\"\u003eI need to take a lot of time off\u003c/a\u003e to get it done.\u003c/p\u003e","title":"Why did we do the Bootcamp?"},{"content":"\nWe released an important fix for an issue with daylight saving in north America (DST), if you are experiencing weird issues only on iOS that could be attributed to time problems then please send a new build to see if the fix works correctly. Our iOS VM code made some assumptions about DST which were apparently false. We chose to release it outside of our regular update schedule due to the significance of this issue.\nRelease Schedule Due to the tight schedule of the bootcamp we’re postponing some of the previously announced to 2017 milestones so we won’t need to split our focus. The bootcamp ends on May 1st and might require some more effort after it completes and we don’t want to draw the attention from the release. Since our set of open issues is ridiculously large there is just no other way.\nThe 3.7 milestone was planned for May 9th. We’ve decided to postpone it to June 27th (a date I just randomly picked with no reason at all).\nThe 3.8 milestone was planned for October 4th, I’m not a fan of December releases and even November is problematic but I don’t want to slip the release into 2018 so we will go for November 14th as the new release date.\nOur Activity During the Bootcamp During the weeks of the bootcamp the blog won’t post updates unless there is something urgent that we need to communicate. We won’t do the standard Friday release either during those dates. Since the bootcamp is split in the middle we will have regular activity during the off week of the bootcamp.\nSupport which I usually handle will be split between employees with Steve taking most of the public support effort and the pro/enterprise support aliases. Things should function as usual for the most par however if you are one of the people who emails me directly instead of the support alias, or one of the people who doesn’t mention his pro/enterprise account in his email you might not get an answer.\nSo please make sure to include that information in support queries (in general not just now). Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChris — March 22, 2017 at 5:50 pm (permalink) Chris says:\nNew Build still I do see there is a 1 hour delay for DST. On simulator, it was working properly but not on iOS.\nShai Almog — March 23, 2017 at 5:55 am (permalink) Shai Almog says:\nWe had a bug in the first fix (worked on the simulator but failed on devices) we’ve since patched it and got confirmation it works. Can you test again?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/changes-2017-milestones-dst-hotfix/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/changes-2017-milestones-dst-hotfix/generic-java-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe released an important fix for an issue with daylight saving in north America (DST), if you are experiencing weird issues only on iOS that could be attributed to time problems then please send a new build to see if the fix works correctly. Our iOS VM code made some assumptions about DST which were apparently false. We chose to release it outside of our regular update schedule due to the significance of this issue.\u003c/p\u003e","title":"Changes to 2017 Milestones and DST Hotfix"},{"content":"\nBootcamp registration closed well and we are currently in the pre-course (more on that in another post) and already the Facebook group of the bootcamp is seeing decent activity. Being as busy as I am I thought I’d lift a question that was asked there to headline this post: \u0026ldquo;When shouldn’t I use Codename One?\u0026rdquo;.\nThat’s a great question. If Codename One was perfect for every use case it would probably suck. One of the biggest reasons for the complexity of the Android API is that it tries to answer every use case (device vendors, utility developers, game developers, app developers etc.).\nI’ll ignore the obvious use cases for people who don’t like Java. Codename One is designed for Java developers so this is the baseline I’m addressing.\nCodename One is optimized for specific use cases: Apps (mostly standard types) \u0026amp; portability.\nIf the app you are building doesn’t fit in either one of these molds Codename One doesn’t make sense.\nE.g. if you are building a game then Codename One isn’t optimized for that.\nYou can build simple games and they will work fine but once you try to do things like 3d graphics etc. this will become a problem. In the case of gaming I would personally go with a framework more designed for gaming rather than native.\nThen there are device specific tools/utilities e.g. if I wanted to build an Android task manager, this makes no sense in other OS’s. With such a tool bulk of my code would be native Android code anyway so the benefit of using Codename One becomes a hindrance.\nCodename One provides access to the native layer so you can patch small missing pieces but if the entire functionality of your app needs to be in native and can’t be encapsulated the pain of going back and forth to the native interface to communicate back to Codename One might not be worth it.\nIn the past this also applied for apps like mapping apps, e.g. up until recently if you wanted to build an app like Uber on top of Codename One this would have been a huge pain as every bit of \u0026ldquo;on-map\u0026rdquo; functionality would have required adding support natively to the google maps native code. We recently introduced the ability to place components on top of heavyweight widgets (e.g. maps) so the functionality of an app like Uber can be accomplished mostly within portable Codename One logic. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMaxim Geraskyn — April 10, 2017 at 5:47 pm (permalink) Maxim Geraskyn says:\nHi Shai!\nThere is a real magic in your tool. I’m leading the development of unTill software (www.untill.com), currently it is rather a big windows desktop app to automate restaurants and hotels, recently we faced a challenge to migrate MOST of our logic to mobile platforms, iOS and Android, so portability is a cornerstone.\nAt this stage my goal was to get right feeling of the development tools. I played a bit with the latest Android SDK, watched an hour or two of training videos and still was unable to develop an Android app. Then I found a reference to the Codenameone and in a half an hour got a feeling that I understand the core idea of it and how to create a first app, very simple and clean ideas.\nBut, the question is – would you recommend to use it as a base for a rather big development, eventually it will contain around 200K-500K lines of code?\nShai Almog — April 11, 2017 at 4:32 am (permalink) Shai Almog says:\nThanks!\nI’ve seen projects of this size work with Codename One but I would cull them. Mobile interfaces (even tablets) should be smaller as deep functionality within a mobile app is often hard on the end user. Apps need to be simpler, smaller and answer narrower use cases than the full blown desktop experience.\nThis is also good in terms of size/performance/build speed for the resulting app. So one of the more important things to do when moving to mobile (regardless of technology used) is to disconnect from the desktop/web version of your application and think smaller.\nA good example is in the division of use cases. E.g. a corporate application that tracks the sales process might be used by managers and line workers. The former use the application very differently from the latter who only need the reports. These should really be two separate apps with common code.\nAs a side note, a lot of desktop related code can be optimized away in the move to mobile e.g. storage can be streamlined as a lot of features (e.g. export) don’t make as much sense in mobile. Codename One also includes a lot of abstractions to help you cull away code and making it more generic.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-when-shouldnt-i-use-codename-one/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-when-shouldnt-i-use-codename-one/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eBootcamp registration closed well and we are currently in the pre-course (more on that in another post) and already the Facebook group of the bootcamp is seeing decent activity. Being as busy as I am I thought I’d lift a question that was asked there to headline this post: \u0026ldquo;When shouldn’t I use Codename One?\u0026rdquo;.\u003c/p\u003e\n\u003cp\u003eThat’s a great question. If Codename One was perfect for every use case it would probably suck. One of the biggest reasons for the complexity of the Android API is that it tries to answer every use case (device vendors, utility developers, game developers, app developers etc.).\u003c/p\u003e","title":"TIP: When Shouldn't I Use Codename One"},{"content":"\nThank you all for the great response to the bootcamp and especially those of you who signed up. Registration is closing in about 2 hours and we have one last spot left! I’m sure we’ll put out some incredible showcase apps around May/June.\nDespite all my efforts going into the bootcamp things have been moving fast in Codename One development.\nSteve add a new blog post the other day detailing the new ComponentSelector API. It was actually committed last week but we didn’t have room in the blog schedule until this week. He also posted about the big changes he made to the Google Maps support and how those can be used with z-ordered peers to make Uber style applications a reality in Codename One.\nToday’s update doesn’t change that much in terms of functionality, just a few bug fixes and refinements. Next week will be have the last Friday update for a while (which means Codename One updates won’t happen for a while) as I go into the bootcamp and I don’t want to throw all of my tasks onto the team. I think they will have their hands full just covering the level of support work.\nBefore I go into the stack overflow section I’d like to mention that I recently looked in our stackoverflow leaderboard and noticed Diamond surpassed me by a pretty big margin!\nI’m totally thrilled by this and hope many of you will follow suit. I think an answer provided by one of you guys is far more valuable than one provided by me. It’s also a great way to learn Codename One, when I started teaching programming courses back in the 90’s my skill level skyrocketed…​\nBesides that we also had quite a few interesting posts worth mentioning:\nTim asked about bluetooth notification. The interesting bit about this should extend beyond bluetooth.\nThe bluetooth API accepts a callback action listener which Tim assumed would be invoked on the EDT. It’s a good assumption to make and not easy to debug because bluetooth currently only works on the device itself. Unfortunately the library didn’t do that and just invoked actionPerformed directly from what appears to be the native thread. This can cause huge problems such as deadlocks which is why we try to always hide the native thread…​\nSo this is really for library authors: If you need to expose the native thread do it in a dedicated callback and don’t use action listener (see the should navigate feature of the BrowserComponent which does just that). Otherwise users might fail in a painful way.\nDiamond gave a great answer to a question about changing a text field in runtime. This is a feature that’s probably pretty important as inputing passwords on a mobile device is always painful/tedious.\nAL \u0026amp; I answered this question almost at the same time. Push is implemented in GCM but we can switch to FSM without most of you noticing the difference.\nMax asked about the device calendar cn1lib, I gave some details on this almost undocumented library and Diamond filled in some blanks. There are other issues with the calendar on iOS as well as on Android with the new permission based system. If this will see usage it might be worth it to refresh this library as it’s a bit out of date.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-47/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-47/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThank you all for the great response to the bootcamp and especially those of you who signed up. Registration is closing in about 2 hours and we have one last spot left! I’m sure we’ll put out some incredible showcase apps around May/June.\u003cbr\u003e\nDespite all my efforts going into the bootcamp things have been moving fast in Codename One development.\u003c/p\u003e\n\u003cp\u003eSteve add a new blog post the other day detailing the new \u003ca href=\"/blog/jquery-css-style-selectors-for-cn1.html\"\u003eComponentSelector API\u003c/a\u003e. It was actually committed last week but we didn’t have room in the blog schedule until this week. He also posted about the big changes he made to the \u003ca href=\"/blog/new-improved-native-google-maps.html\"\u003eGoogle Maps support\u003c/a\u003e and how those can be used with z-ordered peers to make Uber style applications a reality in Codename One.\u003c/p\u003e","title":"Questions of the Week 47"},{"content":"\nThe ComponentSelector class is a new class that brings the power of jQuery to Codename One. While it is not actually jQuery, it is heavily influenced by it. If you’re not familiar with jQuery, here is the 10 second intro.\njQuery is a javascript library, created by John Resig in 2006, that has become a staple of browser-based UI development. As of March 2017, over 70% of web sites are using jQuery. The initial problem that jQuery solved was browser incompatibility issues. It provided a consistent API for most useful DOM methods so that the developer didn’t have to spend all their days and nights fighting with browser compatibility issues. In a way, it did for Javascript, what Codename One does for mobile apps.\nThe other thing that jQuery did, was provide an elegant way to select and manipulate DOM elements (i.e. HTML tags in a web page). It enabled developers to easily form sets of elements using a CSS-like syntax, and to operate on all elements of those sets, as if they were single elements, and they provided a fluent API to enable developers to chain multiple calls together, and delay onset of carpel tunnel for at least a few extra years.\nWith the new ComponentSelector class, I have adopted the following aspects of jQuery:\nCSS-like Selection Sytax – Support for a CSS-like syntax for \u0026ldquo;selecting\u0026rdquo; Components to be included in a set.\nFluent API – The API is fluent, meaning you can chain multiple method calls together and reduce typing.\nWorking on Sets – Methods of this class operate on sets of components as if they are a single component. As you’ll see, this can be incredibly powerful.\nEffects – Support for common effects on components such as fadeIn(), fadeOut(), slideDown(), and slideUp().\nMotivation By Example The following snippet creates a button, that, when pressed, will fade itself and all of its sibling components out, and then fade them back in.\nimport static com.codename1.ui.ComponentSelector.$; // ... Button slideUp = $(new Button(\u0026quot;Slide Up\u0026quot;)) __**(1)** .setIcon(FontImage.MATERIAL_EXPAND_LESS) __**(2)** .addActionListener(e-\u0026gt;{ __**(3)** $(e) __**(4)** .getParent() __**(5)** .find(\u0026quot;\u0026gt;*\u0026quot;) __**(6)** .slideUpAndWait(1000) __**(7)** .slideDownAndWait(1000); __**(8)** }) .asComponent(Button.class); __**(9)** __1 – Creates a new Button and wraps it in a ComponentSelector so that we can use ComponentSelector’s fluent API to modify the button. __2 – Sets the icon on the button __3 – Adds an action listener to the button __4 – Wraps the source of the action event (which is the button) in a ComponentSelector so we can use fluent API. __5 – Gets button’s parent component. (Actually it is a set of components, size=1) __6 – Gets all of the direct children of the button’s parent container. __7 – Hides all of the children of the button’s parent (i.e. the button and siblings) using a slide-up effect. Duration is 1000ms. Blocks until complete. __8 – Shows the button and its siblings using a slide-down effect. __9 – Returns the button itself to assign to the slideUp local variable. __ For people like Shai who don’t like the jQuery $ syntax used for method names, you can alternatively use the select() method as an alias for $(). Take a close look at that example, and imagine implementing that functionality the \u0026ldquo;old\u0026rdquo; way. It actually gets pretty hairy. Hopefully that example is enough to get you interested in using ComponentSelector.\nNow let’s go into some of the details of how it works and how to use it.\nSelecting Components The first thing you’ll want to do with ComponentSelector, is to select the components that will be in your set. You can do this in many ways:\nYou can use the CSS selector syntax. E.g. $(\u0026quot;Label, Button, #MyCalendar\u0026quot;) = The set of all components on the current form with UIID=Label, or UIID=Button, or Name=MyCalendar.\nYou can explicitly wrap one or more components. E.g. $(myButton, myLabel, myCalendar) = A set with 3 components, myButton, myLabel, and myCalendar.\nYou can modify an existing set to create a new one. E.g. $(\u0026quot;Label\u0026quot;).add(\u0026quot;Button\u0026quot;, true).add($(\u0026quot;#MyCalendar\u0026quot;)); = the same set formed in 1 above. (Labels, Buttons, and components with Name=MyCalendar)\nSpecifying the Roots for Queries You can specify the roots for a query to limit the scope of the search. If you don’t provide a root, then the current form will be used as a root. If there is no current form yet, then a RuntimeException will be thrown. It is always a good idea to provide a root if you have one.\nE.g. $(\u0026quot;Label\u0026quot;, myContainer) = The set of components with UIID=\u0026ldquo;Label\u0026rdquo; inside the myContainer. This will scour the full subtree of myContainer for components that match the provided selector.\nYou can provide multiple roots as well. E.g. $(\u0026quot;Label\u0026quot;, myContainer, anotherContainer) = The set of components with UIID=\u0026ldquo;Label\u0026rdquo; inside either myContainer or anotherContainer.\nYou could also provide set of components, and by extension a ContainerSelector (since it implements java.util.Set\u0026lt;Component\u0026gt;) as the roots. E.g. $(\u0026quot;CalendarDay\u0026quot;, $(\u0026quot;Calendar\u0026quot;)) = The set of all components with UIID \u0026ldquo;CalendarDay\u0026rdquo; inside containers with UIID=\u0026ldquo;Calendar\u0026rdquo;.\nFinally, ComponentSelector provides a find() method that implicitly uses the current set as the roots. E.g. $(\u0026quot;Calendar\u0026quot;).find(\u0026quot;CalendarDay\u0026quot;) is equivalent to $(\u0026quot;CalendarDay\u0026quot;, $(\u0026quot;Calendar\u0026quot;)).\nSelector Syntax So far I’ve just glossed over the selector syntax by saying it’s \u0026ldquo;like CSS\u0026rdquo;. Though it is like CSS selectors, it is necessarily different to accommodate the differences between Codename One’s component model and Javascript’s DOM. Rather than go into a technical language definition, I’ll use some examples to illustrate the capabilities of our syntax.\n$(\u0026quot;Label\u0026quot;) – The set of all components on the form with UIID \u0026ldquo;Label\u0026rdquo;\n$(\u0026quot;#MyField\u0026quot;) – The set of all components on the form with Name \u0026ldquo;MyField\u0026rdquo;.\n$(\u0026quot;.some-tag\u0026quot;) – The set of all components on the form with the tag \u0026ldquo;some-tag\u0026rdquo;. (I’ll discuss tags below).\n$(\u0026quot;Label#MyField\u0026quot;) – The set of all components on the form with both UIID=\u0026ldquo;Label\u0026rdquo; and Name=\u0026ldquo;MyField\u0026rdquo;.\n$(\u0026quot;Label#MyField.some-tag\u0026quot;) – The set of all components on the form with UIID=\u0026ldquo;Label\u0026rdquo;, Name=\u0026ldquo;MyField\u0026rdquo;, and tag \u0026ldquo;some-tag\u0026rdquo;.\n$(\u0026quot;*\u0026quot;) – The set of all components on the form.\n$(\u0026quot;.some-tag.some-other-tag\u0026quot;) – All components with both tags \u0026ldquo;some-tag\u0026rdquo; and \u0026ldquo;some-other-tag\u0026rdquo;\n$(\u0026quot;#MyContainer *\u0026quot;) – All components contained in the subtree whose root has Name=\u0026ldquo;MyContainer\u0026rdquo;. The \u0026ldquo;MyContainer\u0026rdquo; wouldn’t be included in this set. Only its descendants.\n$(\u0026quot;#MyContainer \u0026gt; *\u0026quot;) – Direct children of components with Name=\u0026ldquo;MyContainer\u0026rdquo;. (The \u0026ldquo;MyContainer\u0026rdquo; component would not be included in this set. Only its children.)\n$(\u0026quot;#MyContainer \u0026gt; * \u0026gt; Label\u0026quot;) – Direct grandchildren of components with Name=\u0026ldquo;MyContainer\u0026rdquo;. Only grand children with UIID=\u0026ldquo;Label\u0026rdquo; are included.\nTags Some of the examples above mention the use of \u0026ldquo;tags\u0026rdquo;. Tags are analogous to \u0026ldquo;classes\u0026rdquo; in CSS. I wanted to provide the same type of functionality as CSS classes, but in Java, the term \u0026ldquo;class\u0026rdquo; is a little busy, so I decided to use the term \u0026ldquo;tag\u0026rdquo; instead. You can add as many tags to a component as you like. You can then use those tags to assist in your queries. Tags are added using the addTags() method, and they are removed using the removeTags() method.\nHere is an example that uses tags to implement table striping so that even rows are a different color than odd rows in a table.\nTableLayout tl = new TableLayout(numRows, numCols); Container table = new Container(tl); int rowNum = 0; int colNum = 0; for (String[] row : data) { colNum = 0; for (String cell : row) { table.add( tl.createConstraint(rowNum, colNum), $(new Button(cell)) .setUIID(\u0026quot;Label\u0026quot;) .addTags(rowNum % 2 == 0 ? \u0026quot;even\u0026quot;:\u0026quot;odd\u0026quot;) .asComponent() ); colNum++; } rowNum++; } $(\u0026quot;.even\u0026quot;, table) .setBgColor(0xcccccc) .setBgTransparency(255); In the above example we add a tag to each label when we add it to the table or either \u0026ldquo;even\u0026rdquo; or \u0026ldquo;odd\u0026rdquo;. We then use the \u0026ldquo;even\u0026rdquo; in our ComponentSelector to set the background color and transparency of all labels in even rows. In this example, we actually build the table and set the striping in the same place, but consider the situation when the table is constructed by another API. This approach would allow the API to provide more extensibility by simply tagging the elements and allowing the library user to decide how to style the even and odd rows.\nModifying Styles ComponentSelector includes wrappers for most of the methods of com.codename1.ui.plaf.Style so that you can easily modify the styles of selected components using a fluent API. This was demonstrated a little bit in the table striping example (setBgColor() and setBgTransparency() were called on even rows of the table). It is worth going over this in a little more detail though as Codename One styles have \u0026ldquo;state\u0026rdquo;. E.g. For the snippet of code:\n$(\u0026quot;.even\u0026quot;, table) .setBgColor(0xcccccc) .setBgTransparency(255); Were we setting these values on the \u0026ldquo;selected\u0026rdquo; style, the \u0026ldquo;unselected\u0026rdquo; style, the \u0026ldquo;disabled\u0026rdquo; style, \u0026ldquo;ALL\u0026rdquo; styles? In fact we were only setting these values on the \u0026ldquo;current\u0026rdquo; style. I.e. the call to setBgColor() caused something similar to the following loop to happen on all of the components in the set:\nfor (Component c : evenComponents) { c.getStyle().setBgColor(0xcccccc); } If a component was in \u0026ldquo;selected\u0026rdquo; state, then this would changed the selected style. If it was in pressed state, then it would change the \u0026ldquo;pressed\u0026rdquo; style. Etc…​ What if we wanted to specifically change the styles in the \u0026ldquo;pressed\u0026rdquo; state. Then we would call selectPressedStyle() prior calling our style mutation methods. E.g.\n$(\u0026quot;.even\u0026quot;, table) .selectPressedStyle() .setBgColor(0xcccccc) .setBgTransparency(255); Alternatively, ComponentSelector supports a \u0026ldquo;state\u0026rdquo; pseudo-selector that will initialize the selected style so that you don’t have to call selectXXXStyle() before making changes. E.g. The following snippet is equivalent to the previous:\n$(\u0026quot;.even:pressed\u0026quot;, table) .setBgColor(0xcccccc) .setBgTransparency(255); The following \u0026ldquo;state\u0026rdquo; pseudo-selectors are available:\n:pressed – Selects the \u0026ldquo;pressed\u0026rdquo; style\n:selected – Selects the \u0026ldquo;selected\u0026rdquo; style\n:unselected – Selects the \u0026ldquo;unselected\u0026rdquo; style\n:disabled – Selects the \u0026ldquo;disabled\u0026rdquo; style\n:all – Selects the ALLStyles proxy for each component (so that you can target all styles together)\n:* – Same as :all\nIf you want to access Style objects directly, you can use one of:\ngetPressedStyle() – Returns a proxy style with all of the pressed styles of components in the set.\ngetSelectedStyle()\ngetUnselectedStyle()\ngetDisabledStyle()\ngetAllStyles()\nEffects and Transitions As mentioned above, and demonstrated in the first example of this article, ComponentSelector provides a simple way to add eye-candy to your apps. It implements the fadeIn(), fadeOut(), slideUp(), and slideDown() methods and their AndWait() derivations for showing and hiding components in your UI with style. You no longer have any excuse not to use a transition for showing and hiding elements in your UIs. Using a transition always feels nicer to the user.\nIn addition to these basic effects, ComponentSelector wraps all of the existing animation functionality of the Component and Container classes but with proper accommodations for animating multiple elements simultaneously.\nE.g. Consider this example, that shows a button that replaces itself and all siblings with replacement labels, and then replaces them back.\nButton replace = $(new Button(\u0026quot;Replace Fade/Slide\u0026quot;)) .setIcon(FontImage.MATERIAL_REDEEM) .addActionListener(e-\u0026gt;{ $(e).getParent() .find(\u0026quot;\u0026gt;*\u0026quot;) __**(1)** .replaceAndWait(c-\u0026gt;{ __**(2)** return $(new Label(\u0026quot;Replacement\u0026quot;)) __**(3)** .putClientProperty(\u0026quot;origComponent\u0026quot;, c) __**(4)** .asComponent(); }, CommonTransitions.createFade(1000)) __**(5)** .replaceAndWait(c-\u0026gt;{ Component orig = (Component)c.getClientProperty(\u0026quot;origComponent\u0026quot;); if (orig != null) { c.putClientProperty(\u0026quot;origComponent\u0026quot;, null); return orig; __**(6)** } return c; }, CommonTransitions.createCover(CommonTransitions.SLIDE_HORIZONTAL, false, 1000)); __**(7)** }) .asComponent(Button.class); __1 Finds all siblings of the source button __2 Call replaceAndWait() with a mapping function to define the component that should replace each component. This will replace each component in the set with a replacement component in its respective container. This will also return a new ComponentSelector with the set of replacement components. __3 In our \u0026ldquo;mapper\u0026rdquo; callback, we will return a new Label component to replace each existing component. __4 We store the original component in the replacement’s client properties so that we can swap it back afterwards. __5 We use the \u0026ldquo;Fade\u0026rdquo; transition for the replacement. __6 In the second replaceAndWait() call’s mapper method, we return the original component which we retrieved from the replacement’s client properties. __7 We use a cover transition for the replacement. Component Method Wrappers Most mutator methods in Component and Container include a corresponding wrapper method in ComponentSelector. Some of the more common component subclasses have corresponding wrappers as well. E.g. addActionListener(event) will add add the event to all Buttons in the set. setText(txt) will set the text on all labels, text areas, and buttons. If there are other commonly used methods that you would like to see included in ComponentSelector, let me know, but I think you’ll find the current state to be fairly comprehensive.\nTree Navigation Component and Container include a few tree navigation methods. E.g. Component.getParent() returns the parent container of the current component. In cases like this, where ComponentSelector wraps such a method, it will return a set of corresponding components resulting from calling those methods on the components in the current set.\nE.g. $(comp1, comp2).getParent() will include both the parent of comp1 and comp2 (and if they have the same parent, then the set will only include a single element.\nThis can get interesting when you start combining these methods. E.g. $(comp1, comp2).getParent().getComponentAt(10) will be the set of components that are the 11th children of comp1 and `comp2’s parents. If neither of their parents have that many children, then it will be an empty set. If only one of them has that many, then it will be a set of size 1.\nMore Demos I have posted a demo app that demonstrates a few of the things that I discuss here. The file containing most relevant source code is here.\nI have also posted a short screencast of the demo app on youtube: Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChibuike Mba — March 16, 2017 at 5:12 pm (permalink) WOW! Steve this is cool, will definitely try things out with this coding convention. Anybody with good background knowledge of jQuery will really appreciate this. Doing native mobile like jQuery ninja. Great job. 🙂\nshannah78 — March 16, 2017 at 5:21 pm (permalink) shannah78 says:\nThanks for the kind words. Have loved jQuery for years. It really opened doors for web development. Hopefully this will have a similar effect on CN1 development.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/jquery-css-style-selectors-for-cn1/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/jquery-css-style-selectors-for-cn1/new-features-4.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003eComponentSelector\u003c/code\u003e class is a new class that brings the power of jQuery to Codename One. While it is not \u003cstrong\u003eactually\u003c/strong\u003e jQuery, it is heavily influenced by it. If you’re not familiar with jQuery, here is the 10 second intro.\u003c/p\u003e\n\u003cp\u003ejQuery is a javascript library, created by John Resig in 2006, that has become a staple of browser-based UI development. As of March 2017, over 70% of web sites are using jQuery. The initial problem that jQuery solved was browser incompatibility issues. It provided a consistent API for most useful DOM methods so that the developer didn’t have to spend all their days and nights fighting with browser compatibility issues. In a way, it did for Javascript, what Codename One does for mobile apps.\u003c/p\u003e","title":"jQuery/CSS Style Selectors for Codename One"},{"content":"\nI might have been unclear with about the bootcamp materials. It’s possible I implied that the materials will be available later. They won’t…​\nIt would be unfair to our bootcamp participants if the thing they pay for is then made available for free. There will be some content that we will make available some content that will be available as paid material (a course) and some content that will be 100% exclusive.\nI don’t think we’ll offer anything remotely close to the deal we have with the bootcamp…​\nParse One of the things discussed by people who contacted me is parse support. I wanted to talk about that in the bootcamp but decided it would be too much of a detour for me to cover that material. Then I got into a discussion with\nChidiebere G.U. Okwudire who wrote the parse4cn1 cn1lib and maintains it.\nAs part of that we’ll add a workshop day to the bootcamp where he can cover Parse, parse4cn1 \u0026amp; maybe provide some insight into the process of extending Codename One from the outside. I’m sure it will be illuminating to all of us (myself included).\nWhat is Codename One I’ve spent some time building materials for the pre-course which runs before the bootcamp starts and it covers some of the big pieces of Codename One to make sure we all start on the same page. One of the features I’ve made is the \u0026ldquo;long version\u0026rdquo; of the answer to \u0026ldquo;what is Codename One\u0026rdquo;. This answer goes into the details of history, architecture (big pieces), how does it work and lightweight architecture.\nThis is a small piece of some of the things we are working on:\nAnd the slides I show within the video are here:\n**What is codename one ** from Shai Almog\nAre you Still Waiting? If you haven’t signed up for the bootcamp yet this is pretty much your last chance…​ Registration will close up soon and as I said before we won’t have a better offer in the future because it’s just impossible.\nAny future course will not be cheap, won’t include any of the big ticket items like one on one talks or group support. No course in the future will include the enterprise plan bundled in either.\nThis is the last full day of registration so if you still didn’t signup I suggest rushing it because registration will close…​ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — March 15, 2017 at 3:37 pm (permalink) Chidiebere Okwudire says:\nI’m definitely looking forward to the bootcamp and the extra Parse workshop! Feel free to let me know what aspects of Parse and parse4cn1 you’d like to see so that I can prepare accordingly. Just reply to this post with your ideas/questions.\nAndrew Nyago — March 15, 2017 at 3:38 pm (permalink) Andrew Nyago says:\ni don;t see any link to a registration page for the bootcamp.\nJared Ruplinger — March 15, 2017 at 4:15 pm (permalink) Jared Ruplinger says:\nhttp://codenameone.teachabl…\nChidiebere Okwudire — March 15, 2017 at 5:35 pm (permalink) Chidiebere Okwudire says:\nhttp://codenameone.teachabl…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/bootcamp-parse-bouns-post-materials/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/bootcamp-parse-bouns-post-materials/full-stack-java-bootcamp.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI might have been unclear with about the bootcamp materials. It’s possible I implied that the materials will be available later. They won’t…​\u003cbr\u003e\nIt would be unfair to our bootcamp participants if the thing they pay for is then made available for free. There will be some content that we will make available some content that will be available as paid material (a course) and some content that will be 100% exclusive.\u003c/p\u003e","title":"Bootcamp Parse Bonus and post Materials"},{"content":"\nOne of the primary use-cases that benefits from our recent improvements for native peer integration, is \u0026ldquo;map apps\u0026rdquo;. That is, apps that use native maps in some shape or form. This is an extremely common uses case for mobile apps these days. Codename One has supported native maps for quite some time, but (up until recently), they were limited by a couple of factors:\nNative Widgets Were Always In Front – Since Google Maps were \u0026ldquo;native\u0026rdquo; widgets Codename One couldn’t paint over top of the map. Native widgets were always placed in front of the Codename One UI. We could place markers on the map, and draw paths using MapContainer APIs (which were backed by native code on each platform), but we couldn’t, for example, place a Button over top of the map. The Simulator Still Used the Old MapComponent – The simulator didn’t have support for native maps. It would just use the light-weight Codename One MapComponent, which uses tiles (rather than vector graphics like the native maps), and didn’t behave the same as native maps in some cases. E.g. you could draw over top of the MapComponent, which would cause a bit of a surprise if you were counting on that, only to find out after building for iOS that your beautiful buttons were rendered behind the map. I am happy to announce that on Friday we released an update for the Google maps library the resolves both of these issues.\nYou Can Place CN1 Widgets In Front of the Map Now – Now, you can integrate your native maps into your UI seamlessly with the rest of your Codename One UI. Place your codename one widgets under, over, beside, and around your maps…​ but especially over your maps. You don’t need to do anything special for this to happen. The recent native peer improvements cause native peers to just work. The Simulator Now Behaves More Like Actual Devices – The simulator now uses an internal BrowserComponent with the GoogleMaps Javascript API, which behaves much more like then native maps on device. (Don’t worry, you don’t have to use any Javascript…​ the Java \u0026lt;→ Javascript interop is all hidden. You just use the MapContainer API, and it will take care of the rest. Configuration Adding the native maps library is easy. Just open Codename One Settings, click on \u0026ldquo;Extensions\u0026rdquo;, and install the \u0026ldquo;Google Maps\u0026rdquo; library.\nA little bit has changed since the last time we blogged about native maps. Configuration has gotten a little bit easier. You need to provide separate keys for Android, iOS, and Javascript (If you plan to use the Javascript port). The build hints to provide these values are as follows:\njavascript.googlemaps.key=YOUR_JAVASCRIPT_API_KEY android.xapplication=\u0026lt;meta-data android:name=\u0026quot;com.google.android.maps.v2.API_KEY\u0026quot; android:value=\u0026quot;YOUR_ANDROID_API_KEY\u0026quot;/\u0026gt; ios.afterFinishLaunching=[GMSServices provideAPIKey:@\u0026quot;YOUR_IOS_API_KEY\u0026quot;]; Make sure to replace the values YOUR_ANDROID_API_KEY, YOUR_IOS_API_KEY, and YOUR_JAVASCRIPT_API_KEY with the values you\nobtained from the Google Cloud console by following the instructions for Android\n, for iOS, and for Javascript.\nAdditionally, if you want to use the Javascript maps in the simulator (highly recommended), you’ll need to provide your JAVASCRIPT_API_KEY as a parameter to the MapContainer constructor:\nMapContainer map = new MapContainer(JAVASCRIPT_API_KEY); Now you’re ready to use native maps. Here is a sample app that demonstrates adding markers and paths, as well as using LayeredLayout to layer Codename One widgets over top of a native map.\npublic class GoogleMapsTestApp { private static final String HTML_API_KEY = \u0026quot;*********************************\u0026quot;; private Form current; public void init(Object context) { try { Resources theme = Resources.openLayered(\u0026quot;/theme\u0026quot;); UIManager.getInstance().setThemeProps(theme.getTheme(theme.getThemeResourceNames()[0])); Display.getInstance().setCommandBehavior(Display.COMMAND_BEHAVIOR_SIDE_NAVIGATION); UIManager.getInstance().getLookAndFeel().setMenuBarClass(SideMenuBar.class); } catch (IOException e) { e.printStackTrace(); } } public void start() { if (current != null) { current.show(); return; } Form hi = new Form(\u0026quot;Native Maps Test\u0026quot;); hi.setLayout(new BorderLayout()); final MapContainer cnt = new MapContainer(HTML_API_KEY); Button btnMoveCamera = new Button(\u0026quot;Move Camera\u0026quot;); btnMoveCamera.addActionListener(e-\u0026gt;{ cnt.setCameraPosition(new Coord(-33.867, 151.206)); }); Style s = new Style(); s.setFgColor(0xff0000); s.setBgTransparency(0); FontImage markerImg = FontImage.createMaterial(FontImage.MATERIAL_PLACE, s, Display.getInstance().convertToPixels(3)); Button btnAddMarker = new Button(\u0026quot;Add Marker\u0026quot;); btnAddMarker.addActionListener(e-\u0026gt;{ cnt.setCameraPosition(new Coord(41.889, -87.622)); cnt.addMarker( EncodedImage.createFromImage(markerImg, false), cnt.getCameraPosition(), \u0026quot;Hi marker\u0026quot;, \u0026quot;Optional long description\u0026quot;, evt -\u0026gt; { ToastBar.showMessage(\u0026quot;You clicked the marker\u0026quot;, FontImage.MATERIAL_PLACE); } ); }); Button btnAddPath = new Button(\u0026quot;Add Path\u0026quot;); btnAddPath.addActionListener(e-\u0026gt;{ cnt.addPath( cnt.getCameraPosition(), new Coord(-33.866, 151.195), // Sydney new Coord(-18.142, 178.431), // Fiji new Coord(21.291, -157.821), // Hawaii new Coord(37.423, -122.091) // Mountain View ); }); Button btnClearAll = new Button(\u0026quot;Clear All\u0026quot;); btnClearAll.addActionListener(e-\u0026gt;{ cnt.clearMapLayers(); }); cnt.addTapListener(e-\u0026gt;{ TextField enterName = new TextField(); Container wrapper = BoxLayout.encloseY(new Label(\u0026quot;Name:\u0026quot;), enterName); InteractionDialog dlg = new InteractionDialog(\u0026quot;Add Marker\u0026quot;); dlg.getContentPane().add(wrapper); enterName.setDoneListener(e2-\u0026gt;{ String txt = enterName.getText(); cnt.addMarker( EncodedImage.createFromImage(markerImg, false), cnt.getCoordAtPosition(e.getX(), e.getY()), enterName.getText(), \u0026quot;\u0026quot;, e3-\u0026gt;{ ToastBar.showMessage(\u0026quot;You clicked \u0026quot;+txt, FontImage.MATERIAL_PLACE); } ); dlg.dispose(); }); dlg.showPopupDialog(new Rectangle(e.getX(), e.getY(), 10, 10)); enterName.startEditingAsync(); }); Container root = LayeredLayout.encloseIn( BorderLayout.center(cnt), BorderLayout.south( FlowLayout.encloseBottom(btnMoveCamera, btnAddMarker, btnAddPath, btnClearAll) ) ); hi.add(BorderLayout.CENTER, root); hi.show(); } public void stop() { current = Display.getInstance().getCurrent(); } public void destroy() { } } Figure 1. Native Maps Demo App Screensshot\nYou can view the Javascript version of this app here.\nRead more about the Google Maps library in its Github repository.\nInteraction Dialog vs Dialog When using native peers, you’ll find it preferable to use InteractionDialog rather than Dialog whenever possible. This is because Dialog is actually a Form, and Codename One uses a \u0026ldquo;trick\u0026rdquo; (displaying a screen shot) to be able to display the existing form underneath it. InteractionDialog, on the other hand, is a light-weight component that acts like a dialog, but is rendered in the LayeredPane in front of the elements of the current form. This plays with the new native peers quite nicely. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDiamond — March 16, 2017 at 2:09 pm (permalink) Diamond says:\nHi Steve,\nThere is an exception in the javascript bridge on simulator when calling map.getMaxZoom(), see below:\n[EDT] 0:0:19,357 – Exception: java.lang.RuntimeException – Waited too long for browser bridge\njava.lang.RuntimeException: Waited too long for browser bridge\nat com.codename1.googlemaps.MapContainer$BrowserBridge.waitForReady(MapContainer.java:258)\nat com.codename1.googlemaps.MapContainer$BrowserBridge.access$700(MapContainer.java:221)\nat com.codename1.googlemaps.MapContainer.getMaxZoom(MapContainer.java:531)\nshannah78 — March 16, 2017 at 4:18 pm (permalink) shannah78 says:\nPlease file an issue with a test case. I use getMaxZoom() in the GoogleMapsTest app and it works fine. So could be a race condition, or something specific to your test that is triggering this problem.\nBlessing Mahlalela — March 18, 2017 at 7:41 pm (permalink) Blessing Mahlalela says:\nHi Steve, Thanks for this lib! Works great on iOS \u0026amp; Android, on JS Port there is an issue. I have filed it: https://github.com/codename…\nPatrick Hills — March 24, 2017 at 2:57 pm (permalink) Patrick Hills says:\nHello Shai please how to get nearby places around my current location and if possible see their movement in real time\nShai Almog — March 25, 2017 at 5:49 am (permalink) Shai Almog says:\nYou can get location via the location API. Finding nearby elements would require a webservice like googles location API. I dabbled with it a bit here: https://www.codenameone.com…\nBlessing Mahlalela — March 26, 2017 at 3:10 pm (permalink) Blessing Mahlalela says:\nHi Steve, the MapContainer addPointerReleasedListener is not working on my side. I tried this code:\nmapContainer.addPointerReleasedListener((ActionListener) (ActionEvent evt) -\u0026gt; {\nLog.p(\u0026ldquo;Lat released= \u0026quot; + lat, Log.DEBUG);\nLog.p(\u0026ldquo;Long released= \u0026quot; + lng, Log.DEBUG);\n});\nNote the lat \u0026amp; lng values are obtained inside addMapListener which is working well.\nJulio Valeriron Ochoa — May 26, 2021 at 6:28 pm (permalink) Julio Valeriron Ochoa says:\nHello steve, please provide a way to addPointerReleasedListener to MapContainer\nPatrick Hills — March 27, 2017 at 5:39 pm (permalink) Patrick Hills says:\nHello Shai have gone through the tutorial and is working, i can do my live searches of places from the web service Google API but i want it limited to search nearby places around me OR the user (that the user current location,to search around) and not the whole world places.\nSecondly the search is a little slow.\nSo what should i do? Especially the former question, ie. searching places of my current location\nThank you.\nshannah78 — March 27, 2017 at 5:42 pm (permalink) shannah78 says:\nSince the map is a native component, these lightweight events aren’t supported. Use addTapListener() to detect when the user taps on the map.\nBlessing Mahlalela — March 27, 2017 at 7:16 pm (permalink) Blessing Mahlalela says:\nHi Steve, Thanks! addTapListener() achieves what I am trying to do.\nMounir — May 3, 2017 at 6:47 am (permalink) Mounir says:\nHi , I’m facing a problem with your code , it keeps generation an illegal argument exception width(0) and height(0) cannot be \u0026lt;=0\ncouldn’t find the root of the issue\nShai Almog — May 4, 2017 at 7:33 am (permalink) Shai Almog says:\nMake sure the map is in the center of a border layout in the form and not an absolute center mode or some other special case\nArun raj — August 25, 2017 at 5:54 am (permalink) Arun raj says:\nhow to add search functionality to the map component along with auto complete\nShai Almog — August 26, 2017 at 4:51 am (permalink) Shai Almog says:\nSee the link I provided above https://www.codenameone.com…\nThis isn’t a part of the map API from Google it’s something you need to do via a rest request.\nSynapsido — September 12, 2018 at 2:50 am (permalink) Synapsido says:\nI got this error, trying to run app in smatphone: https://uploads.disquscdn.c…\nShai Almog — September 12, 2018 at 4:09 am (permalink) Shai Almog says:\nTry to get the stack trace from the device either by connecting a cable and looking through DDMS or through the new native logging cn1lib.\nSynapsido — September 18, 2018 at 3:00 am (permalink) Synapsido says:\nI solved the problem…\nBut this example runs without problems in the simulator, buttons work good, but running on the phone, buttons isn’t work… whats the problem…?\nShai Almog — September 20, 2018 at 6:51 am (permalink) Shai Almog says:\nIt’s hard to tell from that description. How did you add the buttons, what did you do exactly?\nDo you see an error in the console etc.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-improved-native-google-maps/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-improved-native-google-maps/maps.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the primary use-cases that benefits from our recent improvements for native peer integration, is \u0026ldquo;map apps\u0026rdquo;. That is, apps that use native maps in some shape or form. This is an extremely common uses case for mobile apps these days. Codename One has supported native maps for quite some time, but (up until recently), they were limited by a couple of factors:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003eNative Widgets Were Always In Front\u003c/strong\u003e – Since Google Maps were \u0026ldquo;native\u0026rdquo; widgets Codename One couldn’t paint over top of the map. Native widgets were always placed in front of the Codename One UI. We could place markers on the map, and draw paths using MapContainer APIs (which were backed by native code on each platform), but we couldn’t, for example, place a Button over top of the map.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eThe Simulator Still Used the Old MapComponent\u003c/strong\u003e – The simulator didn’t have support for native maps. It would just use the light-weight Codename One MapComponent, which uses tiles (rather than vector graphics like the native maps), and didn’t behave the same as native maps in some cases. E.g. you \u003cstrong\u003ecould\u003c/strong\u003e draw over top of the MapComponent, which would cause a bit of a surprise if you were counting on that, only to find out after building for iOS that your beautiful buttons were rendered behind the map.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eI am happy to announce that on Friday we released an update for the Google maps library the resolves both of these issues.\u003c/p\u003e","title":"New Improved Native Google Maps"},{"content":"\nI want the bootcamp to sell out fast. Since the number of spots is very limited this should be doable. To make this happen we are adding to the bootcamp:\n2 months of enterprise subscription (worth $798)\nFree access to upcoming \u0026amp; current courses (worth $398)\nTwo one on one sessions with me (you’d be shocked at how much I used to charge per hour as a consultant)\nAnd that is on top of the 4 weeks of material and a full blown startup worth of progress made in a single bootcamp. We did on-site training that included far less than this for 5K per seat last year!\nThe signup page is here and contains a lot of additional details.\nP.S Even if this sells out quickly I won’t do another one of these. It’s too exhausting and I need to focus on Codename One. I want to keep this post brief but in my update later in the week I’ll elaborate a bit more on why.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/go-for-it/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/go-for-it/full-stack-java-bootcamp.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI want the bootcamp to sell out fast. Since the number of spots is very limited this should be doable. To make this happen we are adding to the bootcamp:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e2 months of enterprise subscription\u003c/strong\u003e (worth $798)\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eFree access to upcoming \u0026amp; current courses\u003c/strong\u003e (worth $398)\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eTwo one on one sessions with me\u003c/strong\u003e (you’d be shocked at how much I used to charge per hour as a consultant)\u003c/p\u003e","title":"Go for it!"},{"content":"\nThis has been one of the more exhausting weeks for me in recent years. I don’t remember this level of exhaustion since those first few months of launching Codename One. Getting everything ready is the hard part, doing the actual bootcamp is the relatively easy part…​\nDespite all of that we still got some things done this week.\nSteve reworked the google maps cn1lib to have a web fallback option. He wrote a pretty big post on it but I didn’t want it to get lost in the whole \u0026ldquo;bootcamp launch\u0026rdquo; posts so we’ll post it next week. Our update of the week includes some bug fixes and a bit of new functionality that we will cover in posts next week.\nStack overflow was busy as usual. HelloWorld opened the subject of out of memory on an application. These things are remarkably hard to debug and we are still conducting this discussion.\nJulien Sosin experienced issues with debug build installation, I wrote a detailed step by step that might be useful\nBeck asked about storage not getting wiped. It turns out that Google changed the policy on backup to have it on by default. You can use the new android.allowBackup=false build hint to disable that.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-46/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-46/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis has been one of the more exhausting weeks for me in recent years. I don’t remember this level of exhaustion since those first few months of launching Codename One. Getting everything ready is the hard part, doing the actual bootcamp is the relatively easy part…​\u003cbr\u003e\nDespite all of that we still got some things done this week.\u003c/p\u003e\n\u003cp\u003eSteve reworked the google maps cn1lib to have a web fallback option. He wrote a pretty big post on it but I didn’t want it to get lost in the whole \u0026ldquo;bootcamp launch\u0026rdquo; posts so we’ll post it next week. Our update of the week includes some bug fixes and a bit of new functionality that we will cover in posts next week.\u003c/p\u003e","title":"Questions of the Week 46"},{"content":"\n__ It’s LIVE! Check out the bootcamp signup here. I’m going to build a new mobile startup within 2 weeks and teach some of you how that is done while doing that. Most people might assume I’m talking about one of those \u0026ldquo;MVP\u0026rdquo; cardboard startups…​ This isn’t the case!\nWe’ll build a real ground breaking app with a server component that handles storage, push and a few other things you wouldn’t expect and I plan to fit the whole thing in a two week time frame.\nThis is essentially what I said in the last two posts in this series. We’ll build the full stack of a real world startup from the ground up to server and client production within 2 weeks of hard work!\nFamous last words?\nOver the past 20+ years I worked for startups, major software/hardware companies, operators, banks and much more…​ I founded 4 companies during this time and every time I did it the process became easier. Codename One is a huge product so it’s not something I would compare to \u0026ldquo;an app\u0026rdquo;. However, the basic product we launched as beta took 3 months to build and we spent too much of that debating the \u0026ldquo;launch slide deck\u0026rdquo;.\nUnlike that effort, building an app is almost trivial when you know how…​ The server side will be relatively simple as it won’t include the web interface portions that are always a pain. Just very basic storage, push and simple management.\nThe big effort that will take most of the time is making the apps look good and applying a compelling design.\nWith this bootcamp I want you to see how easy it is to build a startup and a complex mobile app. But the bigger goal is to flip a switch within you that would hopefully be as transformational for you as it would be for me. I want to recreate the startup experience as part of the bootcamp, that’s something you can’t do in a course.\nEvery startup I worked at even as a consultant had affected me on an emotional level and I hope this will leave you in a similar energized state and motivated to \u0026ldquo;take on the world\u0026rdquo;.\nHow will this Work? At a birds eye view the bootcamp will include a short \u0026ldquo;getting ready\u0026rdquo; period for those unfamiliar with Codename One followed by 1 week of basics, 2 weeks of app building hack race and 1 week of finishing, loose ends and cleanup so we are all at the finish line together.\nThe whole bootcamp will last 4 work weeks (5 day weeks). The 4 weeks will be divided into 2 week batches so we’ll have 2 intensive weeks followed by a week and a half off to regroup and the second part.\nThe bootcamp will start on March 27th and the first two weeks will end on April 6th.\nIt will resume on Tuesday April 18th and will end on Monday May 1st.\nHours for the 1 on 1 sessions will be scheduled individually ideally before the start of the bootcamp for the first session. Since they are 1 on 1 sessions hours would be flexible.\nThe course will include:\n1 on 1 sessions with each participant. Ideally 2 sessions per participant but logistics of time and number of participants might make scheduling difficult (I’m limiting registration numbers so ideally 2 sessions should fit)\nMost of the material will be passed as a combination of video and/or webinars. I’ll determine the ratio of video to webinar based on participation and what works for the group\nTasks delivered daily – to make best use of the bootcamp I’ll send out individual daily \u0026ldquo;missions\u0026rdquo;, those will fit into the puzzle as we continue learning. If an individual mission is too challenging use the chat to get help.\nWe’ll have group chat and a Facebook group for questions/collaboration\n__ If we will have webinars they will be recorded so if you miss them you will be able to watch them later and ask followup questions via the chat/facebook The schedule of the course will be as follows:\nPre course – developers who don’t have Codename One experience will take a small crash course in some of the basics of Codename One so we can begin at an equal footing. This will include some pre-made videos and a few missions to get them ready\nWeek 1 – Basics: Layouts, theming, portability, density, basic design principles, GUI builder vs. handcoding, animations/transitions, storage, SQLite, networking, threading, EDT, custom components, certificates \u0026amp; signing\nWeek 2 – Deeper into the core of Codename One and beginning of building the app we will build thru the course, initial server setup with client/server communication (websockets/webservices)\nWeek 3 – App completion and refinement. Server initiated push, complete design both in CSS \u0026amp; designer, integrating native code\nWeek 4 – Loose ends – security, store upload, localization/internationalization, performance, on device debugging\nA bootcamp is a very fluid process and is subject to change based on feedback from the group. So if we have a group that needs to spend more time on basics we’ll do that and if the group can run faster we’ll add more material based on demand.\nOne Time Thing The way I see this bootcamp it can go in two ways:\nA lot of people will signup and fill it up completely – this would mean I would have too much work and won’t want to do this again as I need to focus on Codename One\nFew people will signup – I won’t repeat something that didn’t succeed\nEither way this is probably the only chance to get this bootcamp.\nI’m limiting the seats because if we have too many participants this might get out of hand, we’ll also limit the signup window to 5 days because we need the list of students ASAP. Some students might not know Codename One yet in which case they will need to do a pre-session so the speed of the class won’t be hindered.\nSignup We don’t have the signup page up yet but we’re working on that!\nI’ll send out an e-mail on 2pm GMT this Monday with signup details. It might be ready sooner but I got some feedback that some of you might need time to seek management approval and I wanted to give you the time to do so. However, I can’t give a lot of time here since we are in a rush and the signup needs to finish with time to spare before the bootcamp starts.\nSignup will last until Friday afternoon (GMT) and will close at that point, I’m limiting the number of students significantly so it’s possible we’ll run out of space sooner. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDalvik — March 8, 2017 at 7:17 pm (permalink) Dalvik says:\nLooks great!\nI still have three questions after reading this:\n– Price?\n– What would the app be?\n– What sort of availability will we need during the bootcamp? Can I still go to work?\nShai Almog — March 8, 2017 at 7:44 pm (permalink) Shai Almog says:\n– We’ll list it on Monday\n– I’ll reveal this only after the bootcamp starts and only to the team. This will be an actual startup that we will launch and try to get traction for.\n– I would be spending the whole day on this during the bootcamp but I’m assuming I would work much harder on this than you guys would. You might be able to get away with half a days work but if you have the ability to take the whole day off and focus on this it might be best as the context switch might be difficult.\nI can’t really tell how hard it will be for each of you since this is a bit different from courses I gave in the past and would be more fluid.\nChidiebere Okwudire — March 8, 2017 at 9:21 pm (permalink) Chidiebere Okwudire says:\nAre you saying each participant would need to put in roughly half a day per day over the 5-week period?\nShai Almog — March 8, 2017 at 9:25 pm (permalink) Shai Almog says:\n4 weeks but generally yes. That’s the difference between a bootcamp and a course. You actually need to do work and learn in a very intense way.\nI think people can still get a lot if they don’t put that amount of time but if you look at the post, the goals are pretty intense.\nDalvik — March 9, 2017 at 4:31 am (permalink) Dalvik says:\nThanks, that makes sense. I have some Codename One experience and good server experience so I’m guessing this will be less of an effort right?\nShai Almog — March 9, 2017 at 4:45 am (permalink) Shai Almog says:\nYes in that case you can get away with less time and possibly multi-tasking.\nMy point is that the timeline of the bootcamp is helpful. The materials will still be there after the completion of the bootcamp but we might not. So if we finish the bootcamp and you didn’t pay attention then you decide to go back and review stuff it might be a bit harder. You could ask us (I’ll setup a private Facebook Group for discussion) and we’ll try to help but that might impact the learning experience.\nsalah Alhaddabi — March 9, 2017 at 8:34 am (permalink) salah Alhaddabi says:\nDear Shai, I wish you would have mentioned the time each session will take during the day (greenwich time) and the pricing so we can make up our mind over the weekend before signing up starts.\nShai Almog — March 9, 2017 at 9:00 am (permalink) Shai Almog says:\nThanks.\nThe times are flexible as we might not have live sessions and even if we do they will be recorded so you can watch them at your convenience. I like live sessions but they might not be practical, I did webinars with some audiences where this worked great and some where it didn’t. It’s hard to know what will work for the group as a whole.\nNormally I like pricing upfront so I get where you are coming from. The opacity here is a \u0026ldquo;hack\u0026rdquo; from a friend. He explained it so beautifully, I hope I’m not murdering his explanation as I’m not a marketing guy:\nSay you have a price up front. People will view everything in your offering in light of your price. E.g a 500 dollar product is clearly inferior to a 5000 dollar product. Even if we KNOW better it’s one of those deeply held mind biases: expensive is more valuable.\nPricing is like that, it’s subjective (cheap for X might be expensive for Y) so the moment you mention a price you are ranked based on everything out there in the market as cheap or expensive and this deters your ability to convey your message of your real value proposition.\nI’m in a dilemma here. I need to price things high enough so you will assign value and low enough because I know some of the community is price sensitive but I don’t want to deter from the value proposition that’s discussed.\nYou need to make an objective decision unrelated to the price tag, decide how much you are willing to pay. When we publish the price it can either be higher or lower.\nIf it’s lower then you landed a great deal!\nIf it’s higher then I either overpriced or the value isn’t there for you.\nOverall this is better for both of us, you can make an objective decision without the biases that pricing provides.\nIt’s even a nice consumer hack detailed here: http://twocents.lifehacker….\nChad Elofson — March 9, 2017 at 5:00 pm (permalink) Chad Elofson says:\nShai,\nI definitely won’t determine the value of this bootcamp based on the price. I have worked on a Codename One mobile app and would love to improve my workflow through this bootcamp.\nAs I am going into business for myself, I would find it helpful if there was a payment option for the bootcamp. Definitely looking forward to Monday!\nChad Elofson — March 9, 2017 at 5:10 pm (permalink) Chad Elofson says:\nFor payment options, I mean having the option to pay it all up front or making two or three payments.\nShai Almog — March 9, 2017 at 5:47 pm (permalink) Shai Almog says:\nThanks!\nSince the bootcamp starts this month and ends at the end of next month we won’t have payment options other than a single payment.\nChad Elofson — March 9, 2017 at 5:51 pm (permalink) Chad Elofson says:\nThen I shall find a way to get it covered. Thanks for the update\nfaenze e. — March 9, 2017 at 7:16 pm (permalink) faenze e. says:\nSo we can sign up just to see the price, scoff, and cancel? If you are worried about apparent value, how about a sliding scale, since value is relative. 😉\nShai Almog — March 9, 2017 at 7:49 pm (permalink) Shai Almog says:\nNope. The product isn’t launched so you have nothing to signup for. On Monday the bootcamp signup will launch and the price will be there.\nPricing is relative to you as the payer, not to me as the service provider who has to take nearly two months off work to setup and run this thing.\nfaenze e. — March 9, 2017 at 8:16 pm (permalink) faenze e. says:\nAh, I misinterpreted the signup date and comments.\nAndrew Nyago — March 14, 2017 at 5:09 pm (permalink) Andrew Nyago says:\nHello, am I late for registration?\nShai Almog — March 14, 2017 at 6:13 pm (permalink) Shai Almog says:\nNo. When registration closes we will block the ability to process the payment.\nAndrew Nyago — March 15, 2017 at 3:44 pm (permalink) Andrew Nyago says:\ni failed to see the link to the registration page.\nShai Almog — March 15, 2017 at 4:28 pm (permalink) Shai Almog says:\nI edited the post after it went live and added it to the top, it’s also in the home page below the fold: http://codenameone.teachabl…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/build-something-big/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/build-something-big/full-stack-java-bootcamp.jpg\"\u003e\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eIt’s LIVE! Check out the bootcamp signup \u003ca href=\"https://codenameone.teachable.com/p/full-stack-java-mobile-app-bootcamp/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere\u003c/a\u003e.\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eI’m going to build a new mobile startup within 2 weeks and teach some of you how that is done while doing that. Most people might assume I’m talking about one of those \u0026ldquo;MVP\u0026rdquo; cardboard startups…​ This isn’t the case!\u003cbr\u003e\nWe’ll build a real ground breaking app with a server component that handles storage, push and a few other things you wouldn’t expect and I plan to fit the whole thing in a two week time frame.\u003c/p\u003e","title":"Build Something Big"},{"content":"\nI didn’t post much about new features in a while because we’ve been so busy with the bootcamp that we didn’t have as much time to write the posts or the actual functionality. But a few features/changes did slide in over the past couple of weeks as is pretty much inevitable.\nThere are a lot of small changes so I’ll divide them to avoid confusion.\nJSObject toString Up until now if you got a callback or had obtained a JSObject and wanted to know what it contained e.g. via:\nLog.p(\u0026quot;My JSObject is: \u0026quot; + myJSObject); You would get the default toString() behavior which would give you no helpful information other than a unique object id. This is silly since JavaScript has a toString() method and what you probably want is to call that. So now the toString() method implicitly calls the JavaScript toString() method thus providing you with useful information for debugging.\nCrash Logs Log.e(exception) prints the stack trace exception into the logs which you can view from the device using crash protection. This isn’t new functionality. However, when we launched Codename One we were very concerned with app size and tried to remove inter-dependencies so we didn’t use the Log class in many places.\nAs a result our code was littered with printStackTrace() calls which might make some on-device failures much harder to investigate especially for iOS. We replaced almost all of those legacy usages with proper Log.e() calls so it’s possible that some of the crash reports you will get in the future will include new information.\nUniversal Windows Platform \u0026amp; Desktop Done Listener I wasn’t even aware this didn’t work in UWP but it seems that the done listener wasn’t implemented there.\nFor those of you who don’t know, text field supports a special listener mode that allows you to bind a done listener such as:\ntf.setDoneListener(e -\u0026gt; done()); This happens when the user presses the done button in the virtual keyboard to perform the action. So you can use that to trigger an action immediately without requiring the user to press another button.\nThe other day Steve also added this to the JavaSE port which means you should be able to debug the done listener in the simulator too.\nInclude Nulls I mentioned this pull request from Terry Wilkinson in the Friday blog post but I didn’t go into details.\nThis pull request adds a mode to the JSONParser where null attributes will still be included in the keySet of the parse Map. So you should be able to do something like this:\nJSONParser p = new JSONParser(); p.setIncludeNulls(true); Map\u0026lt;String,Object\u0026gt; m = p.parseJSON(reader); for(String key : m.keySet()) { Object value = m.get(key); // here value might be null where in the past a null value was just omitted } Now why would you need that?\nLets say you display the set of attributes for a user to edit:\nGiven Name: Shai Surname: Almog Age: null I didn’t specify the age but in the old parser age would be removed so I wouldn’t know how to add it. This works OK if you know the keys in advance but obviously this isn’t as flexible.\nLocalizable SignatureComponent: Last but not least Steve added the ability to localize the signature component by setting some values in the resource bundle. You can learn more about resource bundles and localization here.\nYou can use the following keys when localizing:\nTable 1. Resource Bundle keys Key Default Value SignatureComponent.LeadText Press to sign SignatureComponent.DialogTitle Sign Here SignatureComponent.LeadText Press to sign SignatureComponent.SaveButtonLabel Save `SignatureComponent.ResetButtonLabel Reset `SignatureComponent.CancelButtonLabel Cancel SignatureComponent.ErrorDialog.SignatureRequired.Title Signature Required SignatureComponent.ErrorDialog.SignatureRequired.Body Please draw your signature in the space provided. SignatureComponent.ErrorDialog.OK OK Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/better-logging/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/better-logging/new-features-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI didn’t post much about new features in a while because we’ve been so busy with the bootcamp that we didn’t have as much time to write the posts or the actual functionality. But a few features/changes did slide in over the past couple of weeks as is pretty much inevitable.\u003c/p\u003e\n\u003cp\u003eThere are a lot of small changes so I’ll divide them to avoid confusion.\u003c/p\u003e\n\u003ch3 id=\"jsobject-tostring\"\u003eJSObject toString\u003c/h3\u003e\n\u003cp\u003eUp until now if you got a callback or had obtained a \u003ca href=\"/javadoc/com/codename1/javascript/JSObject/\"\u003eJSObject\u003c/a\u003e and wanted to know what it contained e.g. via:\u003c/p\u003e","title":"Better Logging"},{"content":"\n__ It’s LIVE! Check out the bootcamp signup here. Thanks for all the comments and interest on the previous post. In that post I discussed the importance of great app design and showed some of the cool newish demos I built to highlight the general direction. I also talked about the importance of personal mentorship especially with new/elaborate mobile technologies where everything is different.\nI also discussed the bootcamp with broad strokes, I won’t go into too many details about it today (I’ll write more later in the week). Just to clarify the general direction, the main focus will be on UI/UX. This means we will build a complete production grade application from the ground up with server connectivity and everything…​ I’m aiming this as an advanced bootcamp (deep into native interfaces etc.) but I have provisions for people who are new to Codename One.\nOne of the things that really excites me is getting to know you (our community) better on a more personal level. I find it very hard to keep up with all the thousands of people that I’ve communicated with in the past 5 years. Putting faces, voices and some context is something I’m eagerly looking forward to.\nIt’s been over 10 years since Chen and I started what would later become Codename One and almost 9 years since we open sourced that to the world at Java One. Over these years our offering grew and shifted so quickly that we sometimes forget to mention or document some substantial pieces…​\nCase in point: Steve implemented an integration with Spring based on yeoman a while back and I don’t think we told anyone.\nE.g. you can do this using npm/yo:\nsudo npm install -g generator-cn1-spring-app yo cn1-spring-app MySpringApp __ The sudo command might not be needed on all platforms This generates a Codename One Spring template that you can also install manually to build a client server application in minutes…​\nI’m not sure if I’ll use this in the bootcamp though…​ Chen is pushing for Spring Boot while I have some thoughts about using JHipster or maybe something else?\nIf you have strong feelings/opinions on this please let me know in the comments.\nI’m not sure how crucial this will be as the core focus is on the client side and the communication layers. On the server we’ll work a lot on the networking aspects, push etc. but most of that stuff is very simple. My goal is to create something that will be generic enough that you can adapt it almost seamlessly to your environment.\nFrom Zero to Millions of Downloads One of the main things I want to focus on is \u0026ldquo;real life\u0026rdquo; and the transformational effect of this approach. One of my best examples for this is Ram Nathaniel who is probably one of the first developers using our platform.\nRam picked up Codename One during the beta \u0026amp; built one of the coolest apps ever back in 2012. It’s a bit dated by now with its design but it works well and had gained a loyal following because it’s an amazing app.\nRam shipped his app on iOS \u0026amp; Android without a problem but it stagnated for a couple of years. Ram like a lot of us didn’t have the proper expertise in marketing and promotion to push the app to the prominent place it needs to be. A lot of apps die in this exact spot… Most of us think of a competitor as the worst thing that can happen to our app and a strong competitor is exactly what happened!\nA highly visible YC funded company entered the field and got a lot of visibility/PR.\nThis sounds like a disaster right?\nIn Rams case this was a blessing!\nTypically for that time the newcomer was available only in iOS. Ram seized the opportunity \u0026amp; as a result people searching for similar solutions on Android installed his app increasing his install base by leaps and bounds. These users shared the app socially boosting his iOS installs as well.\nWhile the specific app Ram built is unique, the lessons learned are not. Getting into the market fast and supporting secondary markets such as Windows Mobile is often a powerful play for smaller companies. You still need to invest in design, marketing and the general alphabet soup as you don’t want to rely on luck alone.\nThis isn’t unique to the startup world. I worked with customers ranging from banks to operators and so forth. They all benefited from a simpler approach to mobile.\nYour Feedback I got a lot of feedback both in the emails and comments in the various posts I made on the subject. The feedback has been overwhelmingly positive and raised a few interesting points. I won’t quote emails/comments directly as I didn’t ask for permission beforehand…​\nSo here are some of the things I want to address within the bootcamp:\nFull application development process from certificate to final app in the store\nLayouts\nMulti-DPI and resolution independence\nBuilding a gorgeous UI – adopting it from PSD. Adapting to platform native conventions or overriding them entirely\nUsing both designer and using CSS to build UI\nAnimations \u0026amp; Transitions – the different types of animations, where and how to use them\nThreading, the EDT \u0026amp; network threads\nSecurity\nCustom components, composite components and lead components\nWorking with GUI builder and it’s underlying XML\nLocalization, Internationalization \u0026amp; RTL/Bidi\nWorking with sqlite DB\nApplication design – separation of concerns, best practices \u0026amp; Codename One’s interpretation of MVC\nTuning performance and memory usage for consistent cross device usability\nWorking with native code, integrating native library\nOn device debugging with a Mac\nClient server communication – webservices \u0026amp; web sockets\nServer initiated push\nTime permitting I’d like to also cover things like parse, databinding with properties, debugging the Codename One sources etc.\nBecause of the way a bootcamp is structured this is pretty fluid and we’ll shift it around add/de-emphasize things based on the desires of the group.\nI’m also still looking for feedback on that list so if you think something is missing please let me know.\nUp Next Later in the week I want to outline the exactly how everything will work out as there is obvious logistic complexity with my time and how we are going to run this bootcamp.\nI’m thinking about it as a startup experience to go thru together, it’s hard, fast and very effective. The intensity is a core part of a good bootcamp and it applies to everyone who takes part in a bootcamp including me. The trick that always works for me is to dive head first into the challenge.\nI got a lot of personal contacts and a some comments asking how they can join. I’m sorry but we just haven’t scheduled everything yet so I don’t know for sure. I’ll try to get the basics up by the end of the week \u0026amp; by early next week I think I’ll have the final details. What I can tell is that we’d like to move fast and open/close signup quickly as the scheduling for this is turning out to be really difficult.\nP.S. Thanks to all of you who shared my last post within your social circle, I really appreciate that as it brings more people into the discussion and helps us make a better product overall. I would appreciate your taking the time to share this article as well! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJérémy MARQUER — March 6, 2017 at 4:39 pm (permalink) Very interesting program !\nAs I did not take the time to reply by e-mail, I tell you here what I would like to see in the bootcamp : Unit and Integration Test ! 🙂\nSince I had begin to work on my codenameone project in 2014, I’ve experimented many subject you have mentionned above (full application dev, security, sqlite database, nice UI, threads, webservices, third parties, animations etc…). My application is currently in beta testing and right before to release in AppStore, I would like to cover it with some unit test …\nI will probably tell you more details on this application later, with screenshots.\nDalvik — March 6, 2017 at 5:06 pm (permalink) Dalvik says:\nGreat story about Ram, I was impressed that despite looking dated his app has a 4.2 rating on play from 40k users which is pretty decent and beats a lot of apps out there.\nShai Almog — March 6, 2017 at 5:09 pm (permalink) Shai Almog says:\nGreat!\nTDD is one of those things I’d love to improve in Codename One. It’s my personal second on my wish list after on-device-debugging.\nShai Almog — March 6, 2017 at 5:11 pm (permalink) Shai Almog says:\nOne thing I didn’t highlight enough was the fact that when he wrote the app there were no tutorials, guidelines or anything. No developer guide just a blog and javadocs. So he did a pretty amazing job for the shape Codename One was back then. I wonder how the app would look if he had started working on it now.\nChad Elofson — March 6, 2017 at 5:37 pm (permalink) Chad Elofson says:\nJHipster is Spring Boot with Angular. I have been wanting to try it out.\nFabrício Cabeça — March 6, 2017 at 5:45 pm (permalink) Fabrício Cabeça says:\nHi Shai, if you enjoy a dangerous approach please take a look at our crude swagger plugin for cn1 at github 😉\nhttps://github.com/Pmovil/s…\nsalah Alhaddabi — March 6, 2017 at 6:11 pm (permalink) salah Alhaddabi says:\nDear Shai, since you are trying to focus more on the UI/UX I would really strongly advice that you just stick to the standard java ee 7 api without going into any specific free or commercial third party APIs. That way everyone can follow up without having to learn something new on the server side. If you have written specific plugins to work with spring then its better to discuss that on a separate blog please. I think most of us here are very familiar with the Oracle java ee APIs but we are not all using spring or jhipster plus I am sure there are very good tutorials out there that could explain more on those subjects. So please please please just use the standard java ee 7 API as you can achieve all server tasks by using it. Thanks and sorry for the long reply.\nShai Almog — March 6, 2017 at 6:53 pm (permalink) Shai Almog says:\nYes, it’s spring boot with a few extras, angular being one of them. Mostly it’s the scaffolding process they use.\nShai Almog — March 6, 2017 at 6:54 pm (permalink) Shai Almog says:\nInteresting!\nI’ll post about it in the blog but probably too risky for a bootcamp 😉\nShai Almog — March 6, 2017 at 7:00 pm (permalink) Shai Almog says:\nI mostly agree with what you said and want to keep the \u0026ldquo;hot stuff\u0026rdquo; down so most people can apply this instantly.\nHaving said that, I’d like to move thru the material quickly and focus on the client side. If I end up writing low level webservice code or persistence code on the server I might end up spending too much time on the server tier and too little time in the client tier. I’m also trying to focus around what people actually use in the field today and spring boot is pretty common by now.\nEven if I will use spring boot most of the code I will write will be standard Java EE stuff and should work on any server out there so it shouldn’t detract from the applicability of the code. Most of what spring boot brings to the table is a ready made starting point which means I’ll spend less time on server code that most of you already have.\nsalah Alhaddabi — March 7, 2017 at 4:38 am (permalink) salah Alhaddabi says:\nThanks Shai its ok if you insists on using spring boot but we expect that you will be going through the basics of spring boot as well please because some of us are only using standard java ee. Thanks again.\nShai Almog — March 7, 2017 at 5:17 am (permalink) Shai Almog says:\nSure, I don’t assume developers know this. It’s relatively simple and localized otherwise I wouldn’t consider using it.\nSince the bootcamp is very interactive unlike a course I’d expect more \u0026ldquo;back \u0026amp; forth\u0026rdquo; in case I go to quickly or don’t cover something properly.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/spring-template-more-about-bootcamp/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/spring-template-more-about-bootcamp/full-stack-java-bootcamp.jpg\"\u003e\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eIt’s LIVE! Check out the bootcamp signup \u003ca href=\"https://codenameone.teachable.com/p/full-stack-java-mobile-app-bootcamp/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere\u003c/a\u003e.\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eThanks for all the comments and interest on the \u003ca href=\"/blog/full-stack-java-bootcamp/\"\u003eprevious post\u003c/a\u003e. In that post I discussed the importance of great app design and showed some of the cool newish demos I built to highlight the general direction. I also talked about the importance of personal mentorship especially with new/elaborate mobile technologies where \u003cstrong\u003eeverything\u003c/strong\u003e is different.\u003c/p\u003e\n\u003cp\u003eI also discussed the bootcamp with broad strokes, I won’t go into too many details about it today (I’ll write more later in the week). Just to clarify the general direction, the main focus will be on UI/UX. This means we will build a complete production grade application from the ground up with server connectivity and everything…​ I’m aiming this as an advanced bootcamp (deep into native interfaces etc.) but I have provisions for people who are new to Codename One.\u003cbr\u003e\nOne of the things that really excites me is getting to know you (our community) better on a more personal level. I find it very hard to keep up with all the thousands of people that I’ve communicated with in the past 5 years. Putting faces, voices and some context is something I’m eagerly looking forward to.\u003c/p\u003e","title":"Spring Template and more about the Bootcamp"},{"content":"\nWe had some painful downtime due the the big Amazon S3 crash that brought down a huge amount of services with it. I’ve been toying with the idea of improving the system so it doesn’t fully depend on S3 (mostly for performance as S3 isn’t as fast as one would expect). But right now we are so busy with \u0026ldquo;real work\u0026rdquo; that this probably won’t happen.\nThis weeks update will again replace the push servers with a newer version that deals with encoding the push key on the newer supported platforms as well as support for UWP.\nOn the pull request front we had 2051 from Terry Wilkinson which adds a mode to the JSONParser where null attributes will still be included in the keySet of the parse Map.\nOther than that todays update mostly includes bug fixes and hardly any new features.\nOn stack overflow kevin asked about event listening in a Container hierarchy which made Diamond point him at lead component. This is always challenging for me as an API designer, how do you build an API in a way that people will discover without knowing what they are looking for?\nThis is especially true for lead component which exists in no other API as far as I know.\nHelloWorld stumbled on the common pitfall with borders where they take priority over everything else when designing a UI. I’d love to rewrite the theme designer and have some good ideas on how to do it. But we are still recovering from the rewrite of the GUI builder and picking up another windmill at this time is probably too much.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-45/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-45/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe had some painful downtime due the the big Amazon S3 crash that brought down a huge amount of services with it. I’ve been toying with the idea of improving the system so it doesn’t fully depend on S3 (mostly for performance as S3 isn’t as fast as one would expect). But right now we are so busy with \u0026ldquo;real work\u0026rdquo; that this probably won’t happen.\u003c/p\u003e\n\u003cp\u003eThis weeks update will again replace the push servers with a newer version that deals with encoding the push key on the newer supported platforms as well as support for UWP.\u003c/p\u003e","title":"Questions of the Week 45"},{"content":"\n__ It’s LIVE! Check out the bootcamp signup here. Thanks again to everyone who answered my questions. I got tons of valuable feedback on our work \u0026amp; what you would like to learn. It was super helpful and I’m grateful to all of you as you are literally shaping how this bootcamp (and the future of Codename One). I’m sorry if I was brief in some of the thank you emails, it took some time as I wrote them all personally and worked well into the night the other day.\nOne of the main things I got from pretty much everyone who wrote is the desire to improve your UI, this is a huge deal for us as I think we have an advantage here. E.g. a lot of developers who wrote to me (some of which worked with us for years) weren’t familiar with these demos I’ve published:\nMaterial Screens\nPhoenix\nPSD to App\nClean Modern\nFigure 1. This took me a day or two to build (based on existing design)\nTo me these demos show more than just a good looking UI. They hint of the potential…​\nIn the right hands you can produce any damn UI design that your insane designer can come up with. This isn’t true for most other tools as they don’t control every pixel on the screen…​\nWe don’t have that level of control even in regular native apps where an OS update (or vendor customization) can wreck havoc in your meticulously crafted UI.\nLearning to do this in a portable and consistent way is challenging. Some of that is because of the rough edges of our tools \u0026amp; some of that is because of outdated docs/videos. I spend almost all of my time writing documentation, answering your questions on stackoverflow/elsewhere but this is clearly not enough.\nOur open source community is hugely helpful but it isn’t as effective for things like high quality guides. Docs are probably the hardest things to build using a community process.\nHow do we Fix This? This will require some work…​\nWhen I was a young programmer in my late teens and early 20s I already knew quite a lot but I also had bad habits…​\nI picked a lot of bad practices from learning on my own and I might have ended up very differently had I not stumbled into amazing mentors who guided me in the right direction. These great mentors transformed the way I code communicate \u0026amp; think. They were pivotal in my career.\nWhen we started the LWUIT project at Sun Microsystems we spent a lot of with customers trying to understand the difficulties they were addressing firsthand. At that point I realized that not only was I mentoring the junior developers I was working with, I was getting a lot in return. I was able to glimpse into LWUIT thru a fresh pair of eyes and see what we got right and what we got wrong. This improved LWUIT immensely.\nThat’s why I spend almost all my time doing customer support, it teaches me a lot and allows me to run the company in a way that makes sense for this type of product. But that’s not enough…​\nBootcamp A bootcamp isn’t a regular course. It runs over a narrow stretch of time \u0026amp; is deeply interlaced with personal 1 on 1 mentoring. This means I’ll need to seriously clear my schedule to do this but I think the value proposition is huge. Unfortunately it also means this doesn’t scale all too well either. Here I want to provide from my experience but also learn from yours so I can initiate changes and we can adapt better to fit your needs.\nThe core focus of the bootcamp would be on building a compelling UI that would be native in feel and quality without compromising on anything. The samples I gave you above are great but they’re just samples. When you need to take an app all the way from generating a certificate, designing a gorgeous UI, building a server, connecting it and putting it into production in the store this becomes a challenge with many pitfalls along the way.\nBut this is not enough, I want an end to end full stack application from mobile to server. This is important because so many developers today carry the full weight of responsibility to build a complete app including the server side, networking and everything.\nBuilding an App from Scratch to Production When I told Chen about my plan to do a 4 week bootcamp and build a full production app as part of it he had his doubts. I’m paraphrasing here but this is the gist of what he said: \u0026ldquo;you don’t really think you can build a full production grade app in 4 weeks?\u0026rdquo;.\nMy answer was: \u0026ldquo;no, I will build the app and server in two weeks!\u0026rdquo;\nThat’s ambitious but that’s exactly what a bootcamp is, it’s a startup for all intents and purposes. Building a full fledged well designed and architected app is something all of you can do within 2-4 weeks when using Java/Codename One.\nThe two additional weeks will cover a lot of things and include personal mentoring which I think is crucial for our shared success.\nMore Details Coming Soon There is so much more I would like to cover and I’ll cover some of the nitty gritty details on how this bootcamp will achieve it’s transformative goals in my post early next week. There are many logistic details that we need to sort out mostly with the company as I will find it hard to handle my day to day tasks during the bootcamp.\nIn the meantime, if you haven’t answered my email please do so as I’m still interested in hearing more. Also feel free to write and comment in the blog with thoughts/issues/concerns etc.\nI’d also appreciate sharing this with your friends \u0026amp; co-workers who might be appropriate.\nThis was the first article in a 3 part series, check out part 2 here. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDalvik — March 1, 2017 at 1:04 pm (permalink) Interesting stuff, is this for all levels?\nIs there a place to register?\nHow would this be structured?\nShai Almog — March 1, 2017 at 3:34 pm (permalink) Shai Almog says:\nJava knowledge is a must, ideally some level of Codename One experience would help but there will be optional content at the start that a person completely new to Codename One would be able to follow to get started quickly.\nI’ll answer the rest in an upcoming post.\nDalvik — March 2, 2017 at 8:45 am (permalink) Dalvik says:\nThanks! Looking forward to it!\nWill this be at a physical location or will I be able to join online?\nIgnatus Ujomor — March 2, 2017 at 9:05 am (permalink) Ignatus Ujomor says:\nI am interested in the bootcamp and want to know the date, location, cost (if any), and other requirements.\nChad Elofson — March 2, 2017 at 9:21 am (permalink) Chad Elofson says:\nThis sounds great. I have gained insight from Steve Hannah already. So, I feel this would be great to take my Codename One experience to the next level.\nLooking forward to it.\nShai Almog — March 2, 2017 at 10:02 am (permalink) Shai Almog says:\nGreat!\nI’ll announce all the details in the blog since the final dates aren’t settled (a lot of logistics around my time). Registration should open soon though.\nThe bootcamp will be over the internet with 1 on 1 sessions going over skype or something like that.\nShai Almog — March 2, 2017 at 10:03 am (permalink) Shai Almog says:\nGreat. This will be over the internet thru skype or similar tools for the 1 on 1.\nShai Almog — March 2, 2017 at 10:04 am (permalink) Shai Almog says:\nThanks, I’m sure Steve is thrilled to hear that 😉\nsalah Alhaddabi — March 2, 2017 at 3:04 pm (permalink) salah Alhaddabi says:\nDear Shai very excellent idea. Would be great if you can cover backend stuff using java ee 7 api only without third party libraries. You can for example include rest api, websocket, jms, jason processing, cdi, jpa, ejb and then present how to call web services layer from CN1 and also how to asynchrounously listen to websockets and best practices to update UI and to upliad/download images so everything is in java\nShai Almog — March 2, 2017 at 3:33 pm (permalink) Shai Almog says:\nThanks for the feedback. I’m somewhat conflicted between simple tomcat, Java EE or Spring in terms of backend. My goal is to spend as little time as possible configuring stuff and make the solution as simple as possible so people can adapt this easily to their \u0026ldquo;real world\u0026rdquo; setups.\nI don’t want to use something too exotic though, so I won’t go into some of the newer microservice style frameworks. My main focus by a huge margin is on the client, there are great Java EE/Spring etc. courses out there and I don’t think I can improve on them. What I want to do is show how all this ties together to a single cohesive product.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/full-stack-java-bootcamp/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/full-stack-java-bootcamp/full-stack-java-bootcamp.jpg\"\u003e\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eIt’s LIVE! Check out the bootcamp signup \u003ca href=\"https://codenameone.teachable.com/p/full-stack-java-mobile-app-bootcamp/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere\u003c/a\u003e.\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eThanks again to everyone who answered my questions. I got tons of valuable feedback on our work \u0026amp; what you would like to learn. It was super helpful and I’m grateful to all of you as you are literally shaping how this bootcamp (and the future of Codename One). I’m sorry if I was brief in some of the thank you emails, it took some time as I wrote them all personally and worked well into the night the other day.\u003c/p\u003e","title":"Full Stack Java Bootcamp"},{"content":"\nJust last week I mentioned that we wanted to get push working on Windows \u0026amp; we’re pretty thrilled to announce that it’s available already…​ This means that we now support push on pretty much any major device with the exception of the Safari web browser.\nAs part of this change we also decided to change the push keys for the JavaScript push implementation so I suggest waiting for the next update before you push out a new version of your app. The crux of the issue was that the web push key included illegal characters for the web so the fix when using the client side send push API’s is to encode the arguments to the server.\nHowever, considering that someone might not do that change or might have other bugs in his system we decided to base64 the keys of the JavaScript/Windows push API’s. This way they will be safe to use anywhere regardless of encoding.\nThe server side push API changed a bit (we updated the developer guide to reflect this) as Windows needs additional arguments. Specifically the push servers expect two new arguments: sid \u0026amp; client_secret both of which you can get from the Windows Store when submitting your app.\nThis values are also required on the client but the Push API was getting a bit big so we ended up rewriting the Push API to use a builder pattern. So instead of using a single Push.sendPush(…​) static call we use something like this:\nnew Push(PUSH_TOKEN, \u0026quot;Hello World\u0026quot;, deviceKey) .apnsAuth(cert, pass, ITUNES_PRODUCTION_PUSH) .gcmAuth(GCM_SERVER_API_KEY) .wnsAuth(WNS_SID, WNS_CLIENT_SECRET) .send(); This allows more flexibility e.g. if our app isn’t available for iOS or we know we are sending to one device that isn’t an iOS device we can just avoid the apnsAuth entry altogether. It’s also far more descriptive and intuitive.\nFinally We need to make push simpler and smoother, we need to redo the video tutorials for it which are out of date by now and we need the ability to track users in a generic way to make push \u0026ldquo;seamless\u0026rdquo;.\nHowever, having said all that I think we are in a great place in terms of push support as we now support almost every platform that allows it and the functionality is very solid.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/push-almost-everywhere/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/push-almost-everywhere/push-megaphone.png\"\u003e\u003c/p\u003e\n\u003cp\u003eJust last week I mentioned that we wanted to get push working on Windows \u0026amp; we’re pretty thrilled to announce that it’s available already…​ This means that we now support push on pretty much any major device with the exception of the Safari web browser.\u003c/p\u003e\n\u003cp\u003eAs part of this change we also decided to change the push keys for the JavaScript push implementation so I suggest waiting for the next update before you push out a new version of your app. The crux of the issue was that the web push key included illegal characters for the web so the fix when using the client side send push API’s is to encode the arguments to the server.\u003c/p\u003e","title":"Push (Almost) Everywhere"},{"content":"\nBefore we go into the tip I’d like to start with an apology to all the people I didn’t get back to. Earlier today I sent an email asking for help with the upcoming Codename One bootcamp. The anticipation and resulting email flood took me totally off-guard as I expected a couple of dozen responses in the best case scenario and got much more…​\nI started answering as fast as I could and getting back to people I already answered in the back and forth but quickly this became untenable and I’m seeing my backlog pile growing. Chen and others around here tried to help but I prefer to do this personally as I’d like the feedback to sink into my brain not as an afterthought as it is very valuable!\nI promise that by tomorrow I’ll answer each and every one of you, I’m not doing it in order of arrival so some might wait while others get instant feedback (that’s mostly an oddity of intercom that makes it hard to work sensibly).\nAnyway I read everything and agree with pretty much all of your ideas so a huge thank you, to all of you who took the time to write.\nIf you didn’t get a chance to write to me please answer that e-mail now , help shape our upcoming bootcamp \u0026amp; effectively make it yours. The thing that drives Codename One is the community and this is where it’s most obvious.\nAnd now, something completely different…​\nTable Row Selection When we designed the Codename One Table class we tried to keep it as far as possible from the Swing JTable. I loved that class but during my years as a consultant I was struck by the amount of bad JTable code that was floating around. Developers just couldn’t grasp so many of the nuances related to the delicate balance of renderer/editor…​\nI hope we did a better job with our Table class, I know it’s not easy but having gone thru tables in many OS’s (don’t get me started on iOS) I would say our approach is MUCH easier.\nOne of the tricks we do in Table is a \u0026ldquo;forced refresh\u0026rdquo; which we trigger thru tbl.setModel(tbl.getModel()) this effectively saves us from the need to derive the model and fire the proper model changed event. It allows us to store state in a different location than the model which we normally shouldn’t do but it’s a hack that’s useful as a shortcut.\nE.g. a recent stackoverflow question asked about highlighting a table row. The asker eventually just meant a checkbox mode (I guess he didn’t think about the fact that ctrl-click doesn’t work in touch UI’s) but this is the perfect example for this use case.\nWe keep the selection in a variable and putting it into the model seems redundant. So when we need to refresh the other cells in the row we can just use that trick as a workaround.\nForm hi = new Form(\u0026quot;Table\u0026quot;, new BorderLayout()); TableModel model = new DefaultTableModel(new String[] {\u0026quot;Col 1\u0026quot;, \u0026quot;Col 2\u0026quot;, \u0026quot;Col 3\u0026quot;}, new Object[][] { {\u0026quot;Row 1\u0026quot;, \u0026quot;Row A\u0026quot;, \u0026quot;Row X\u0026quot;}, {\u0026quot;Row 2\u0026quot;, \u0026quot;Row B can now stretch\u0026quot;, null}, {\u0026quot;Row 3\u0026quot;, \u0026quot;Row C\u0026quot;, \u0026quot;Row Z\u0026quot;}, {\u0026quot;Row 4\u0026quot;, \u0026quot;Row D\u0026quot;, \u0026quot;Row K\u0026quot;}, }) { public boolean isCellEditable(int row, int col) { return col != 0; } }; Table table = new Table(model) { private int selectedRow = -1; @Override protected Component createCell(Object value, int row, int column, boolean editable) { Component cell; if(row \u0026lt; 0) { cell = super.createCell(value, row, column, editable); } else { cell = new Button(value.toString()); cell.setUIID(\u0026quot;TableCell\u0026quot;); ((Button)cell).addActionListener(e -\u0026gt; { selectedRow = row; setModel(getModel()); }); } if(selectedRow \u0026gt; -1 \u0026amp;\u0026amp; selectedRow == row) { cell.getAllStyles().setBgColor(0xff0000); cell.getAllStyles().setBgTransparency(100); } return cell; } @Override protected TableLayout.Constraint createCellConstraint(Object value, int row, int column) { TableLayout.Constraint con = super.createCellConstraint(value, row, column); if(row == 1 \u0026amp;\u0026amp; column == 1) { con.setHorizontalSpan(2); } con.setWidthPercentage(33); return con; } }; hi.add(BorderLayout.CENTER, table); hi.show(); Figure 1. Selected table row from the code above\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-select-table-row/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-select-table-row/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eBefore we go into the tip I’d like to start with an apology to all the people I didn’t get back to. Earlier today I sent an email asking for help with the upcoming Codename One bootcamp. The anticipation and resulting email flood took me totally off-guard as I expected a couple of dozen responses in the best case scenario and got much more…​\u003cbr\u003e\nI started answering as fast as I could and getting back to people I already answered in the back and forth but quickly this became untenable and I’m seeing my backlog pile growing. Chen and others around here tried to help but I prefer to do this personally as I’d like the feedback to sink into my brain not as an afterthought as it is \u003cstrong\u003every valuable\u003c/strong\u003e!\u003c/p\u003e","title":"TIP: Select Table Row"},{"content":"\nThis weeks release adds support for JavaScript push but I’d recommend you don’t use it in production yet…​ The main issue is that we might change the way JavaScript push keys are generated so it might be better to put this on hold or only experiment with this for now. Regardless it’s a pretty big change to the push server so we have the old version standing by and might revert it if things get hairy.\nWe don’t have huge new features but we did make some big changes, e.g. the pull request from jaanushansen is pretty ambitious and might impact Android text editing significantly so keep your eye out on this.\nWe also changed the behavior of IMEI on Android tablets following this pull request from JrmyDev.\nWe’ve had a lot of activity on stackoverflow this past week, here are some interesting posts:\nFirst Jeremy asked about debugging using the Codename One sources when using the Eclipse IDE. Currently our instructions are exclusive to NetBeans. I recall a community member did this a while back but I can’t find the thread in the developer group. If anyone recalls that (or if you did this yourself) please take a look at that post and we’d appreciate an edit to the developer guide too!\nJordan asked a very different question that I think people should ask more often: how to create the UI in this screenshot. Ideally we’d have a gallery with common screenshots and instructions on how to implement every such UI as most UI patterns are very similar.\nGraham asked whether Kotlin can be used with Codename One I explained the challenges and then Steve clarified some of the finer points of the process. The short answer is \u0026ldquo;not officially\u0026rdquo;, it’s possible but some work might be required. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\n3lix — February 24, 2017 at 5:15 pm (permalink) 3lix says:\nIs 3.6.0 the lastest update?\nI thought last week you mentioned pushing updates: https://www.codenameone.com…\nBut I think the lastest update I see is 3.6.0 https://www.codenameone.com… released on 2017/01/10.\nThanks!\nShai Almog — February 25, 2017 at 5:29 am (permalink) Shai Almog says:\nFYI if you include URL’s they go into moderation automatically to prevent SEO spam. We approve automatically if it’s relevant.\nRight now we are only pushing updates to the libraries/servers. A plugin update is a bigger deal and we don’t do it as often. We aim for once a month or two.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-44/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-44/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis weeks release adds support for JavaScript push but I’d recommend you don’t use it in production yet…​ The main issue is that we \u003cstrong\u003emight\u003c/strong\u003e change the way JavaScript push keys are generated so it might be better to put this on hold or only experiment with this for now. Regardless it’s a pretty big change to the push server so we have the old version standing by and might revert it if things get hairy.\u003c/p\u003e","title":"Questions of the Week 44"},{"content":"\nWe’ve had a lot of security related posts in the past few months as we refined many edge cases with some customers. These posts are difficult to comb through as they are all over the place, and it’s hard to get a glance of \u0026ldquo;what’s available.\u0026rdquo;\nSo we added a new security section to the developer guide which adds some general information about Codename One security and includes most of the details about what you can do in terms of security.\nIf you have any ideas or notice anything missing don’t forget that you can edit every section of the developer guide in our wiki and this includes the security section which is available in the wiki here.\nIf this isn’t something you know how to fix please feel free to comment below or open an issue in the issue tracker.\nWhat’s Next? The big thing on my personal \u0026ldquo;wish list\u0026rdquo; for the next update of the developer guide is a cn1libs section that will cover some of the top Codename One libraries. This isn’t included yet but if you have a cn1lib that you’d like to feature in the developer guide you can just edit the wiki section for cn1libs and add your own.\nI hope to have some of our big cn1libs out there as reference and when I do that I’ll post about it again so 3rd party library authors can align.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/security-section/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/security-section/security.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve had a lot of security related posts in the past few months as we refined many edge cases with some customers. These posts are difficult to comb through as they are all over the place, and it’s hard to get a glance of \u0026ldquo;what’s available.\u0026rdquo;\u003c/p\u003e\n\u003cp\u003eSo we added a new \u003ca href=\"/developer-guide#_security\"\u003esecurity section\u003c/a\u003e to the developer guide which adds some general information about Codename One security and includes most of the details about what you can do in terms of security.\u003c/p\u003e","title":"Security Section"},{"content":"\nUp until now push notification in Codename One only worked for Android \u0026amp; iOS devices. This is about to change this weekend when the JavaScript port should (almost) seamlessly start working with push!\nThis is pretty cool as push to the web is a pain with every browser taking a somewhat different route but with Codename One this will \u0026ldquo;mostly\u0026rdquo; work.\nThe JavaScript port will generate push keys that match the notation cn1-web.\nAt this time we support:\nFirefox (Version 50)\nChrome (Version 49)\nOpera (Version 42)\nChrome for Android (Version 56)\n__ Edge/IE don’t currently support push. We might support Edge as it becomes available there Firefox doesn’t require any special setup for Push. If your main class implements the PushCallback interface, it should just work.\nChrome uses GCM for its push notifications – the same system that Android uses. The directions for setting up a GCM account are the same as provided in the Android section, and you can reuse the same GCM_SENDER_ID and GCM_SERVER_KEY values. You need to add a build hint so that the GCM_SENDER_ID will be added to the app’s manifest file:\nYou don’t need to do anything special and your push callback will be invoked when you send a push to the given key. That’s pretty cool.\nSo currently we use the setProperty() method of Display to set the sender ID but this won’t work for Chrome as we need that value during build time. Just move that value to the build hint gcm.sender_id and you can remove the setProperty statement once this change goes live as it will become implicit.\n__ Notice we used gcm.sender_id and not javascript.sender_id to highlight that this value is common for GCM implementations Safari is problematic as it doesn’t use the same semantics of any other push service. It doesn’t act like iOS or like other browsers. So at this time we don’t plan on supporting Safari as it’s audience is mostly in mobile where we have proper native app support.\nAvailability \u0026amp; More Push on UWP is something we hope to introduce in the near future as well. We began some work on this but it is not ready at this time. Hopefully we’ll have a completely universal push solution in the near future.\nWe will update the new push support this Friday which should include a push server update. Once that update goes in push for web should \u0026ldquo;just work\u0026rdquo; but would require a new build.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/push-on-javascript/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/push-on-javascript/push-megaphone.png\"\u003e\u003c/p\u003e\n\u003cp\u003eUp until now push notification in Codename One only worked for Android \u0026amp; iOS devices. This is about to change this weekend when the JavaScript port should (almost) seamlessly start working with push!\u003cbr\u003e\nThis is pretty cool as push to the web is a pain with every browser taking a somewhat different route but with Codename One this will \u0026ldquo;mostly\u0026rdquo; work.\u003c/p\u003e\n\u003cp\u003eThe JavaScript port will generate push keys that match the notation \u003ccode\u003ecn1-web\u003c/code\u003e.\u003c/p\u003e","title":"Push on JavaScript"},{"content":"\nA very common request is support for rich text in Codename One, this is hard to do in a generic/performant cross platform way but can be done as I explained in my answer here. This is pretty common though so it might be worth it doing this in a generic way.\nBuilding a \u0026ldquo;proper\u0026rdquo; rich text view would take some work as there are many edge cases \u0026amp; complexities. However, since we already have an XML parser that’s perfectly capable of parsing HTML I decided to try a very simple HTML based syntax just to show how easy it would be to create something generic like this. I avoided the \u0026ldquo;link\u0026rdquo; use case as that would require some link handler code and I avoided font sizes/colors as I didn’t want to go into attributes and related complexities.\nInstead I just added support for bold and italic while demonstrating that simple things like line breaks still work:\nForm hi = new Form(\u0026quot;Rich Text\u0026quot;, BoxLayout.y()); class RichTextView extends Container { private String text; public RichTextView() { __**(1)** } public RichTextView(String text) { setText(text); } public final void setText(String text) { this.text = text; final Font defaultFont = Font.createTrueTypeFont(\u0026quot;native:MainRegular\u0026quot;, \u0026quot;native:MainRegular\u0026quot;); __**(2)** final Font boldFont = Font.createTrueTypeFont(\u0026quot;native:MainBold\u0026quot;, \u0026quot;native:MainBold\u0026quot;); final Font italicFont = Font.createTrueTypeFont(\u0026quot;native:ItalicRegular\u0026quot;, \u0026quot;native:ItalicRegular\u0026quot;); final int sizeOfSpace = defaultFont.charWidth(' '); __**(3)** XMLParser parser = new XMLParser() { private Font currentFont = defaultFont; @Override protected void textElement(String text) { if(text.length() \u0026gt; 0) { if(text.indexOf(' ') \u0026gt; -1) { for(String s : StringUtil.tokenize(text, ' ')) { createComponent(s); } } else { createComponent(text); } } } private void createComponent(String t) { Label l = new Label(t); Style s = l.getAllStyles(); s.setFont(currentFont); __**(4)** s.setPaddingUnit(Style.UNIT_TYPE_PIXELS); s.setPadding(0, 0, 0, sizeOfSpace); s.setMargin(0, 0, 0, 0); add(l); } @Override protected boolean startTag(String tag) { switch(tag.toLowerCase()) { case \u0026quot;b\u0026quot;: currentFont = boldFont; break; case \u0026quot;i\u0026quot;: currentFont = italicFont; break; } return true; } @Override protected void endTag(String tag) { currentFont = defaultFont; } @Override protected void attribute(String tag, String attributeName, String value) { } @Override protected void notifyError(int errorId, String tag, String attribute, String value, String description) { Log.p(\u0026quot;Error during parsing: \u0026quot; + tag); } }; try { parser.eventParser(new CharArrayReader((\u0026quot;\u0026lt;body\u0026gt;\u0026quot; + text + \u0026quot;\u0026lt;/body\u0026gt;\u0026quot;).toCharArray())); __**(5)** } catch(IOException err) { Log.e(err); } } public String getText() { return text; } } hi.add(new RichTextView(\u0026quot;This is plain text \u0026lt;b\u0026gt;this is bold\u0026lt;/b\u0026gt; and \u0026lt;i\u0026gt;this is italic\u0026lt;/i\u0026gt; and all of this breaks lines nicely as well....\u0026quot;)); hi.show(); This code produces the image below. Notice the following things about it:\n__1 The default layout is FlowLayout which works well for simple things like that but might be a little flaky for complex use cases __2 For simplicity I just hardcoded the fonts __3 I removed the spaces and padding/margin. Then I used the width of the spaces to re-add a space in the form of padding. This allows line breaks on word boundaries __4 Here I reset the individual padding/margin to 0 except for the space (see \u0026lt;3\u0026gt;) __5 I need to wrap the text in a \u0026lt;body\u0026gt; tag as XML requires one parent tag. I use the event callback parser instead of DOM as it is a bit more convenient (and faster) Figure 1. The demo above running in the simulator\nMoving On The obvious question is \u0026ldquo;why isn’t this in Codename One?\u0026rdquo;.\nThis is a proof of concept, the devil is in the details with things such as this and once we start going into them this will drag us down a huge rabbit hole. However, your personal use case might not be as extensive as ours would need to be. With this as a starting point I’m sure most use cases could be adapted to handle some form of rich text within your app.\nI chose to use HTML because I already had a parser but the basic concept should work well for any markup language out there. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — April 6, 2018 at 10:17 pm (permalink) Thank you Shai, your \u0026ldquo;proof of concept\u0026rdquo; (as you definited it) is exactly what I was looking for. In some simple circumstances, it can be a good replacement for SpanLabel and an easier and better solution than BrowserComponent (expecially if I need a text that should be automatically internationalized like in Label and SpanLabel). However, I found two issues in your code, that are easy to fix. The first one is that the font size is zero, so no text is shown. To solve, I changed the fonts definitions so:\nint fontSize = Display.getInstance().convertToPixels(3);\nfinal Font defaultFont = Font.createTrueTypeFont(\u0026ldquo;native:MainRegular\u0026rdquo;, \u0026ldquo;native:MainRegular\u0026rdquo;).derive(fontSize, Font.STYLE_PLAIN);\nfinal Font boldFont = Font.createTrueTypeFont(\u0026ldquo;native:MainBold\u0026rdquo;, \u0026ldquo;native:MainBold\u0026rdquo;).derive(fontSize, Font.STYLE_PLAIN);\nfinal Font italicFont = Font.createTrueTypeFont(\u0026ldquo;native:ItalicRegular\u0026rdquo;, \u0026ldquo;native:ItalicRegular\u0026rdquo;).derive(fontSize, Font.STYLE_PLAIN);\nThe second issue is that the text is not internationalized. To solve, at the start of the method setText I added the code:\nLabel internalization = new Label(text);\ntext = internalization.getText();\nShai Almog — April 7, 2018 at 4:36 am (permalink) Shai Almog says:\nThanks. Odd that I didn’t see that.\nText is internationalized as individual words which probably isn’t what you’d want.\nYou can easily internationalize the body of HTML and this example using the UIManager.getInstance().localize() method.\nGareth Murfin — August 8, 2018 at 3:23 am (permalink) Gareth Murfin says:\nGreat little widget, with these fixes its showing ok .\nDurank — September 30, 2020 at 12:49 pm (permalink) Durank says:\nProvide and example how to applie color to specific portion of text\nShai Almog — October 1, 2020 at 6:40 am (permalink) Shai Almog says:\nThere’s nothing built in but it should be trivial to add that as it isn’t much different than setting bold styles. You can parse a font tag or a custom tag of your own and set the color any way you want. That’s the point of including the source and not building this into Codename One.\nJulio Valeriron Ochoa — September 22, 2021 at 3:03 pm (permalink) Julio Valeriron Ochoa says:\nPlease provide support to color and size\nLianna Casper — September 23, 2021 at 1:54 am (permalink) Lianna Casper says:\nThis is literally the same. Just add int currentColor next to currentFont. Then when a color attribute is hit set the value of the currentColor and reset it to the default when exiting the tag.\nThen just do an s.setFgColor(currentColor);.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-lightweight-rich-text-view/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-lightweight-rich-text-view/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA very common request is support for rich text in Codename One, this is hard to do in a generic/performant cross platform way but can be done as I explained in my answer \u003ca href=\"http://stackoverflow.com/questions/42288518/html-link-for-one-word-in-label-text-in-codename-one\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere\u003c/a\u003e. This is pretty common though so it might be worth it doing this in a generic way.\u003c/p\u003e\n\u003cp\u003eBuilding a \u0026ldquo;proper\u0026rdquo; rich text view would take some work as there are many edge cases \u0026amp; complexities. However, since we already have an XML parser that’s perfectly capable of parsing HTML I decided to try a very simple HTML based syntax just to show how easy it would be to create something generic like this. I avoided the \u0026ldquo;link\u0026rdquo; use case as that would require some link handler code and I avoided font sizes/colors as I didn’t want to go into attributes and related complexities.\u003c/p\u003e","title":"TIP: Lightweight Rich Text View"},{"content":"\nSurprisingly the big VM update we had last week didn’t trigger any major regressions but we did break some versioned build behavior with the string obfuscation feature. Todays update is far more tame and should mostly include minor bug fixes and not to many new/disruptive features.\nThere were a lot of questions but most of them weren’t broad enough for this forum, so I’ll discuss only two questions and in both cases I’ll talk less about the question and more about the implications.\nBeck asked about an issue with QR code scanning a while back. This is an issue with a 3rd party library and as a result there wasn’t much we could do. I eventually submitted a pull request to the library but it was ignored and didn’t seem to solve the issue completely. Eventually we decided to patch the library ourselves and updated the cn1lib extensions today.\nThis highlights the fine line between using our libraries and 3rd parties, we can’t warrant community code but if something drags out too long we try to help. It’s not something we can guarantee though.\nAndrew asked about the security of Storage to which Diamond gave a great answer. But this does highlight the fact that security isn’t covered in depth anywhere so I can’t just point the developer to the security section of the developer guide…​\nThis is something we hope to remedy now that with the results of our recent efforts to improve some of the security features in Codename One. So hopefully in the 3.7 timeline we will have a security section in the developer guide. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbeck — February 17, 2017 at 6:26 pm (permalink) beck says:\nThankyou shai.. much appreciated. It works in older devices but in marshmallow there is a permission denial error. Please have a look http://stackoverflow.com/qu… thankyou\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-43/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-43/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSurprisingly the big VM update we had last week didn’t trigger any major regressions but we did break some versioned build behavior with the \u003ca href=\"/blog/obfuscated-constants.html\"\u003estring obfuscation feature\u003c/a\u003e. Todays update is far more tame and should mostly include minor bug fixes and not to many new/disruptive features.\u003c/p\u003e\n\u003cp\u003eThere were a lot of questions but most of them weren’t broad enough for this forum, so I’ll discuss only two questions and in both cases I’ll talk less about the question and more about the implications.\u003c/p\u003e","title":"Questions of the Week 43"},{"content":"\nI wrote on the Friday post about a few cool pull requests from Diamond but I didn’t provide a usage example for that API. Probably the best usage example is gmail style undo. If you are not a gmail user then the gmail app essentially never prompts for confirmation!\nIt just does whatever you ask and pops a \u0026ldquo;toast message\u0026rdquo; with an option to undo. So if you clicked by mistake you have 3-4 seconds to take that back!\nThis is great and I wanted it for a while in Codename One. Diamond beat me to it by adding the ability to have an action on a Toast message. This simple example shows you how you can undo any addition to the UI in a similar way to gmail:\nForm hi = new Form(\u0026quot;Undo\u0026quot;, BoxLayout.y()); Button add = new Button(\u0026quot;Add\u0026quot;); add.addActionListener(e -\u0026gt; { Label l = new Label(\u0026quot;Added this\u0026quot;); hi.add(l); hi.revalidate(); ToastBar.showMessage(\u0026quot;Added, click here to undo...\u0026quot;, FontImage.MATERIAL_UNDO, ee -\u0026gt; { l.remove(); hi.revalidate(); }); }); hi.add(add); hi.show(); That’s a pretty cool feature. I’m sure there are other use cases people can come up with…​\nBetter URLImage URLImage is great, it really changed the way we do some things in Codename One and I’m a bit shocked it took us years to introduce it…​\nHowever, when we introduced it we didn’t have support for cache filesystem or for the JavaScript port. The cache filesystem is probably the best place for images of URLImage so supporting that as a target is a \u0026ldquo;no brainer\u0026rdquo; but JavaScript seems to work so why would it need a special case?\nWell, JavaScript already knows how to download and cache images from the web. URLImage is actually a step back from the things a good browser can do so why not use the native abilities of the browser when we are running there and fallback to using the cache filesystem if it’s available and as a last resort go to storage…​\nThat’s exactly what the new method of URLImage does:\npublic static Image createCachedImage(String imageName, String url, Image placeholder, int resizeRule); There are a few important things you need to notice about this method:\nIt returns Image and not URLImage. This is crucial. Down casting to `URLImage* will work on the simulator but might fail in some platforms (e.g. JavaScript) so don’t do that!\nSince this is implemented natively in JavaScript we need a different abstraction for that platform.\nIt doesn’t support image adapters and instead uses a simplified resize rule. Image adapters work on URLImage since we have a lot of control in that class. However, in the browser our control is limited and so an adapter won’t work.\nIf you do use this approach it would be far more efficient when running in the JavaScript port and will make better use of caching in most OS’s.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/toastbar-actions-urlimage-caching/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/toastbar-actions-urlimage-caching/new-features-5.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI \u003ca href=\"/blog/questions-of-the-week-42.html\"\u003ewrote on the Friday\u003c/a\u003e post about a few cool pull requests from Diamond but I didn’t provide a usage example for that API. Probably the best usage example is gmail style undo. If you are not a gmail user then the gmail app essentially never prompts for confirmation!\u003c/p\u003e\n\u003cp\u003eIt just does whatever you ask and pops a \u0026ldquo;toast message\u0026rdquo; with an option to undo. So if you clicked by mistake you have 3-4 seconds to take that back!\u003c/p\u003e","title":"ToastBar Actions \u0026 URLImage Caching"},{"content":"\nOne of the first things a hacker will do when compromising an app is look at it. E.g. if I want to exploit a bank’s login UI I would look at the label next to the login and then search for it in the decompiled code. So if the UI has the String \u0026ldquo;enter user name and password\u0026rdquo; I can search for that.\nIt won’t lead directly to a hack or exploit but it will show you the approximate area of the code where we should look and it makes the first step that much easier. Obfuscation helps as it removes descriptive method names but it can’t hide the Strings we use in constants. So if an app has a secret encoding it even slightly can make a difference…​\nNotice that this is a temporary roadblock as any savvy hacker would compile the app and connect a debugger eventually (although this is blocked in release builds) and would be able to inspect values of variables/flow. But the road to reverse engineering the app would be harder even with a simple xor obfuscation.\n__ I’m not calling this encoding or encryption since it is neither. It’s a simple obfuscation of the data We thought about adding this to all the constants in the application as an additional security measure but this would cost in size/performance so eventually we decided to leave this to you. We added two simple methods to the Util class:\npublic static String xorDecode(String s); public static String xorEncode(String s); They use a simple xor based obfuscation to make a String less readable. E.g. if you have code like this:\nprivate static final String SECRET = \u0026quot;Don't let anyone see this....\u0026quot;; And you’d obviously be concerned about secret, then this would make it slightly harder to find:\n// Don't let anyone see this.... private static final String SECRET = Util.xorDecode(\u0026quot;RW1tI3Ema219KmpidGFhdTFhdnE1Yn9xajQ1MjM=\u0026quot;); Notice that this is not secure , if you have a crucial value that must not be found you need to store it in the server. There is no alternative as everything that is sent to the client can be compromised by a determined hacker\n__ Use the comment to help you find the string in the code Our builtin user specific constants will now be obfuscated with this method, e.g. normally an app built with Codename One carries some internal data such as the user who built the app etc. This will be obfuscated now. We built this small app to encode strings easily so we can copy and paste them into our app easily:\nForm hi = new Form(\u0026quot;Encoder\u0026quot;, BoxLayout.y()); TextField bla = new TextField(\u0026quot;\u0026quot;, \u0026quot;Type Text Here\u0026quot;, 20, TextArea.ANY); TextArea encoded = new TextArea(); SpanLabel decoded = new SpanLabel(); hi.addAll(bla, encoded, decoded); bla.addDataChangedListener((a, b) -\u0026gt; { String s = bla.getText(); String e = Util.xorEncode(s); encoded.setText(e); decoded.setText(Util.xorDecode(e)); hi.getContentPane().animateLayout(100); }); hi.show(); This allows you to type in the first text field and the second text area shows the encoded result. We used a text area so copy/paste would be easy.\nFor your convenience check out the demo below that encodes strings. You can copy and paste the encoded String to your application. It was built using the JavaScript port of Codename One and can thus run in the browser.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/obfuscated-constants/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/obfuscated-constants/security.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the first things a hacker will do when compromising an app is look at it. E.g. if I want to exploit a bank’s login UI I would look at the label next to the login and then search for it in the decompiled code. So if the UI has the String \u0026ldquo;enter user name and password\u0026rdquo; I can search for that.\u003c/p\u003e\n\u003cp\u003eIt won’t lead directly to a hack or exploit but it will show you the approximate area of the code where we should look and it makes the first step that much easier. Obfuscation helps as it removes descriptive method names but it can’t hide the Strings we use in constants. So if an app has a secret encoding it even slightly can make a difference…​\u003c/p\u003e","title":"Obfuscated Constants"},{"content":"\nTLDR: ParparVM is now up to 2.8x faster, and produces binaries that are 15%-20% smaller than before.\nIf you build your app for iOS today, you may notice a performance boost due to some improvements to ParparVM – the AOT compiler we use to build Codename One apps for iOS. Read on for a short history of ParparVM, as well as some details about these improvements.\nA Brief History Of ParparVM In the beginning, Codename One used XMLVM to build apps for iOS. It worked by converting Java byte-codes into its own XML representation, and then converting that XML into C-code. Unfortunately XMLVM was an academic project, and was announced in 2014 that development on it would be discontinued. We were faced with a choice. Do we continue to use XMLVM and simply support it ourselves, or do we migrate to something else. At the time RoboVM was an exciting new technology that compiled Java to LLVM and could produce iOS apps. I had also created a proof of concept port using Avian, an AOT compiler for Java that could produce iOS binaries. A fourth option, which seemed overly ambitious at the time, was to create our own tool from scratch. Ultimately, that is the avenue that was chosen, and ParparVM was born.\nWhy Didn’t We Choose Avian or RoboVM? At the time it may have seemed like a logical choice to go with RoboVM, but this was deemed not an option because it was extremely important that we be able to use Apple’s official tool-chain for building apps. That would ensure that we wouldn’t hit a dead end. A key requirement of ParparVM was to produce actual X-code projects that could be built using Apple’s tool-chain. This had several benefits. In addition to \u0026ldquo;future-proofing\u0026rdquo; us in the case that Apple might start rejecting apps that didn’t use the official tools, it provided the ability to use Apple’s mature tools for profiling and debugging if needed.\nIn the Beginning: A Stack-Based VM in C In the beginning ParparVM generated a faithful representation of java’s stack-based virtual machine in C-code. This made it very easy to verify the correctness of the code. Using our own stack also enabled us to implement a highly efficient, concurrent garbage collector that would avoid pauses. XMLVM had used the Boehm conservative garbage collector that would need to \u0026ldquo;stop the world\u0026rdquo; to collect garbage. ParparVM, in contrast, uses its own concurrent Mark-sweep garbage collector that very nearly eliminates all such pauses.\nOnce this was stable, we started introducing a few optimizations for common sequences of stack instructions. E.g. A statement like:\nreturn 1; in Java would produce bytecodes to:\nAdd \u0026ldquo;1\u0026rdquo; to the stack.\nPop \u0026ldquo;1\u0026rdquo; off the stack and return it.\nClearly, it would be better for the resulting C code to simply return 1, just like the Java code, so ParparVM would optimize cases like this to do just that.\nHowever there were multitudes of other cases that we left unoptimized. E.g. The instruction:\nint result = 20 + this.height * width; would generate 7 stack operations. The C-compiler (LLVM) would help optimize this a bit, but there is only so much it could do.\nThings like this would cause ParparVM to perform poorly in some micro benchmarks, but it didn’t factor in to actual perceived app performance and user experience because most of the critical code (especially related to UI and graphics) is written in native C code, and 90% of CPU time is spent in that code.\nImplementing Key Methods in Native C Once ParparVM was stable, we started optimizing common use cases by implementing \u0026ldquo;important\u0026rdquo; methods in native code. Many Math, String, and StringBuilder methods were implemented in native C since those are core to many applications. As users presented use cases that didn’t perform well (usually in crunching large amounts of data), we would profile and ease the bottlenecks by implementing more things natively.\nBy the time Codename One 3.4 was released, general performance had improved dramatically. Native implementations of String methods made the most common data tasks (parsing JSON and XML) almost on par with native code. If an app needed additional performance for certain tasks, they could always use native interfaces to get a boost.\nThere remained much low-hanging fruit for optimizing the actual generated C-code produced by ParparVM, this was placed on the back-burner since performance for key use cases had already been optimized with native code directly – and perceived performance, which related mostly to graphics rendering, did not depend on java code to a great extent.\nPresent Day: A New Reason to Revisit Optimizations ParparVM remained largely unchanged and stable through Codename One 3.5 and 3.6, but recently we ran into an issue where clang was having difficulty compiling very large C methods. This gave us some motivation to optimize some of the generated C-code again. This time, the impetus was a desire to reduce the size of the generated code.\nThe use case that we were provided with included hundreds method invocations to construct a GeneralPath. Each java instruction looked like:\n((GeneralPath) shape).curveTo(105.305275, 167.71288, 105.24711, 168.68971, 105.457146, 169.88364); The resulting C-code for each of these would be over 20 lines of code. It would add the shape and each of the numbers to the stack, then call the function which would unwind the stack.\nI was able to reduce this down to the point where the C-code was pretty much identical to the Java code (disregarding method naming conventions), and lines of code in the method were reduced by 80%. This solved Clang \u0026ldquo;hanging\u0026rdquo; problem, and improved performance.\nLet’s do ALL the Optimizations! Fixing the code size issue in this special case made me realize just how easy it would be to implement all the optimizations. So I set to work trying to eliminate as many stack operations as possible. In many cases now, the resulting C code is line-for-line the same as the original Java code. Cutting out the middle-man (the stack), I hoped, would also allow LLVM to optimize the code more aggressively.\nBenchmarks I hoped that my optimizations would produce a noticeable difference in performance. I would have been happy with a 25% improvement. So I set up a micro benchmark to see how it compared.\nTo start with, I created a method that calculates the largest prime number less than some large value. Then I created a benchmark that would run this method 100 times on some large value. The method is as follows:\npublic static final int getMaxPrimeBefore(int limit) { boolean[] sieve = new boolean[limit]; Arrays.fill(sieve, true); sieve[0] = false; sieve[1] = false; int largest = 0; for (int p = 2; p \u0026lt; limit; p++) { if (sieve[p]) { largest = p; for (int np = p * 2; np \u0026lt; limit; np += p) { sieve[np] = false; } } } return largest; } This would test performance on local variable usage, array element access, arithmetic, and if/else branches. Running this benchmark on my iPhone 6S using Codename One 3.6 (i.e. before the recent optimizations) resulted in an average time of 231ms to run getMaxPrimeBefore(4000000). Running it using the latest Codename One (i.e. after optimizations), this time was reduced to 113ms. That is a performance increase of over 2x.\nNow, to test out performance of static variable access, I modified the benchmark slightly to use static variables instead of local variables:\nprivate static boolean[] staticSieve; private static int staticLargest; private static int staticP; private static int staticNp; private static int staticLimit; public static final int getMaxPrimeBeforeStaticVars(int limit) { staticLimit = limit; staticSieve = new boolean[staticLimit]; Arrays.fill(staticSieve, true); staticSieve[0] = false; staticSieve[1] = false; staticLargest = 0; for (staticP = 2; staticP \u0026lt; staticLimit; staticP++) { if (staticSieve[staticP]) { staticLargest = staticP; for (staticNp = staticP * 2; staticNp \u0026lt; staticLimit; staticNp += staticP) { staticSieve[staticNp] = false; } } } return staticLargest; } Running this benchmark on Codename One 3.6 (before optimizations) resulted in an average time of 380ms. On that latest Codename One (i.e. after optimizations) it ran in 135ms. That is an speed increase of over 2.8x.\nThere are obviously many more benchmarks that can be written that would cover more cases, but things are looking good so far. Does this mean that your app will perform 2.8x better? Probably not. As I mentioned above, most of the user experience is dictated by graphics performance and responsiveness (scrolling, rendering, etc..), and this is already done mostly in native code. However, for processor intensive tasks like number crunching, or data parsing, you are likely to see real performance gains. Code that is heavy on 2D graphics, shapes, and transforms may also see noticeably improvement.\nEven if these gains aren’t readily noticeable in your app, it is nice to know that if you crank out some extra performance for something in your app, you can do it without having to delve into native interfaces.\nCode Size and App Size These optimizations also yielded smaller apps. I built the Kitchen Sink app using Codename One 3.6 and with the latest to see if there was any difference in the size of code. It produced 15% to 20% improvements on both of these fronts. With 3.6, Kitchen Sink resulted in 930276 lines of C code (in .m files), and an App store IPA file size of 7.3MB. Buliding it with the latest Codename One resulted in 802457 lines of code, and an IPA file size of 6.3MB. That is 16% fewer lines of code and a final app size that is also 16% smaller. Not dramatic, but substantial.\nConclusion These early benchmarks look promising, and I fully expect similar gains across the board. It is worth mentioning (again), however, that microbenchmarks like this don’t correlate directly to user experience. If your app isn’t doing anything CPU intensive in Java code, then you probably won’t notice a difference, since most critical UI functionality is already implemented in native code. However, if you’re doing a lot of data crunching in your app, or drawing a lot of shapes with transforms, then these optimizations are likely to be more tangible to you.\nFeel free to create your own benchmarks comparing Codename One 3.6 with the latest. I’m interested in hearing about your results. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJérémy MARQUER — February 14, 2017 at 1:21 pm (permalink) Really nice !!\nI think it could also be noticeable on older devices …\nbryan — February 14, 2017 at 8:05 pm (permalink) Great work Steve. CN1 is getting better and better, congrats to all.\nGareth Murfin — February 9, 2019 at 4:49 pm (permalink) Great work Steve – certainly in the last year or so cn1 has felt way faster\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/parparvm-optimizations-compiling-java-for-ios/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/parparvm-optimizations-compiling-java-for-ios/parparvm-blog.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eTLDR: ParparVM is now up to 2.8x faster, and produces binaries that are 15%-20% smaller than before.\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eIf you build your app for iOS today, you may notice a performance boost due to some improvements to ParparVM – the AOT compiler we use to build Codename One apps for iOS. Read on for a short history of ParparVM, as well as some details about these improvements.\u003c/p\u003e\n\u003ch2 id=\"a-brief-history-of-parparvm\"\u003eA Brief History Of ParparVM\u003c/h2\u003e\n\u003cp\u003eIn the beginning, Codename One used XMLVM to build apps for iOS. It worked by converting Java byte-codes into its own XML representation, and then converting that XML into C-code. Unfortunately XMLVM was an academic project, and was announced in 2014 that development on it would be discontinued. We were faced with a choice. Do we continue to use XMLVM and simply support it ourselves, or do we migrate to something else. At the time RoboVM was an exciting new technology that compiled Java to LLVM and could produce iOS apps. I had also created a proof of concept port using Avian, an AOT compiler for Java that could produce iOS binaries. A fourth option, which seemed overly ambitious at the time, was to create our own tool from scratch. Ultimately, that is the avenue that was chosen, and ParparVM was born.\u003c/p\u003e","title":"ParparVM Optimizations: Java on iOS now 2.8x Faster"},{"content":"\nEditor note: This post is still valid for CocoaPods, but current iOS dependency setup also supports Swift Package Manager (SPM). See the current \u0026ldquo;Working with iOS\u0026rdquo; section in the developer guide.\nLast week I talked about using gradle dependencies to build native code, this week I’ll talk about the iOS equivalent: CocoaPods. We’ve discussed CocoaPods before but this bares repeating especially in the context of a specific cn1lib like intercom.\nCocoaPods allow us to add a native library dependency to iOS far more easily than Gradle. However, I did run into a caveat with target OS versioning. By default we target iOS 7.0 or newer which is supported by Intercom only for older versions of the library. Annoyingly CocoaPods seemed to work, to solve this we had to explicitly define the build hint ios.pods.platform=8.0 to force iOS 8 or newer.\nIncluding intercom itself required a single build hint: ios.pods=Intercom which you can obviously extend by using commas to include multiple libraries. You can search the cocoapods website for supported 3rd party libraries which includes everything you would expect. One important advantage when working with CocoaPods is the faster build time as the upload to the Codename One website is smaller and the bandwidth we have to CocoaPods is faster. Another advantage is the ability to keep up with the latest developments from the library suppliers. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\n3lix — February 13, 2017 at 5:02 pm (permalink) 3lix says:\nI am not familiar with cocoapods.\nI have two questions:\nWhen adding a a cocoapod library would it work on all three platforms (iOS , Android and Windows? ) In your previous post you had mentioned that there are over 18000 libraries. https://www.codenameone.com… Do they need to be converted to CN1LIBS before use (some sort of a JAVA api) ? Shai Almog — February 14, 2017 at 8:02 am (permalink) Shai Almog says:\nCocoaPods are used with native code similarly to the Android gradle build options being used for native code. This is important since libraries for iOS can sometimes be pretty huge (100mb+) thus become impractical for build processes.\nYou need to build a cn1lib to wrap every library that’s required, e.g. Native Google Maps support transitioned to using CocoaPods instead of just bundling the maps. This was a HUGE benefit as it allowed us to keep up with the latest version from Google with no effort. But it also made the build MUCH faster as the original build size approached 50mb and would take forever to upload each time, not it can even be used by free accounts as it clocks under the free quota size.\n3lix — February 14, 2017 at 4:13 pm (permalink) 3lix says:\nThank you for the explanation. This makes sense now\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-use-ios-cocoapods-dependencies-native-code/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-use-ios-cocoapods-dependencies-native-code/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cem\u003eEditor note: This post is still valid for CocoaPods, but current iOS dependency setup also supports Swift Package Manager (SPM). See the current \u0026ldquo;Working with iOS\u0026rdquo; section in the developer guide.\u003c/em\u003e\u003c/p\u003e\n\u003cp\u003eLast week I talked about \u003ca href=\"/blog/tip-use-android-gradle-dependencies-native-code.html\"\u003eusing gradle dependencies\u003c/a\u003e to build native code, this week I’ll talk about the iOS equivalent: CocoaPods. We’ve \u003ca href=\"/blog/cocoapods.html\"\u003ediscussed CocoaPods before\u003c/a\u003e but this bares repeating especially in the context of a specific cn1lib like \u003ca href=\"/blog/intercom-support.html\"\u003eintercom\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eCocoaPods allow us to add a native library dependency to iOS far more easily than Gradle. However, I did run into a caveat with target OS versioning. By default we target iOS 7.0 or newer which is supported by Intercom only for older versions of the library. Annoyingly CocoaPods seemed to work, to solve this we had to explicitly define the build hint \u003ccode\u003eios.pods.platform=8.0\u003c/code\u003e to force iOS 8 or newer.\u003c/p\u003e","title":"TIP: Use iOS CocoaPods Dependencies in Native Code"},{"content":"\nThis weeks update will go out a bit late or maybe even tomorrow. The reason for the postponing is the scope of the changes. We’ve made a lot of changes to ParparVM and we are very concerned that there will be regressions. So we would like this update to go in later in case we need to revert that work. Steve wrote a detailed post about the changes he made to ParparVM which we will post next week…​\nBesides that with the 64bit change to the build I’m sure there will be a lot of feedback on this update during the week. There are quite a few other interesting things in this update including the big change to the way redirects are handled on iOS which might be significant as well.\nIn terms of questions we had quite a few interesting questions but nothing that would be interesting to the general public. We did have two interesting pull requests this week starting with the redirect fix I wrote about and followed by this new feature from Diamond.\nDiamond also submitted this pull request just this morning. It’s a trivial change that I think most of you can probably do and appreciate. This is probably my favorite type of improvement as it doesn’t disrupt much and makes Codename One just a bit easier to use. It’s a great way to get your feet wet when submitting pull requests.\nSo instead of questions I’d like to remind you how easy it is to submit a pull request and add to Codename One the stuff that you need. The importance of contributing to Codename One isn’t about our need of your code, it’s about taking part in shaping the tool that we use every day to something that suits us all. It’s about participation!\nIt’s really easy to submit a pull request, you don’t even need to submit code changes to fix a typo or edit the developer guide docs.\nEven if we ask you for a change we really appreciate the involvement as we think it makes Codename One better and it makes you better programmers. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJoão Bastos — February 19, 2017 at 9:53 am (permalink) João Bastos says:\nShai, in the line of Diamond trivial change, that i really love 🙂 i think that it would be nice to have a MultiButton method like:\nMultiBtn.setTextLines(textline1,textline2,textline3,textline4);\ni keep doing this a lot:\nMultiBtn.setTextLine1(\u0026ldquo;name\u0026rdquo;);\nMultiBtn.setTextLine2(\u0026ldquo;address\u0026rdquo;);\nMultiBtn.setTextLine3(\u0026ldquo;city\u0026rdquo;);\nMultiBtn.setTextLine4(\u0026ldquo;phonenumber\u0026rdquo;);\nJust a thought, dont know if it already exists, but havent found it.\nP.S.- I know i should get my feet wet…but lets go one step at a time\nShai Almog — February 20, 2017 at 8:28 am (permalink) Shai Almog says:\nGo ahead and contribute this, it’s easy. I would recommend using a varargs argument so one can submit only some of the lines and not all 4 so it will be setTextLines(String… lines).\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-42/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-42/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis weeks update will go out a bit late or maybe even tomorrow. The reason for the postponing is the scope of the changes. We’ve made a lot of changes to \u003ca href=\"https://github.com/codenameone/CodenameOne/tree/master/vm\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eParparVM\u003c/a\u003e and we are very concerned that there will be regressions. So we would like this update to go in later in case we need to revert that work. Steve wrote a detailed post about the changes he made to ParparVM which we will post next week…​\u003c/p\u003e","title":"Questions of the Week 42"},{"content":"\nWhen building an iOS debug version of the app we only build a 32bit version to save build time. Otherwise the build will take almost twice as long as every file would be compiled twice. This worked well and was also fast enough. However, Apple started sending warnings to old 32bit apps and mistakes our apps as such.\nThe crux of the issue is Apple forcing developers to support 64 bit, we already support it and have for years. But now Apple is showing a warning on apps built without 64 bit support even if they are only meant for debug.\nUnfortunately, even if this remains only as a warning this doesn’t look good for to developers trying Codename One for the first time and seeing a message that the app might be \u0026ldquo;slow\u0026rdquo;. So from now on we will build 64 bit versions of the apps by default and if you have an old 32 bit device you would need to explicitly disable that using the build hint:\nios.debug.archs=armv7 This will produce a 32bit build like before. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJames van Kessel — February 13, 2017 at 11:48 am (permalink) James van Kessel says:\nHi Shai, I’m trying to track down the cause of my app development builds failing to install on a Gen5 iPod touch and a 3-year-old ipad mini with a message \u0026ldquo;could not install at this time\u0026rdquo;. I suspect this issue you describe is the cause (will check this evening when I have my test devices), but I’m wondering, is this a typical symptom that other users would expect to see? are there other ways this could manifest that users may not understand from the errors apple gives?\nI didn’t find this answer by searching for my problem, but Lianna pointed it out on chat for me (Thank you!) suspecting it may be related. To make your helpful articles easier to find via Google, can you add more context to notes like this: for example, making a short list of the common problems users will experience due to this issue would have shortened my search by a day. I know you’re addressing a frustration point where users may think an app is running slow or seeing a warning, but in this case, I can’t install and test my app, and the apple error messages aren’t instructive to the cause. A google search of the error related to CodenameOne finds nothing but certificate issue posts, so in my opinion that will be more detrimental to users experience with CN1 than a warning about running slow which I think would be less intrusive. thanks for all that you do, and Hopefully this can make it easier to get CN1 devs going.\nShai Almog — February 14, 2017 at 8:04 am (permalink) Shai Almog says:\nHi,\nthanks for the feedback. I wrote this post before we published the change and didn’t think about phrasing it like that but that is indeed a good point.\nKeith Valdez Hasselstrom — March 6, 2017 at 6:01 pm (permalink) Keith Valdez Hasselstrom says:\nI just got snagged by this. Trying to install on older IPad mini that previously worked. Maybe a little note on the dashboard would be useful. Thanks again for a great product.\nShai Almog — March 7, 2017 at 6:33 am (permalink) Shai Almog says:\nI was going to answer that we looked into that and couldn’t find the right place in the UX and just as I was typing that I had that forehead slap of \u0026ldquo;why didn’t I think about THAT\u0026rdquo;.\nThere is a place to add that: the page with the green \u0026ldquo;Install\u0026rdquo; button we show on the iOS device. It’s not perfect but at least it will get noticed more.\nKeith Valdez Hasselstrom — March 7, 2017 at 2:20 pm (permalink) Keith Valdez Hasselstrom says:\nPerfect !! At a minimum it would be a quick reminder. Thanks again for the level of support you personally provide; for a project this size, it’s extremely impressive !!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/moving-to-64bit-by-default/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/moving-to-64bit-by-default/generic-java-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen building an iOS debug version of the app we only build a 32bit version to save build time. Otherwise the build will take almost twice as long as every file would be compiled twice. This worked well and was also fast enough. However, Apple started sending warnings to old 32bit apps and mistakes our apps as such.\u003c/p\u003e\n\u003cp\u003eThe crux of the issue is \u003ca href=\"https://arstechnica.com/apple/2017/01/future-ios-release-will-soon-end-support-for-unmaintained-32-bit-apps/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eApple forcing developers to support 64 bit\u003c/a\u003e, we already support it and have for years. But now Apple is showing a warning on apps built without 64 bit support even if they are only meant for debug.\u003c/p\u003e","title":"Moving to 64bit by Default"},{"content":"\nOne of the common requests we received over the years is a way to let text \u0026ldquo;fit\u0026rdquo; into the allocated space so the font will match almost exactly the width available. In some designs this is very important but it’s also very tricky. Measuring the width of a String is a surprisingly expensive operation on some OS’s. Unfortunately, there is no other way other than trial \u0026amp; error to find the \u0026ldquo;best size\u0026rdquo;.\nStill despite the fact that something is \u0026ldquo;slow\u0026rdquo; we might still want to use it for some cases, this isn’t something you should use in a renderer, infinite scroll etc. and we recommend minimizing the usage of this feature as much as possible.\nThis feature is only applicable to Label and its subclasses (e.g. Button), with components such as TextArea (e.g. SpanButton) the choice between shrinking and line break would require some complex logic.\nTo activate this feature just use setAutoSizeMode(true) e.g.:\nForm hi = new Form(\u0026quot;AutoSize\u0026quot;, BoxLayout.y()); Label a = new Label(\u0026quot;Short Text\u0026quot;); a.setAutoSizeMode(true); Label b = new Label(\u0026quot;Much Longer Text than the previous line...\u0026quot;); b.setAutoSizeMode(true); Label c = new Label(\u0026quot;MUCH MUCH MUCH Much Longer Text than the previous line by a pretty big margin...\u0026quot;); c.setAutoSizeMode(true); Label a1 = new Button(\u0026quot;Short Text\u0026quot;); a1.setAutoSizeMode(true); Label b1 = new Button(\u0026quot;Much Longer Text than the previous line...\u0026quot;); b1.setAutoSizeMode(true); Label c1 = new Button(\u0026quot;MUCH MUCH MUCH Much Longer Text than the previous line by a pretty big margin...\u0026quot;); c1.setAutoSizeMode(true); hi.addAll(a, b, c, a1, b1, c1); hi.show(); Figure 1. Automatically sizes the fonts of the buttons/labels based on text and available space\nAdd All You will notice in the code above we added a new method: addAll.\naddAll is a shortcut that allows the code above to be written as:\nhi.addAll(a, b, c, a1, b1, c1); Instead of the more verbose syntax:\nhi.add(a). add(b). add(c). add(a1). add(b1). add(c1); It’s not a huge difference but at least when building demos/test cases it’s nice.\nRedirects on iOS One of the big decisions we made in Codename One was to not copy java.io wholesale. This has been a double edged sword…​\nIt has made us far more portable and also provided reliability that no other competing service can match in terms of networking. However, the differences within the network stack between OS’s are second only to the GUI differences. One such painful difference is the fact that iOS requires HTTPS now.\nAnother such painful difference is redirect behavior. Codename One handles redirect by returning the 30x HTTP response and redirecting seamlessly. However, you can override that behavior and grab the 30x redirect. This also means the behavior of redirect (which is one of those gray areas in HTTP implementations) is consistent.\nBut this isn’t the case on iOS where it handles redirect internally and we are faced with this after the fact.\nIn the past we evaluated this and determined that this wouldn’t be an easy fix, I’m not sure if this is something we missed or something that changed in recent iOS versions but it looks like the fix isn’t as hard as we feared as we got this pull request \u0026amp; merged it.\nWe might still revert this fix if we run into too many problems so with this Friday update check out your networking code and make sure everything is in order, if not we might need to provide a build hint to toggle this. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJoão Bastos — February 13, 2017 at 12:32 pm (permalink) Is the addAll shortcut already available? Cant see it in netbeans…\nShai Almog — February 14, 2017 at 8:05 am (permalink) Shai Almog says:\nIt should be. Use the Update Client Libs button in Codename One Settings.\nJoão Bastos — February 14, 2017 at 5:23 pm (permalink) João Bastos says:\nSolved! Thanks Shai!\nDenis — September 20, 2018 at 8:06 pm (permalink) Denis says:\nHi Shai,\nsetAutoSizeMode(true) doesn’t work for my app, more over it makes text to disappear\nplease take at screenshots, this is before AutoSize set to true, text is very tiny in tablets\nhttps://uploads.disquscdn.c…\nand this is after AutoSize set to true for first (top) label\nhttps://uploads.disquscdn.c…\nwhat can a reason for that ?\nThanks,\nDenis\np.s. CodenameOne version 5.0\nDenis — September 21, 2018 at 10:38 am (permalink) Denis says:\nupdate, text appears on real devices, but it’s very very tiny\nShai Almog — September 22, 2018 at 6:09 am (permalink) Shai Almog says:\nIt looks like you used something such as absolute center or flow layout. That won’t work. These layout managers give components their preferred size which means the resizing text will shrink and won’t grow. You need to use a layout that gives out the full width.\nDenis — September 23, 2018 at 9:02 pm (permalink) Denis says:\nyes, you are right, in some parts of UI I used flow layout. Is there any other way to make text bigger on tablets ? because it’s really very very tiny on 10 inch tablets, is it possible to set font size for \u0026ldquo;Label\u0026rdquo; UUID (to apply it to all labels at once) depending on device screen size ?\nShai Almog — September 24, 2018 at 4:33 am (permalink) Shai Almog says:\nYou can do that in the theme. See the section in the developer guide about theme layering. You can add a theme on top of the current theme.\nDenis — September 24, 2018 at 6:54 am (permalink) Denis says:\nI see, that’s better than maintain different APKs for different devices (phones, tablets), but still needs some logic to figure out on which device app is currently running and there should it load secondary theme or not, is there some handy way ?\nor I just go with one of these\nDisplay.getInstance().getDeviceDensity()\nDisplay.getInstance().getDisplayWidth()\nDisplay.getInstance().getDisplayHeight()\nShai Almog — September 25, 2018 at 8:23 am (permalink) Shai Almog says:\nThere’s isTablet() both in Display \u0026amp; the CN class.\nDenis — September 25, 2018 at 12:05 pm (permalink) Denis says:\ncool, thanks ! just tried that, interesting, but font changes doesn’t apply, background color does, i.e. I have correct layered theme and code setup, I see different background for tablets, but font size doesn’t change, I am trying t set to \u0026ldquo;True Type: native:MainRegular\u0026rdquo; and \u0026ldquo;True Type Size: Large\u0026rdquo;, but nothing happens on tablets, I tried both \u0026ldquo;[Default Style]\u0026rdquo; and \u0026ldquo;Label\u0026rdquo;, \u0026ldquo;Button\u0026rdquo; individually, can you please advise ?\nDenis — September 26, 2018 at 9:01 pm (permalink) Denis says:\nsetting \u0026ldquo;True Type Size\u0026rdquo; to millimeters value on component level helped, [Default Style] still doesn’t work even with millimeters value, I set font site for Buttons and Labels, but for example Dialog title is still very tiny, looks like I should set values for all components individually\nDenis — September 27, 2018 at 8:48 am (permalink) Denis says:\nalso Dialogs for some reason looks differently on mobile and tables, with the same theme (and no layered themes)\nmobile\nhttps://uploads.disquscdn.c…\ntablet https://uploads.disquscdn.c…\nall in simulator haven’t test on real devices yet\nDenis — September 27, 2018 at 10:43 am (permalink) Denis says:\non real tablet device dialog title appears similar to mobile, but with less spacing from top and bottom\nShai Almog — September 28, 2018 at 5:31 am (permalink) Shai Almog says:\nWhich tablet skin? It’s possible the skin is out of date and needs a new theme\nDenis — September 28, 2018 at 7:17 am (permalink) Denis says:\nthere are different skins for the same device name, for example for iPad Pro (ipad-pro.skin and iPadPro.skin), iPhoneX (this one is strangest iPhoneX.skin and /iPhoneX.skin) and Galaxy S7 (GalaxyS7.skin and SamsungGalaxyS7.skin), which is a bit confusing, but it would be easier if skins sorted by device name\nthe skin in above mentioned issue is IPadPro.skin, but I have compared to Nexus5.skin, different platform, I didn’t though about that, MicrosoftSurfacePro4.skin also have different view of Dialogs, but again it’s another platform, so may there is no issue at all, I have’t real Apple device to compare\np.s.\nI also get these errors when I changing a skin, simulator crashes and I have to start it again, but it works after that\njava.lang.UnsatisfiedLinkError: Native Library C:UsersDenisAppDataLocalTempsqlite-3.7.151-amd64-sqlitejdbc.dll already loaded in another classloader\njava.lang.UnsatisfiedLinkError: org.sqlite.NativeDB._open(Ljava/lang/String;I)V\nShai Almog — September 29, 2018 at 4:27 am (permalink) Shai Almog says:\nDid you refresh theme? It’s a bit hard to guess with that amount of information.\nShai Almog — September 29, 2018 at 4:31 am (permalink) Shai Almog says:\nThe iPad skin will look like iOS where the dialogs have a different default design inherited from te native theme.\nThe simulator crash is due to sqlite, we tried multiple ways to workaround it but it seems that the sqlite JDBC support is averse to class loaders. If you use sqlite switching skins will crash and you’ll have to re-run the app. There’s this issue which we tried and failed to fix multiple times https://github.com/codename…\nShai Almog — September 30, 2018 at 9:27 am (permalink) Shai Almog says:\nDefault will only work for things that aren’t explicitly defined. Since the title is explicitly defined in the native theme you need to override that.\nShai Almog — September 30, 2018 at 9:28 am (permalink) Shai Almog says:\nThat mostly relates to the density of the device\nDenis — October 1, 2018 at 9:07 am (permalink) Denis says:\nthat makes sense, and I thought the same, the only problem is that we can’t see what defined in native theme ))) I have just 6 items in theme settings, Default style, Button, Container, Label, Multibutton and Toolbar (only Padding/Margin) and as I understand because they are explicitly defined in main theme I have to define them also in layered theme, [Default Style] in layered theme will not override their parameters from main theme, is that correct ?\nShai Almog — October 2, 2018 at 4:49 am (permalink) Shai Almog says:\nTechnically you can open the native theme file from our git repo, but that’s probably not a good idea since that might change. Yes you need to explicitly define things you want to change. E.g. the title in iOS is center aligned and in Android it’s left aligned. We usually don’t override alignment to keep that default behavior.\nThe nice thing is that most of these things can be tested live with the simulator and switching is relatively quick (with the exception of the SQLite problem).\nDenis — October 2, 2018 at 12:21 pm (permalink) Denis says:\nThank you Shai, I do exactly the same, use emulator to adjust components, it’s very useful, thanks !\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/autosizing-add-all-ios-redirects/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/autosizing-add-all-ios-redirects/new-features-5.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the common requests we received over the years is a way to let text \u0026ldquo;fit\u0026rdquo; into the allocated space so the font will match almost exactly the width available. In some designs this is very important but it’s also very tricky. Measuring the width of a String is a surprisingly expensive operation on some OS’s. Unfortunately, there is no other way other than trial \u0026amp; error to find the \u0026ldquo;best size\u0026rdquo;.\u003c/p\u003e","title":"Autosizing, Add All \u0026 iOS Redirects"},{"content":"\nI discussed both of these last week but we’ve made some progress that warrants a dedicated post. We added a new feature that allows you to block copy \u0026amp; paste on a text component either globally or on a case by case basis. This is helpful for highly sensitive applications.\nThis feature was previously restricted to Android but is now available to iOS as well with no change required to your code.\nBuild Performance What started as a bunch of optimizations to fix issue 2024 evolved to a set of optimizations that should make the generated iOS code more readable, smaller \u0026amp; faster. This took some twists and turns and for now we reverted this set of changes until next Friday.\nHowever, the end result is that this should also shorten build times noticeably although not for everyone…​\nThe clang compiler is very slow when dealing with large methods and macros. By optimizing away some of the more ASM oriented conventions of the bytecode and substituting them with direct variable/constant usage we reduced some overheads.\nIf you weren’t directly impacted by this you probably won’t see any performance impact. The speed of the JVM rarely factors into the performance of Codename One which is governed more by the speed of the native port than anything else.\nOne of the things to notice in the issue discussion is that the original optimization fixed the problem while causing worse compilation times for different code pathways. That’s why optimizations \u0026amp; fixes are so tricky in a product as big as Codename One as regressions can be very complicated. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nM Usman Nu — February 10, 2017 at 1:52 pm (permalink) M Usman Nu says:\nDo i need to add ios.disableScreenshots in built-hints in order to enable this feature ?\nShai Almog — February 11, 2017 at 5:57 am (permalink) Shai Almog says:\nNo, that has nothing to do with that.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/block-copy-paste-faster-performance-ios/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/block-copy-paste-faster-performance-ios/security.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI discussed both of these last week but we’ve made some progress that warrants a dedicated post. We added a new feature that allows you to \u003ca href=\"/blog/disable-screenshots-copy-paste.html\"\u003eblock copy \u0026amp; paste\u003c/a\u003e on a text component either globally or on a case by case basis. This is helpful for highly sensitive applications.\u003c/p\u003e\n\u003cp\u003eThis feature was previously restricted to Android but is now available to iOS as well with no change required to your code.\u003c/p\u003e","title":"Block Copy/Paste \u0026 Faster Performance on iOS"},{"content":"\nIntegrating a native OS library isn’t hard but it sometimes requires some juggling. Most instructions target developers working with xcode or Android Studio \u0026amp; you need to twist your head around them. In Android the steps for integration in most modern libraries include a gradle dependency.\nE.g. we recently published a library that added support for Intercom. The native Android integration instructions for the library looked like this:\nAdd the following dependency to your app’s build.gradle file:\ndependencies { compile 'io.intercom.android:intercom-sdk:3.+' } Which instantly raises the question: \u0026ldquo;How in the world do I do that in Codename One\u0026rdquo;?\nWell, it’s actually pretty simple. You can add the build hint:\nandroid.gradleDep=compile 'io.intercom.android:intercom-sdk:3.+' This would \u0026ldquo;work\u0026rdquo; but there is a catch…​\nYou might need to define the specific version of the Android SDK used and specific version of Google play services version used. Intercom is pretty sensitive about those and demanded that we also add:\nandroid.playServices=9.8.0 android.sdkVersion=25 Once those were defined the native code for the Android implementation became trivial to write and the library was easy as there were no jars to include.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-use-android-gradle-dependencies-native-code/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-use-android-gradle-dependencies-native-code/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIntegrating a native OS library isn’t hard but it sometimes requires some juggling. Most instructions target developers working with xcode or Android Studio \u0026amp; you need to twist your head around them. In Android the steps for integration in most modern libraries include a gradle dependency.\u003c/p\u003e\n\u003cp\u003eE.g. we recently published a library that added support for \u003ca href=\"/blog/intercom-support.html\"\u003eIntercom\u003c/a\u003e. The native Android integration instructions for the library looked like this:\u003c/p\u003e\n\u003cp\u003eAdd the following dependency to your app’s \u003ccode\u003ebuild.gradle\u003c/code\u003e file:\u003c/p\u003e","title":"TIP: Use Android Gradle Dependencies in Native Code"},{"content":"\nWe are releasing a small Eclipse update today, it’s small because it isn’t a full release that includes the latest features/libraries but rather a minor bug fix to the previous release which was missing the UWP build target. One of the biggest changes this week is the fix for the build performance issue mentioned below. It might also speed up general app performance for some use cases!\nThe biggest change this week is the support for peer component Z-ordering on practically all platforms, this completely changes the use cases for Codename One and we intend to take full advantage of these new capabilities moving forward.\nKlaus asked about that annoying iOS 10+ warning when building 32bit apps. It seems Apple is dropping 32bit support moving forward so we might flip the default to be 64 bit on this flag in the near future.\nThis issue raised by Stefan is really problematic and I hope it leads us to faster build times which are crucial!\nWhat I really liked about this is the good and small test case he was able to come up with for such a challenging issue…​\nDee ran into some issues with signature component and JPEG export, since the generated image is transparent this caused some issues with the simulator codec.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-41/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-41/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are releasing a small Eclipse update today, it’s small because it isn’t a full release that includes the latest features/libraries but rather a minor bug fix to the previous release which was missing the UWP build target. One of the biggest changes this week is the fix for the build performance issue mentioned below. It might also speed up general app performance for some use cases!\u003c/p\u003e\n\u003cp\u003eThe biggest change this week is the support for peer component Z-ordering on practically all platforms, this completely changes the use cases for Codename One and we intend to take full advantage of these new capabilities moving forward.\u003c/p\u003e","title":"Questions of the Week 41"},{"content":"\nWe use intercom.io for our website support system you can see it as the chat button on the bottom right of the page. The true value of this tool is in it’s ability to deliver a unified interface everywhere, normally this stretches into native mobile apps as well. As a result we decided to port the native intercom device API to Codename One so it will be easy to deploy everywhere.\nWe added a new cn1lib for intercom, it works on Android/iOS and will allow you to communicate with users of your app thru the app and web. It also allows for more advanced event based automation which is really useful when building a user funnel.\nTo get started install the cn1lib thru the extensions menu as usual. Then assuming you have an intercom.io account create Android/iOS apps there. From there you can get the keys for Android/iOS and use the following to activate intercom:\nIntercom.init(\u0026quot;AndroidAppKey\u0026quot;, \u0026quot;IosAppKey\u0026quot;, \u0026quot;AppId\u0026quot;); Assuming intercom is supported on the platform Intercom.getInstance() will return a non-null value. You need to start by registering your user, if your app allows for login you can use the email or other credential you might have for binding the user identity using something like:\nIntercom.getInstance().registerIdentifiedUser(Registration.create().withEmail(usersEmail)); If not you can use registerUnidentifiedUser().\n__ You MUST register before using other API’s Once you are registered you can check for messages and show the compose/discussion threads. You can use a UI like FloatingActionButton to trigger a chat with support etc.\nIntegrating Intercom was very easy, I’ll write some more about it next week.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/intercom-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/intercom-support/new-features-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe use \u003ca href=\"http://intercom.io\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eintercom.io\u003c/a\u003e for our website support system you can see it as the chat button on the bottom right of the page. The true value of this tool is in it’s ability to deliver a unified interface everywhere, normally this stretches into native mobile apps as well. As a result we decided to port the native intercom device API to Codename One so it will be easy to deploy everywhere.\u003c/p\u003e","title":"Intercom Support"},{"content":"\nContinuing our security trend from the past month we have a couple of new features for Android security that allow us to block the user from taking a screenshot or copying \u0026amp; pasting data from fields. Notice that these features might fail on jailbroken devices so you might want to check for jailbreak/rooting first.\nBlocking screenshots is an Android specific feature that can’t be implemented on iOS. This is implemented by classifying the app window as secure and you can do that via the build hint android.disableScreenshots=true. Once that is added screenshots should no longer work for the app, this might impact other things as well such as the task view etc.\nWe will add the ability to block copy \u0026amp; paste on Android in the coming update. We will add this feature to iOS as we move forward and it should work with the same semantics. You can block copy \u0026amp; paste globally or on a specific field, to block this globally use:\nDisplay.getInstance().setProperty(\u0026quot;blockCopyPaste\u0026quot;, \u0026quot;true\u0026quot;); To block this on a specific field do:\ntextCmp.putClientProperty(\u0026quot;blockCopyPaste\u0026quot;, Boolean.TRUE); __ Notice that the inverse of using false might not work as expected Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/disable-screenshots-copy-paste/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/disable-screenshots-copy-paste/security.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eContinuing our security trend from the past month we have a couple of new features for Android security that allow us to block the user from taking a screenshot or copying \u0026amp; pasting data from fields. Notice that these features might fail on jailbroken devices so you might want to \u003ca href=\"/blog/jailbreak-rooting-detection.html\"\u003echeck for jailbreak/rooting\u003c/a\u003e first.\u003c/p\u003e\n\u003cp\u003eBlocking screenshots is an Android specific feature that can’t be implemented on iOS. This is implemented by classifying the app window as secure and you can do that via the build hint \u003ccode\u003eandroid.disableScreenshots=true\u003c/code\u003e. Once that is added screenshots should no longer work for the app, this might impact other things as well such as the task view etc.\u003c/p\u003e","title":"Disable Screenshot, Copy \u0026 Paste"},{"content":"\nWhen Android launched RSA1024 with SHA1 was considered strong enough for the foreseeable future, this hasn’t changed completely but the recommendation today is to use stronger cyphers for signing \u0026amp; encrypting as those can be compromised.\nAPK’s are signed as part of the build process when we upload an app to the Google Play Store. This process seems redundant as we generate the signature/certificate ourselves (unlike Apple which generates it for us). However, this is a crucial step as it allows the device to verify upgrades and make sure a new update is from the same original author!\nThis means that if a hacker takes over your account on Google Play, he still won’t be able to ship fake updates to your apps without your certificate. That’s important since if a hacker would have access to your certificate he could create an app update that would just send him all the users private information e.g. if you are a bank this could be a disaster.\nAndroid launched with RSA1024/SHA1 as the signing certificates. This was good enough at the time and is still pretty secure. However, these algorithms are slowly eroding and it is conceivable that within the 10-15 year lifetime of an app they might be compromised using powerful hardware. That is why Google introduced support for stronger cryptographic signing into newer versions of Android and you can use that.\nThe Bad News There is a downside…​\nGoogle only introduced that capability in Android 4.3 so using these new keys will break compatibility with older devices. If you are building a highly secure app this is probably a tradeoff you should accept. If not this might not be worth it for some theoretical benefit.\nFurthermore, if your app is already shipping you are out of luck. Due to the obvious security implications once you shipped an app the certificate is final. Google doesn’t provide a way to update the certificate of a shipping app. Thus this feature only applies to apps that aren’t yet in the play store.\nThe Good If you are building a new app this is pretty easy to integrate and requires no changes on your part. Just a new certificate. You can generate the new secure key using instructions in articles like this one.\nIf you are using Codename One Setting we will have a new option in the next update to generate an SHA512 key which will harden the security for the APK:\nFigure 1. New SHA512 option for Android key generation\nSecurity As you might have noticed we made a lot of posts about hardening the security of Codename One applications, we’d like to make Codename One applications more secure by default and make it easy for you to find what you need in regards to security.\nOne part of that is an introduction of a new security tag to the blog. We’ll also include more detailed documentation on hardening a Codename One application in an upcoming blog post and within the developer guide. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMiguel Munoz — August 14, 2020 at 10:22 pm (permalink) Where does it put the certificate? I’m moving my source to GitHub, and I naturally don’t want the certificates stored there, too. I found the iOS certificates in a folder called iosCerts, and excluded those from github, but I can’t find them for the android build. What files should I exclude?\nShai Almog — August 15, 2020 at 5:17 am (permalink) Shai Almog says:\nIt should be under your users home directory under the \u0026ldquo;.codenameone\u0026rdquo; directory. So no worries.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/strong-android-certificates/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/strong-android-certificates/security.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen Android launched RSA1024 with SHA1 was considered strong enough for the foreseeable future, this hasn’t changed completely but the recommendation today is to use stronger cyphers for signing \u0026amp; encrypting as those can be compromised.\u003c/p\u003e\n\u003cp\u003eAPK’s are signed as part of the build process when we upload an app to the Google Play Store. This process seems redundant as we generate the signature/certificate ourselves (unlike Apple which generates it for us). However, this is a crucial step as it allows the device to verify upgrades and make sure a new update is from the same original author!\u003c/p\u003e","title":"Strong Android Certificates"},{"content":"\nI recently had to debug some code on Android Studio and was reminded how awful that IDE really is. IntelliJ is a pretty good IDE but Android Studio is remarkably slow even for trivial projects…​ One of the things that make it slow (besides RAM usage) is the approach of downloading everything it needs dynamically.\nThis might be unnoticeable on Googles fast networks where this probably runs instantly. But on my fast home network this was painfully slow.\nWith mobile apps this problem is often just as bad, we debug on the device in the office where the device is connected to wifi or 4G networks. This might be OK for some cases but it doesn’t represent flaky on-the-road conditions that exist even in the western hemisphere in some regions.\nWe have an option in the simulator to disable networking or slow it down but these don’t reproduce the same result as one would get with a real slow connection. One of the tricks I picked over the years is to tether my laptop to my phone with a portable hotspot, I then limit the phone to 3g or even 2g networking. At this point the internet connection in the simulator will literally use a slow mobile connection and I’m able to debug/profile the performance accurately.\nYou can reproduce this on the device too but that won’t allow for easy debugging or profiling.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-use-tethering-to-simulate-slow-network-connections/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-use-tethering-to-simulate-slow-network-connections/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI recently had to debug some code on Android Studio and was reminded how awful that IDE really is. IntelliJ is a pretty good IDE but Android Studio is remarkably slow even for trivial projects…​ One of the things that make it slow (besides RAM usage) is the approach of downloading everything it needs dynamically.\u003c/p\u003e\n\u003cp\u003eThis might be unnoticeable on Googles fast networks where this probably runs instantly. But on my fast home network this was painfully slow.\u003c/p\u003e","title":"TIP: Use Tethering to Simulate Slow Network Connections"},{"content":"\nToday we have the first weekly release since the 3.6 release and as such it is choke full of changes which is natural given that we skipped a release and had a lot of code pending to \u0026ldquo;post release\u0026rdquo;. So please be vigilant especially if you use peer components and let us know about potential regressions ASAP.\nan anonymous poster asked a recurring question that we still don’t have a great answer for, how to capture timed video. This is possible to do with audio using the MediaManager but it can’t be done with video which can only use Capture. However, thanks to the new PeerComponent work we might expose low level camera API’s including video/picture capture with viewfinder etc.\nThis was always possible to implement before (even for 3rd parties) using PeerComponent but with the recent z-order improvements the benefit becomes HUGE.\nStefan asked about porting Flamingo SVG to Codename One which is something I’ve been pondering too!\nIf you are interested in fast cross platform SVG this is a great opportunity for community involvement.\nStefan also asked this question which is one of those niche pieces of knowledge most of us don’t notice until we bump our head against them.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-40/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-40/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eToday we have the first weekly release since the 3.6 release and as such it is choke full of changes which is natural given that we skipped a release and had a lot of code pending to \u0026ldquo;post release\u0026rdquo;. So please be vigilant especially if you use peer components and let us know about potential regressions ASAP.\u003c/p\u003e\n\u003cp\u003ean \u003ca href=\"http://stackoverflow.com/users/7454657/anonymous\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eanonymous\u003c/a\u003e poster asked a recurring question that we still don’t have a great answer for, \u003ca href=\"http://stackoverflow.com/questions/41852856/how-to-automatically-start-video-recording-and-stop-automatically-after-a-predef\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehow to capture timed video\u003c/a\u003e. This is possible to do with audio using the \u003ccode\u003eMediaManager\u003c/code\u003e but it can’t be done with video which can only use \u003ccode\u003eCapture\u003c/code\u003e. However, thanks to the new \u003ccode\u003ePeerComponent\u003c/code\u003e work we might expose low level camera API’s including video/picture capture with viewfinder etc.\u003c/p\u003e","title":"Questions of the Week 40"},{"content":"\nJust last week I mentioned the effort we were taking to bring the z-ordered peer components into other platforms and I’m pretty happy to report that tomorrows update should include support for iOS \u0026amp; the JavaScript ports for z-ordering.\nWhat this means is that peer components (e.g. maps, videos, browser etc.) can reside below a component in the Codename One hierarchy and won’t always be on top as it is now. This opens up Codename One for a huge set of use cases and makes building some types of apps (e.g. Maps) much easier!\nThe implementation on iOS is very different from Android. Z-Ordering on Android was \u0026ldquo;relatively\u0026rdquo; simple as it allowed us to place components pretty much within their place in the hierarchy. However, on iOS and other platforms this is impractical as it might cause an issue with some complex components. Our initial solution was to define two layers, everything that paints below the peer and everything that paints above the peer.\nThis would have meant that if you had two peers in a Form they would both be in the same Z location and won’t be mixed.\nHowever, we found a better way using a \u0026ldquo;clear\u0026rdquo; operation where each peer component will clear the elements below it and paint in the right location. That way peers are always painted at the bottom but have a special clear graphics function to remove anything that should be underneath. This does mean that peers should be opaque though…​\nThe \u0026ldquo;clear\u0026rdquo; approach is the one we took in the JavaScript port and it will carry those tradeoffs.\nThis is a HUGE change so if your app relies on peers (Maps, Video, Browser etc.) I suggest testing it extensively and letting us know at once if you run into any regressions!\nOnly UWP remains as a target for this feature, thanks to the work done in iOS/JavaScript this might not be too hard.\nMoving Forward Now that this is effectively working we need to use peers more both in our demos and in practice. A huge case is in the mapping applications where we need to enhance the demo with peers.\nAnother thing we need to work on is better video support and especially video/image capture using a peer. This is something we should offer relatively easily and it’s a HUGE advantage over tools such as PhoneGap/Cordova/Qt etc.\nall of which are incapable of doing this.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/z-order-peers-in-ios-javascript/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/z-order-peers-in-ios-javascript/maps.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eJust last week \u003ca href=\"/blog/html-maps-z-order-peer-properties-update.html\"\u003eI mentioned\u003c/a\u003e the effort we were taking to bring the z-ordered peer components into other platforms and I’m pretty happy to report that tomorrows update should include support for iOS \u0026amp; the JavaScript ports for z-ordering.\u003c/p\u003e\n\u003cp\u003eWhat this means is that peer components (e.g. maps, videos, browser etc.) can reside below a component in the Codename One hierarchy and won’t \u003cstrong\u003ealways\u003c/strong\u003e be on top as it is now. This opens up Codename One for a huge set of use cases and makes building some types of apps (e.g. Maps) \u003cstrong\u003emuch\u003c/strong\u003e easier!\u003c/p\u003e","title":"Z-Order Peers in iOS \u0026 JavaScript"},{"content":"\nDisplay.canExecute(url) provides us with a generic tool to test the availability of a feature before executing a command. This is very useful for inter-app communications and allows us to achieve various things such as launching Google Map instead of Apple Maps on iOS.\nLets say I want to navigate using Google Maps if it’s installed in iOS but if not I’ll settle for Apple Maps I can do something like this:\nString url = \u0026quot;comgooglemaps://?q=\u0026quot; + Util.encodeUrl(address); Boolean b = Display.getInstance().canExecute(url); if(b != null \u0026amp;\u0026amp; b.booleanValue()) { Display.getInstance().execute(url); } else { // google maps is probably not installed Display.getInstance().openNativeNavigationApp(address); } This should work and would have worked but might not have…​\nThe reason this might have failed in recent iOS \u0026amp; xcode versions is because Apple changed the behavior of the underlying API used by canExecute to always return false. The workaround is to add the prefix of the URL into a list within the plist file. We have a build hint for that which accepts a comma separated list:\nios.applicationQueriesSchemes=comgooglemaps If there are additional entries you can separate them with a comma. You can use up to 50 URL prefixes.\nThe reason for this requirement isn’t 100% clear but it’s assumed that some apps used this feature to query the installed apps on the device thus violating users privacy in a subtle way.\nThanks to the recent build hint automation we can detect cases where you use the canExecute API and automatically setup the build hint correctly. Obviously, this won’t work for dynamic values that change on the device but should work for standard prefixes.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/can-execute-hint/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/can-execute-hint/new-features-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eDisplay.canExecute(url)\u003c/code\u003e provides us with a generic tool to test the availability of a feature before executing a command. This is very useful for inter-app communications and allows us to achieve various things such as launching Google Map instead of Apple Maps on iOS.\u003c/p\u003e\n\u003cp\u003eLets say I want to navigate using Google Maps if it’s installed in iOS but if not I’ll settle for Apple Maps I can do something like this:\u003c/p\u003e","title":"Can Execute Hint"},{"content":"\niOS \u0026amp; Android are walled gardens which is both a blessing and a curse. Looking at the bright side the walled garden aspect of locked down devices means the devices are more secure by nature. E.g. on a PC that was compromised I can detect the banking details of a user logging into a bank. But on a phone it would be much harder due to the deep process isolation.\nThis isn’t true for jailbroken or rooted devices. In these devices security has been compromised often with good intentions (opening up the ecosystem) but it can also be used as a step in a serious attack on an application!\nFor obvious reasons it’s really hard to accurately detect a jailbroken or rooted device but when possible if you have a high security app you might want to block the functionality or even raise a \u0026ldquo;silent alarm\u0026rdquo; in such a case. To detect this we are introducing a new method:\nif(Display.getInstance().isJailbrokenDevice()) { // probably jailbroken or rooted } else { // probably not } Notice that this is all \u0026ldquo;probably\u0026rdquo;, we can’t be 100% sure as there are no official ways to detect that. That is why it’s crucial to encrypt everything and assume the device was compromised to begin with when dealing with very sensitive data. Still it’s worthwhile to use these API’s to make the life of an attacker just a little bit harder.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/jailbreak-rooting-detection/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/jailbreak-rooting-detection/security.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eiOS \u0026amp; Android are walled gardens which is both a blessing and a curse. Looking at the bright side the walled garden aspect of locked down devices means the devices are more secure by nature. E.g. on a PC that was compromised I can detect the banking details of a user logging into a bank. But on a phone it would be much harder due to the deep process isolation.\u003c/p\u003e","title":"Jailbreak/Rooting Detection"},{"content":"\nThe Tabs component isn’t our first attempt at the the multi-tab UI and as such we made a lot of changes to the logic to facilitate a level of flexibility that can answer most use cases e.g. Tabs that can be closed with an X on the top right section or span multiple rows.\nMost developers are oblivious to this capability which is a shame, it is indeed a bit obscure. The code below demonstrates multi-line tabs:\nForm hi = new Form(\u0026quot;Custom Tabs\u0026quot;, new BorderLayout()); Tabs tb = new Tabs() { @Override protected Component createTab(String title, Image icon) { __**(1)** SpanButton custom = new SpanButton(title); custom.setIcon(icon); custom.setUIID(\u0026quot;Container\u0026quot;); custom.setTextUIID(\u0026quot;Tab\u0026quot;); custom.setIconPosition(BorderLayout.NORTH); custom.setIconUIID(\u0026quot;Tab\u0026quot;); return custom; } @Override protected void setTabSelectedIcon(Component tab, Image icon) { ((SpanButton)tab).setPressedIcon(icon); __**(2)** } protected void selectTab(Component tab) { __**(3)** } @Override protected void bindTabActionListener(Component tab, ActionListener l) { ((SpanButton)tab).addActionListener(l); } }; tb.setTabUIID(null); tb.addTab(\u0026quot;Tab 1\u0026quot;, FontImage.MATERIAL_3D_ROTATION, 4, new Label(\u0026quot;T1\u0026quot;)); tb.addTab(\u0026quot;Really long text in tab\u0026quot;, FontImage.MATERIAL_ACCESSIBILITY, 4, new Label(\u0026quot;T2\u0026quot;)); tb.addTab(\u0026quot;Tab 3\u0026quot;, FontImage.MATERIAL_ACCESS_ALARM, 4, new Label(\u0026quot;T3\u0026quot;)); tb.addTab(\u0026quot;Tab 4\u0026quot;, FontImage.MATERIAL_ACCOUNT_BOX, 4, new Label(\u0026quot;T4\u0026quot;)); tb.getTabsContainer().setScrollableX(false); __**(4)** hi.add(BorderLayout.CENTER, tb); hi.show(); __1 This method can return any arbitrary component to use as a Tab, by default Tabs uses RadioButton but you can use anything e.g. here we used SpanButton __2 We added this in the latest version in git, that method still isn’t available but will be this Friday __3 This method works well when we have a RadioButton tab at which point it can make it \u0026ldquo;selected\u0026rdquo; however in this case I would just set the UIID to something other than the default for the selected tab. Since I didn’t want to get into it I left it blank. __4 By default tabs are scrollable which prevents them from breaking lines. This code must reside after adding the tabs otherwise scrollability will be enabled implicitly. The result looks pretty much like a standard tabs only it allows line breaks and when we have enough space uses it intelligently.\nFigure 1. Portrait mode shows the line break in place\nFigure 2. In landscape we have more space so a line break isn’t necessary Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDurank — September 28, 2020 at 4:37 pm (permalink) How can I add form instead a container to the taps for better scalability code?\nShai Almog — September 29, 2020 at 2:44 am (permalink) Adding forms into a Container is a bad practice. A form is huge and heavyweight. You should do the reverse and add a container into a form and tab.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-customize-tabs-behavior/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-customize-tabs-behavior/tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003eTabs\u003c/code\u003e component isn’t our first attempt at the the multi-tab UI and as such we made a lot of changes to the logic to facilitate a level of flexibility that can answer most use cases e.g. Tabs that can be closed with an X on the top right section or span multiple rows.\u003c/p\u003e\n\u003cp\u003eMost developers are oblivious to this capability which is a shame, it is indeed a bit obscure. The code below demonstrates multi-line tabs:\u003c/p\u003e","title":"TIP: Customize Tabs Behavior"},{"content":"\nWe are ending the enterprise annual promotion today so if you didn’t sign up for this special deal this is literally your last chance. This is important as the JavaScript build promotion will expire soon so I suggest taking advantage of this!\nWe had a lot of updates and new features this week but we decided in advance to skip the update right after the release and so we’ll push them out only next week.\nWe had a lot of good questions on stackoverflow this week but I don’t think most of them would be interesting to the general blog readership. I thought about covering Dave’s request in the group but I don’t have much more to say other than: \u0026ldquo;we need enterprise customers to keep the lights on, please upgrade\u0026rdquo;.\nWith that I’ll cut this weeks Q\u0026amp;A short…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-39/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-39/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are \u003ca href=\"/blog/codename-one-3-6-now-live-special-sale.html\"\u003eending the enterprise annual promotion\u003c/a\u003e today so if you didn’t sign up for this special deal this is literally your last chance. This is important as the JavaScript build promotion will expire soon so I suggest taking advantage of this!\u003cbr\u003e\nWe had a lot of updates and new features this week but we decided in advance to skip the update right after the release and so we’ll push them out only next week.\u003c/p\u003e","title":"Questions of the Week 39"},{"content":"\nOne of the problems with native maps is that they work very differently between the device and the simulator. This is because we use MapComponent on the simulator and as a fallback on the devices where Google Maps isn’t available. We just committed a new mode for maps that allows you to use the Google HTML maps as the fallback instead of the MapComponent.\nThis is faster, has better support from Google and is more similar to the way maps work on the physical device because the browser component is also a peer component so similar restrictions will apply. This is off by default since the HTML maps require a key and right now we didn’t finish mapping all the components. This also needs some server functionality so I’m not sure when this will land in the actual extension but it’s already there is you build from source. We’ll post more about this when we do an official refresh of the extension.\nZ-Ordering in Peer Components We did a lot of work getting z-ordering in Android a while back and then dropped the ball on it by postponing the rest of the work to 3.7 at the last minute. For those of you who don’t remember peer components are native OS widgets like video, browser, native maps etc.\nThis change allows us to draw on top of them and place components on top of them so we can create pretty rich applications from subtitling a video to augmented reality apps would be (relatively) easy with such a change. Without this change you would need native code to do this…​\nIt will also make apps that rely heavily on Native Maps far easier to write with far better results.\nZ-ordering is a big change and just didn’t fit into the schedule, however we didn’t abandon this effort and Steve just committed a major overhaul of our peer handling in the simulator/desktop port which will allow z-ordering on those platforms.\niOS will probably be more challenging but we hope to do it sooner rather than later so we will have plenty of time to test before 3.7 lands.\nProperties Update We’re working on some big changes for the Properties API. We added a new MapProperty option which is effectively a property that functions as a java.util.Map equivalent similar to the existing ListProperty. We also added properties to represent primitive or numeric types e.g. instead of writing:\npublic final Property\u0026lt;Integer,MyObject\u0026gt; myNumber = new Property\u0026lt;\u0026gt;(\u0026quot;myNumber\u0026quot;); We would now write:\npublic final IntProperty\u0026lt;MyObject\u0026gt; myNumber = new IntProperty\u0026lt;\u0026gt;(\u0026quot;myNumber\u0026quot;); The main motivation for this is erasure. Parsing code that accesses myNumber wouldn’t know the generic type since that is removed during compilation. However, we can know the type of IntProperty \u0026amp; thus implicitly convert numeric types during parsing. This isn’t as \u0026ldquo;generic\u0026rdquo; but since NumericProperty is a common base class for all number properties and derives from Property we can write common code relatively easily.\nThe NumericProperty also introduces support for non-nullable elements in this case which will fail if you try to set a null value and thus work better with auto-boxed values. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nBlessing Mahlalela — February 16, 2017 at 11:46 am (permalink) Blessing Mahlalela says:\nHi, currently trying latest Github CN1 Google maps code. I added Java script api key, however on simulator it shows Open street maps. Is it possible to display html5 JS maps on simulator and every other device that does not have the SDK?\nBlessing Mahlalela — February 16, 2017 at 12:12 pm (permalink) Blessing Mahlalela says:\nOk, issue fixed I was using an old CN1Google lib. It will be good to remove it as it causes un necessary confusion.\nhttps://github.com/codename…\nSecondly Android build causes an error (have not tried iOS):\nException is:\norg.gradle.api.tasks.TaskExecutionException: Execution failed for task ‘:transformClassesAndResourcesWithProguardForRelease’.\nShai Almog — February 16, 2017 at 2:34 pm (permalink) Shai Almog says:\nThis isn’t implemented completely but should work for desktop and does work for my test case. The Android build isn’t something I tested with the current version but I’ll need the full logs as this isn’t the actual error message.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/html-maps-z-order-peer-properties-update/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/html-maps-z-order-peer-properties-update/maps.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the problems with native maps is that they work very differently between the device and the simulator. This is because we use \u003ccode\u003eMapComponent\u003c/code\u003e on the simulator and as a fallback on the devices where Google Maps isn’t available. We just committed a new mode for maps that allows you to use the Google HTML maps as the fallback instead of the \u003ccode\u003eMapComponent\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThis is faster, has better support from Google and is more similar to the way maps work on the physical device because the browser component is also a peer component so similar restrictions will apply. This is off by default since the HTML maps require a key and right now we didn’t finish mapping all the components. This also needs some server functionality so I’m not sure when this will land in the actual extension but it’s already there is you build from source. We’ll post more about this when we do an official refresh of the extension.\u003c/p\u003e","title":"HTML Maps, Z-Order Peer \u0026 Properties Update"},{"content":"\nWe try to make Codename One \u0026ldquo;seamless\u0026rdquo;, this expresses itself in many small details such as the automatic detection of permissions on Android etc. The build servers go a long way in setting up the environment as intuitive. But it’s not enough, build hints are often confusing and obscure. It’s just hard to abstract the mess that is native mobile OS’s and the odd policies from Apple/Google…​\nE.g. a common problem developers face is location code that doesn’t work in iOS. This is due to the ios.locationUsageDescription build hint that’s required. The reason we added that build hint was a requirement by Apple to provide a description for every app that uses the location service.\nWe could detect usage of the API in the servers and inject some random string into place and in fact that was what we were about to do with issue 1415 but then it occurred to us that there is a much simpler way that will also provide far more power…​\nWe added two new API’s to Display:\n/** * Returns the build hints for the simulator, this will only work in the debug environment and it's * designed to allow extensions/API's to verify user settings/build hints exist * @return map of the build hints that isn't modified without the codename1.arg. prefix */ public Map\u0026lt;String, String\u0026gt; getProjectBuildHints() {} /** * Sets a build hint into the settings while overwriting any previous value. This will only work in the * debug environment and it's designed to allow extensions/API's to verify user settings/build hints exist. * Important: this will throw an exception outside of the simulator! * @param key the build hint without the codename1.arg. prefix * @param value the value for the hint */ public void setProjectBuildHint(String key, String value) {} Both of these allow us to detect if a build hint is set and if not (or if set incorrectly) set its value…​\nSo now if you will use the location API from the simulator and you didn’t define ios.locationUsageDescription we will implicitly define a string there. The cool thing is that you will now see that string in your settings and you would be able to customize it easily.\nHowever, this gets way better than just that trivial example!\nThe real value is for 3rd party libraries, e.g. Google Maps or Parse. They can inspect the build hints in the simulator and show an error in case of a misconfiguration. They can even show a setup UI. Demos that need special keys in place can force the developer to set them up properly before continuing. We plan to make extensive use of this feature moving forward.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/automatic-build-hints-configuration/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/automatic-build-hints-configuration/new-features-4.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe try to make Codename One \u0026ldquo;seamless\u0026rdquo;, this expresses itself in many small details such as the automatic detection of permissions on Android etc. The build servers go a long way in setting up the environment as intuitive. But it’s not enough, build hints are often confusing and obscure. It’s just hard to abstract the mess that is native mobile OS’s and the odd policies from Apple/Google…​\u003c/p\u003e\n\u003cp\u003eE.g. a common problem developers face is location code that doesn’t work in iOS. This is due to the \u003ccode\u003eios.locationUsageDescription\u003c/code\u003e build hint that’s required. The reason we added that build hint was a requirement by Apple to provide a description for every app that uses the location service.\u003c/p\u003e","title":"Automatic Build Hints Configuration"},{"content":"\nA couple of years ago I wrote an app for my spouses yoga studio for managing her student list. I intended to open source it but the code is a bit messy and I can’t seem to find the time/energy to clean it up. I used the excellent parse4cn1 library from Chidiebere Okwudire during the height of Parse.\nAs Parse ended I started thinking about contingency plans but after a few emails with Chidi and his posts detailing the various options I thought it might be possible to take the \u0026ldquo;lazy approach\u0026rdquo;.\nSince the app is mostly for personal use I wasn’t faced with the prospect of replacing a \u0026ldquo;live\u0026rdquo; server which would have probably made the migration difficult. Since the app doesn’t use any \u0026ldquo;difficult\u0026rdquo; feature like push or complex server code this would be a trivial migration. Still I braced myself for hiccups…​\nLooking at the options available I chose to go with back4app, it’s the first one I picked so I have no idea if other options are better/worse. I liked how easy they made the migration and I’m all for taking the lazy option when it’s available.\nThe migration didn’t require anything on the parse side, I just signed up for back4app and then selected the migration option. They offered two options for the migration supposedly an easy and a more custom migration. I clicked easy and it worked but I wish there was a description there detailing what I’m choosing (e.g. if I click easy and it doesn’t work can I have a do over? And if so why not do easy by default and offer the advanced option when something doesn’t work?).\nAfter clicking the easy option I got some emails from parse and the UI showed my app from Parse being migrated at 0%. Since I don’t have much of a database I assumed this would be instant and it wasn’t. It took a bit under 10 minutes so your millage may vary, during those 10 minutes I tried to reload the site and something didn’t work but afterwards things started working and seemed in order so it might have been a small hiccup.\nThe end result looks great and the only thing I had to change in the app to get it to work was this:\nprivate static final String PARSE_SERVER = \u0026quot;https://parseapi.back4app.com\u0026quot;; Parse.initialize(PARSE_SERVER, APPLICATION_ID, CLIENT_KEY); I had to update the parse library since I was still using an older version now the initialize method takes the new server URL and I could set the back4app URL to the parse SDK. That one small change was enough and everything started working.\nFuture I like parse a lot, now that it’s open and has some solid servers it might be superior to firebase as it provides options and can’t be brought down by one company. I’d be very interested to hear about other companies besides back4app, I think that having multiple companies in this field will help them all grow in a similar way that multiple Linux distributions helped redhat grow.\nI wonder if parse hosting will become a commodity in the future and I’d really like to hear stories/explanations about migrating live users from one parse host to another. If that is feasible parse might be a really good option for a generic app backend. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nRicardo Vicari — March 11, 2017 at 12:51 am (permalink) Ricardo Vicari says:\nShai, you dont sleep??? 🙂\nRicardo Vicari — March 11, 2017 at 12:53 am (permalink) Ricardo Vicari says:\nShai, I currently have a company that develops solutions with totalcross (www.totalcross.com) but I’m thinking of migrating to codenameone, but I’m worried about performance, we have running applications that have 100, 200 thousand records with SQLite and SQLite native wheel Inside Totalcross, how does it work in cn1?\nShai Almog — March 11, 2017 at 6:19 am (permalink) Shai Almog says:\nI haven’t used totalcross since it was superwaba (back in the palmpilot days). Back then it was an interpreter, no idea what they are doing now.\nSince Codename One translates code to native and compiles it we have native speeds. In this particular case the speed will be limited by sqlite not by us. Either way, do a test case and benchmark to see how it will work.\nYou can also write native code to optimize cases that we might not handle efficiently enough.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/migrating-from-parse-back4app/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/migrating-from-parse-back4app/parse.com-post-header.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA couple of years ago I wrote an app for my spouses yoga studio for managing her student list. I intended to open source it but the code is a bit messy and I can’t seem to find the time/energy to clean it up. I used the excellent \u003ca href=\"https://github.com/sidiabale/parse4cn1\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eparse4cn1\u003c/a\u003e library from \u003ca href=\"https://www.smash-ict.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eChidiebere Okwudire\u003c/a\u003e during the height of Parse.\u003c/p\u003e\n\u003cp\u003eAs Parse ended I started thinking about contingency plans but after a few emails with Chidi and his \u003ca href=\"/blog/how-i-chose-my-replacement-for-parse-com/\"\u003eposts\u003c/a\u003e detailing the various \u003ca href=\"/blog/how-i-chose-my-replacement-for-parse-com-part-2/\"\u003eoptions\u003c/a\u003e I thought it might be possible to take the \u0026ldquo;lazy approach\u0026rdquo;.\u003c/p\u003e","title":"Migrating from Parse to Back4app"},{"content":"\nCodename One, the \u0026ldquo;industry defining\u0026rdquo; Write Once Run Anywhere native mobile app platform for Java developers has just published version 3.6.\nWe’re thrilled with this release whose key features are offline build support and official support for UWP (Universal Windows Platform). Starting with this release we are changing the scope for Codename One: Instead of trying to be \u0026ldquo;as good as native\u0026rdquo; we’d like to aim to be \u0026ldquo;better than native\u0026rdquo;.\nWe already offer many advantages over native platform development:\nFaster builds and build cycles\nPortability\nEasier customization of the UI with ability to control every pixel\nWith 3.6 we hammered down all of these to a fine tuned machine and moving forward we’d like to build the Codename One that is better than native.\nYou can check out our press release here.\nSpecial Sale To celebrate this release we are offering the first year of the annual enterprise subscription at half of the standard monthly price which totals at 199 USD per month (2,388 USD for the year). You can take advantage of this offer by logging in and clicking the button below. This will allow you to take advantage of all the enterprise features including offline builds and enhanced support…​\nThis special offer expires on Friday!\nLast year we had a special promotion for JavaScript builds. A lot of you got to experiment with the JavaScript port thanks to that and it will be ending very soon!\nSo if you found that valuable this is probably the best price you will get on an enterprise subscription.\n__ The special deal has elapsed, thanks for all of you who signed up! Highlights of this Release Offline Build Support – Building thru the cloud is one of the \u0026ldquo;defining features\u0026rdquo; of Codename One, but some government level customers need the ability to build offline due to regulatory concerns\nProduction grade UWP (Universal Windows Platform) Port – UWP allows seamless native support for Windows 10 on Intel/ARM devices \u0026amp; PC’s such as the very popular Surface line\nNew GUI Builder Release – We released the new GUI builder. It still has rough edges but is improving at a rapid pace\nRound Borders – Round style borders are available now both in the designer and code\nFloating Action Button – New FloatingActionButton component that allows badging as well\nIn App Purchase Subscriptions \u0026amp; Receipts – We completely rewrote the IAP documentation and added support for subscriptions\nSecurity Enhancements – We introduced seamless storage encryption \u0026amp; certificate pinning (SSL Pinning)\nNew \u0026amp; Remastered Demos – Demos were overhauled and new demos were added based on PSD design showing the level of creativity that you can integrate into your applications\nURL \u0026amp; File API’s – Easier porting for existing Java code thru File \u0026amp; URL API’s\nProperties – Properties allow us to build terse/type safe efficient mapping to storage/database/XML/JSON etc.\nNewer Defaults – Java 8 \u0026amp; Android API 23 are now on by default as well as xcode 7.3 with xcode 8 coming soon. Android’s peer component is also on by default\nEasy Caching – Caching HTTP has never been easier…​\nLowlights Overall we are very happy with this release we think we dotted the i’s and crossed the t’s. This is to a large part due to the delay of the release from December. We still had to push back some issues to 3.7 but that’s always unavoidable.\nThe one thing we really didn’t get out in this release is a new Codename One course which we’ve been working on for a while. We hope we’ll get it done during the 3.7 era but video production is always a big effort and we just don’t have enough hours in the day…​\nOnwards to 3.7 Version 3.7 work is already underway. We hope to get the z-ordering in native peers to work on all major platforms in this version. We think it will open up Codename One to a whole new type of application (e.g. Augmented Reality).\nOur biggest wish for 3.7 is on-device-debugging but it’s a big feature so it’s unclear if it’s something that we’ll be able to deliver soon.\nWe Need your Help Spread the word, please let people know about us.\nSign up for enterprise accounts, besides the huge benefits of an enterprise account these are the guys that keep the lights on here and allow us to build Codename One. If your company can afford it please take the time and upgrade to enterprise, this will allow us to work on the things that are important for your company!\nThanks for reading this far and if you have any thoughts/suggestions of any kind please feel free to post below! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nBoniface N. Githinji — January 16, 2017 at 5:34 pm (permalink) Boniface N. Githinji says:\nThese are great advancements. Kudos team CodenameOne.\nI can attest to just how great this platform is, just finished working on a new app and it’s incredibly gorgeous and goes a long way to show just what is possible with this platform. https://play.google.com/sto…\nhttps://uploads.disquscdn.c… https://uploads.disquscdn.c… https://uploads.disquscdn.c… https://uploads.disquscdn.c…\nbryan — January 16, 2017 at 7:44 pm (permalink) bryan says:\nScreenshots on the app store look quite impressive. Well done !\nShai Almog — January 17, 2017 at 6:47 am (permalink) Shai Almog says:\nYou guys made a lot of progress since the screenshots were added here: https://www.codenameone.com…\nWe’ll try to update to the latest screenshots!\nChidiebere Okwudire — January 17, 2017 at 6:58 am (permalink) Chidiebere Okwudire says:\nGreat job guys! I’ve been out of touch lately due to other commitments but I follow the updates and look forward to when I can get busy with CodenameOne again.\nLukman Javalove Idealist Jaji — January 17, 2017 at 2:42 pm (permalink) Lukman Javalove Idealist Jaji says:\nSasa boniface…\ndid you generate your UI from a PSD?\nBoniface N. Githinji — January 17, 2017 at 3:16 pm (permalink) Boniface N. Githinji says:\nThanks bryan.\nBoniface N. Githinji — January 17, 2017 at 3:16 pm (permalink) Boniface N. Githinji says:\nHi Lukman, no; did it all in Java from scratch.\nBoniface N. Githinji — January 17, 2017 at 3:20 pm (permalink) Boniface N. Githinji says:\nThanks Shai. Yes indeed. This is a great platform, we are big believers in WORA and will keep shipping all our mobile apps via CodenameOne.\nLukman Javalove Idealist Jaji — January 17, 2017 at 5:39 pm (permalink) Lukman Javalove Idealist Jaji says:\nFantastic…….good job man….really good job\nLukman Javalove Idealist Jaji — January 17, 2017 at 6:06 pm (permalink) Lukman Javalove Idealist Jaji says:\npleae give me your email boniface….. thank you\nChen Fishbein — January 18, 2017 at 11:48 am (permalink) Chen Fishbein says:\nNice one! well done!\nBoniface N. Githinji — February 16, 2017 at 1:28 pm (permalink) Boniface N. Githinji says:\nFind our review of the Codename One platform here – http://sematime.com/product…\nKeep doing the good work we’ll keep evangelizing this framework here in Africa.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-3-6-now-live-special-sale/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-3-6-now-live-special-sale/codenameone-3-6.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/\"\u003eCodename One\u003c/a\u003e, the \u0026ldquo;industry defining\u0026rdquo; \u003cstrong\u003eWrite Once Run Anywhere native mobile app platform for Java developers\u003c/strong\u003e has just published version 3.6.\u003cbr\u003e\nWe’re thrilled with this release whose key features are offline build support and official support for UWP (Universal Windows Platform). Starting with this release we are changing the scope for Codename One: Instead of trying to be \u0026ldquo;as good as native\u0026rdquo; we’d like to aim to be \u0026ldquo;better than native\u0026rdquo;.\u003c/p\u003e","title":"Codename One 3.6 Now Live \u0026 Special Sale"},{"content":"\nCodename One 3.6 is finally landing early next week, this means that today there is no Friday release and we might skip it next week too so we can rest from this long release process. Once that is out of the way we can finally set our sights on 3.7.\nWe already have a long wishlist for that release and I hope we’ll be able to deliver on that.\nOn stackoverflow there were quite a few questions but I’d like to only focus on one this week…​\nStefan Eder asked for overshadowing which is the process of overriding our implementation with his changes.\nThis isn’t the first time people asked for that but we won’t deliver it. Doing this creates huge problems:\nDevelopers don’t file issues or submit fixes instead they make local fixes\nDevelopers break things due to complex behaviors then try to get support and blame us for the issues\nWe have a process of submitting patches to Codename One, patches are always accepted quickly when they are valid. If something needs fixing that’s what you need to do. If you need a hack then submit a patch that defines the extension point that you need. That’s why we are open source…​\nIn the past this might have been painful as you would need to wait until we updated the servers, but since changes go in every week in recent revisions this is no longer an issue. Don’t think of it as \u0026ldquo;contributing\u0026rdquo;, think of it as free code reviews where the entire community pulls together to improve your work…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-38/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-38/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One 3.6 is finally landing early next week, this means that today there is no Friday release and we might skip it next week too so we can rest from this long release process. Once that is out of the way we can finally set our sights on 3.7.\u003cbr\u003e\nWe already have a long wishlist for that release and I hope we’ll be able to deliver on that.\u003c/p\u003e","title":"Questions of the Week 38"},{"content":"\nWe haven’t talked as much in recent years about what it takes to run Codename One. Our infrastructure and backend are pretty complex with multiple pieces working in cohort to make everything feel like a single product. As part of that we work with 5-10 different backend SaaS providers that sell us various services, this might seem like an \u0026ldquo;odd\u0026rdquo; statement since the number should be fixed but it isn’t…​\nWe change provider and some backend providers like Intercom/Cloudflare or AWS you might not think of as proper backend (like Digital Ocean or Linode) so the number will fluctuate based on our moving servers from one provider to another and based on what you would consider a provider.\nA couple of years ago we moved all our Linux based infrastructure from AWS reserved instances to digital ocean. The price was better (even after factoring reserved instance discount) and simplicity/service were superior so there was really no question. As an added bonus digital ocean accepts payments via PayPal making it much cheaper for us as we get paid thru paypal too, this saves on currency conversion and PayPal fees.\nWe’ve recently become aware of Linode and were very skeptical. The pricing was literally half the price of the already cheap digital ocean. Digital ocean hasn’t made any price cuts in over 2 years which is odd in the competitive cloud server landscape. Since we don’t use any of the value added features of digital ocean we decided to give linode a chance.\nThey start by billing with credit card but they accept paypal once they have a card on record. Setting up the servers was as easy as doing it in digital ocean and once they were up we could literally move traffic to the new servers. Thanks to cloudflare we switched servers while people were working with no downtime and no one was the wiser…​\nOnce we validated everything worked we deleted the old digital ocean servers. The whole process took a couple of days and cut our Linux server expenses by half (we still pay a lot for App engine, Mac hosting \u0026amp; Windows hosting though). The real cool thing is that the servers seem much faster than the old digital ocean ones. This might be because we are on a shared machine that isn’t filled yet so it might change.\nThe web interface for linode doesn’t seem as polished as the one on digital ocean but it works well and we are very happy with the result as this literally maps to thousands of dollars saved over a couple of days work!\nIaaS vs. PaaS Our biggest expense is still App Engine, we planned to dump it as soon as we can but it’s hard to remove it from our infrastructure as it is embedded so deep. The story above pretty much proves to me the value of IaaS over\nPaaS when building major apps, it allowed us to cut expenses with almost no effort!\nI used to be a big PaaS fan as I can see the value of binding an entire infrastructure seamlessly but with the trouble with had with App Engine over the years I’m now convinced that I was wrong.\nFuture Plans We want to move additional resources from app engine to Linode and probably AWS webservices for some of the features. The timeline for this is flexible though as it’s really hard for us to allocate developers to rewrite stuff that already works even if it does save some money. That’s part of the difficulty in running a SaaS company you sometimes need to compromise on these sort of things to keep moving ahead.\nWe’ll try to find better hosts for our Windows/Mac servers which will allow us to add more servers there and shorten the iOS build times for everyone. So far these fields aren’t as competitive as the Linux hosting fields so we’re not as optimistic about that.\nAnother thing on our todo list for the past couple of years is packaging everything into containers. We started Codename One before Docker was \u0026ldquo;a thing\u0026rdquo; so by the time it got on our radar we had too much invested. Had we used it this move might have been even simpler than it already was. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMark Korsak — January 13, 2017 at 5:29 pm (permalink) Mark Korsak says:\nThis is great to see! Glad to hear the transition went so smooth. Let us know if there’s ever anything we can do for you! – Linode Community Advocate\nJoão Bastos — January 13, 2017 at 11:43 pm (permalink) João Bastos says:\nWell, my doubts about linode are no longer here… Thank You 🙂\nAhmed Kamel Taha — January 16, 2017 at 11:21 pm (permalink) Ahmed Kamel Taha says:\nHave you considered jelastic? Mirhousting provide a really competitive prices for PaaS \u0026amp; CaaS only $1.15a month for the cloudlet and they only charge for the real usage with automatic vertical \u0026amp; horizontal scaling\nhttps://jelastic.cloud/deta…\nShai Almog — January 17, 2017 at 5:21 am (permalink) Shai Almog says:\nThat’s a PaaS, check out what I said about PaaS…\nI tried them a few years ago mostly thinking about replacing App Engine with them. I like the idea in general but I’m not sure I want to go there and financially I’m not sure it makes sense. In our case the servers we use are pretty darn sophisticated (build servers) and PaaS might be over simplistic.\nNkansah Rexford — January 17, 2017 at 9:57 am (permalink) Nkansah Rexford says:\nAnd you know why I didn’t start with Linode?\nBecause you don’t have a 5$ option! Not everyone needs a 2 GB 1 Core 24 GB SSD2 TB 40 Gbps 125 Mbps on the first day of launch.\nI’m currently on a 10$ DO droplet, although I started with 5$. and with the 5$ I could run 3 WordPress instances, 2 Django apps, 1 NodeJS app and 2 static sites, with Nginx as the front-end server, all with an average of about 4 seconds response time with a combined average of 15,000 hits a month. Just 5$.\nAlthough the Linode 10$ offer beats that of DO, I think that 5$ on DO is what attracts, and although I’m yet to face any crippling funds reasons to want to move my entire system to Linode, DO works, and I’ve never had not even 1 second issue with DO since I started using over some 2 years ago.\nAt just an extra 1$/month, I can top up my DO SSD to 40 Gig from 30.\nFortunately for me, my applications haven’t scaled enough for the price difference to mean a lot. The 5$ got me into DO. Good to know Linode has great options too. It might come handy.\nShai Almog — January 20, 2017 at 12:37 pm (permalink) Shai Almog says:\nThat’s a good point. Our needs require stronger servers so I wasn’t even aware of the 5USD tier.\nJust to be clear I really like Digital Ocean too, they were super nice when I asked them about the prices of Linode. They wouldn’t match the prices but after we moved they refunded the remainder balance back into our paypal which I totally didn’t expect…\nnoxiouz — January 25, 2017 at 6:01 pm (permalink) noxiouz says:\nI’m still a big fan of PaaS.\nCould you please write some words about your negative experience?\nShai Almog — January 26, 2017 at 6:58 am (permalink) Shai Almog says:\nI wrote a bit about it here: https://www.codenameone.com…\nGenerally Google just started overcharging us at a rate that would have bankrupted us very quickly.\nThe problem is that to be effective PaaS sometimes hides details and in this case we had no way to track the cause of the HUGE expenses. I opened a ticket with Google as a gold customer (400USD per month for that \u0026ldquo;privilege\u0026rdquo;) and essentially got an \u0026ldquo;it’s a problem on your end, we checked in our logs\u0026rdquo;. Which is essentially a big F U.\nThis went back and forth a lot but basically the gist of it is you have no way of \u0026ldquo;knowing\u0026rdquo; what you are paying for with PaaS as it’s way too big. After migrating away our scaling improved because we could write better code (without all the app engine restrictions) and because we could add affordable servers/CDN.\nJohn Scarborough — February 21, 2017 at 10:09 am (permalink) John Scarborough says:\nWell this has just changed with Linode offering a $5 option now. Ive already moved some droplets over! I dont need snapshots/block storage for them … Good luck!\nsmaugstheswagger — November 25, 2017 at 10:46 am (permalink) smaugstheswagger says:\nLinode is much better than any shared hosting. Shared hosting has lots of issues regarding performance and security, while Linode doesn’t because it is a VPS. Try Linode on Cloudways and you will see the difference in performance. This platform has its own custom stack optimized for performance. Together with Linode, you will experience a significant increase in performance.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/migrating-from-digital-ocean-linode/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/migrating-from-digital-ocean-linode/under-the-hood.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe haven’t talked as much in recent years about what it takes to run Codename One. Our infrastructure and backend are pretty complex with multiple pieces working in cohort to make everything feel like a single product. As part of that we work with 5-10 different backend SaaS providers that sell us various services, this might seem like an \u0026ldquo;odd\u0026rdquo; statement since the number should be fixed but it isn’t…​\u003c/p\u003e","title":"Migrating from Digital Ocean to Linode"},{"content":"\nCertificate pinning is a security measure designed to thwart potentially dangerous and complex attacks. Since those sort of attacks are pretty hard to execute it’s a security measure that is probably unnecessary for most developers. However, if you are building an application for a very sensitive industry (e.g. Government, Banking etc.) you might be required to include this defensive measure.\nWhen we connect to an HTTPS server our client checks the certificate on the server. If the certificate was issued by a trusted certificate authority then the connection goes thru otherwise it fails. Let’s imagine a case where I’m sitting in a coffee shop connected to the local wifi, I try to connect to gmail to check my email. Since I use HTTPS to Google I trust my connection is secure.\nWhat if the coffee shop was hacked and the router is listening in on everything?\nSo HTTPS is encrypted and the way encryption works is thru the certificate. The server sends me a certificate and we can use that to send encrypted data to it.\nWhat if the router grabs the servers certificate and communicates with Google in my name?\nThis won’t work since the data we send to the server is encrypted with the certificate from the server.\nSo what if the router sends its own \u0026ldquo;fake certificate\u0026rdquo;?\nThat won’t work either. All certificates are signed by a \u0026ldquo;certificate authority\u0026rdquo; indicating that a google.com certificate is valid.\nWhat if I was able to get my fake certificate authorized by a real certificate authority?\nThat’s a problem!\nIt’s obviously hard to do but if someone was able to do this he could execute a \u0026ldquo;man in the middle\u0026rdquo; attack as described above. People were able to fool certificate authorities in the past and gain fake certificates using various methods so this is possible and probably doable for any government level attacker.\nCertificate Pinning This is the attack certificate pinning (or SSL pinning) aims to prevent. We code into our app the \u0026ldquo;fingerprint\u0026rdquo; of the certificate that is \u0026ldquo;good\u0026rdquo; and thus prevent the app from working when the certificate is \u0026ldquo;fake\u0026rdquo;. This might break the app if we replace the certificate at some point but that might be reasonable in such a case.\nTo do this we introduced a new cn1lib. that fetches the certificate fingerprint from the server, we can just check this fingerprint against a list of \u0026ldquo;authorized\u0026rdquo; keys to decide whether it is valid. You can install the SSLCertificateFingerprint from the extensions section in Codename One Settings and use something like this to verify your server:\nif(CheckCert.isCertCheckingSupported()) { String f = CheckCert.getFingerprint(myHttpsURL); if(validKeysList.contains(f)) { // OK it's a good certificate proceed } else { if(Dialog.show(\u0026quot;Security Warning\u0026quot;, \u0026quot;WARNING: it is possible your commmunications are being tampered! We suggest quitting the app at once!\u0026quot;, \u0026quot;Quit\u0026quot;, \u0026quot;Continue\u0026quot;)) { Display.getInstance().exitApplication(); } } } else { // certificate fingerprint checking isn't supported on this platform... It's your decision whether to proceed or not } Notice that once connection is established you don’t need to verify again for the current application run. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nEric Kimotho — January 18, 2021 at 7:09 pm (permalink) Eric Kimotho says:\nThis is great.\nHow do we get \u0026ldquo;validKeysList\u0026rdquo; required in this line\nif(validKeysList.contains(f))\nShai Almog — January 19, 2021 at 2:46 am (permalink) Shai Almog says:\nThis article is somewhat out of date by now. We have a builtin approach that works better. See: \u0026lt;/javadoc/com/codename1/io/ConnectionRequest/#checkSSLCertificates-com.codename1.io.ConnectionRequest.SSLCertificate:A-\u0026gt;\nEric Kimotho — January 19, 2021 at 8:03 pm (permalink) Eric Kimotho says:\nThank you. I tried to follow link above and came up snippet below. But length of SSLCertificate Array is 0 for all https url i tried. Please note i am using synchronous version of ConnectionRequest to be able to update UI incase network error. Please assist with correct implementation\nEric Kimotho — January 19, 2021 at 8:05 pm (permalink) Eric Kimotho says:\nprivate void certPinning() {\nConnectionRequest request = new ConnectionRequest();\nrequest.setUrl(myHttpsUrl);\nrequest.setCheckSSLCertificates(true);\nswitch (Display.getInstance().getPlatformName()) {\ncase \u0026ldquo;and\u0026rdquo;:\ncase \u0026ldquo;ios\u0026rdquo;:\ntry {\nif (request.canGetSSLCertificates()\n\u0026amp;\u0026amp; getSSLCertArray(request).length \u0026gt; 0) {\nnew SignIn().show();\n} else {\nshowWarningAlert(\u0026ldquo;Connection Alert\u0026rdquo;,\n\u0026ldquo;Secure Connection is tampered, quit app now\u0026rdquo;);\n}\n} catch (IOException e) {\nLog.p(\u0026ldquo;Exception \u0026quot; + e.getMessage());\n}\nbreak;\ncase \u0026ldquo;win\u0026rdquo;:\nnew SignIn().show();\nbreak;\n}\n}\nprivate SSLCertificate[] getSSLCertArray(ConnectionRequest request)\nthrows IOException {\nLog.p(\\nCert Length \u0026quot; + request.getSSLCertificates().length);\nreturn request.getSSLCertificates();\n}\nShai Almog — January 20, 2021 at 3:25 am (permalink) Shai Almog says:\nThis is before the call. I specifically pointed at checkSSLCertificates which is a callback that will be invoked when the request data arrives.\nEric Kimotho — January 20, 2021 at 6:05 pm (permalink) Eric Kimotho says:\nAt least using below implementations i can get certificate length as 2, Please Confirm if these implementations are okay\n//Synchronous Implementation\nprivate void certPinning() {\nConnectionRequest request = new ConnectionRequest();\nrequest.setUrl(myHttpsUrl);\nrequest.setHttpMethod(\u0026ldquo;POST\u0026rdquo;);\nrequest.setTimeout(15000);\nrequest.setReadTimeout(20000);\nrequest.addArgument(\u0026ldquo;dataTag\u0026rdquo;, \u0026ldquo;request data\u0026rdquo;);\nrequest.setFailSilently(true);\nrequest.setCheckSSLCertificates(true);\nNetworkManager.getInstance().addToQueueAndWait(request);\nswitch (request.getResponseCode()) {\ncase 0:\ncase 404:\n//Connection error\nbreak;\ncase 200:\nbyte[] result = request.getResponseData();\nString resp = new String(result);\nbreak;\n}\nswitch (Display.getInstance().getPlatformName()) {\ncase \u0026ldquo;and\u0026rdquo;:\ncase \u0026ldquo;ios\u0026rdquo;:\ntry {\nif (request.canGetSSLCertificates()\n\u0026amp;\u0026amp; getSSLCertArray(request).length \u0026gt; 0) {\n//Continue\n} else {\nshowWarningAlert(\u0026ldquo;Connection Alert\u0026rdquo;,\n\u0026ldquo;Secure Connection is tampered, quit app now\u0026rdquo;);\n}\n} catch (IOException e) {\n}\nbreak;\ncase \u0026ldquo;win\u0026rdquo;:\n//Continue\nbreak;\n}\n}\nprivate SSLCertificate[] getSSLCertArray(ConnectionRequest request)\nthrows IOException {\nLog.p(\\nCert Length \u0026quot; + request.getSSLCertificates().length);\nreturn request.getSSLCertificates();\n} //Asynchronous Implementation\n//Seems checkSSLCertificates function requires Asynchronous version of ConnectionRequest\nprivate void certPinning() {\nString resp;\nConnectionRequest request = new ConnectionRequest(){\n@Override\nprotected void checkSSLCertificates(SSLCertificate[] certificates) {\nLog.p(\u0026ldquo;Cert Len \u0026quot; + certificates.length);\nswitch (Display.getInstance().getPlatformName()) {\ncase \u0026ldquo;and\u0026rdquo;:\ncase \u0026ldquo;ios\u0026rdquo;:\nif (certificates.length == 0) {\nLog.p(\u0026ldquo;Secure Connection is tampered, quit app now\u0026rdquo;);\n} else {\n//Continue\n}\nbreak;\ncase \u0026ldquo;win\u0026rdquo;:\n//Continue\nbreak;\n}\n}\n}\n@Override\nprotected void readResponse(InputStream input) throws IOException {\nresult = Result.fromContent(input, Result.JSON);\nresp = result.getAsString(\u0026ldquo;root\u0026rdquo;);\n}\n@Override\nprotected void postResponse() {\nLog.p(resp);\n}\nrequest.setUrl(myHttpsUrl);\nrequest.setHttpMethod(\u0026ldquo;POST\u0026rdquo;);\nrequest.setTimeout(15000);\nrequest.setReadTimeout(20000);\nrequest.addArgument(\u0026ldquo;dataTag\u0026rdquo;, \u0026ldquo;request data\u0026rdquo;);\nrequest.setFailSilently(true);\nrequest.setCheckSSLCertificates(true);\nNetworkManager.getInstance().addToQueue(request);\nNetworkManager.getInstance().addErrorListener((e) -\u0026gt; e.consume());\n}\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/certificate-verification-avoid-pinning-vulnerability/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/certificate-verification-avoid-pinning-vulnerability/security.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCertificate pinning is a security measure designed to thwart potentially dangerous and complex attacks. Since those sort of attacks are pretty hard to execute it’s a security measure that is probably unnecessary for most developers. However, if you are building an application for a very sensitive industry (e.g. Government, Banking etc.) you might be required to include this defensive measure.\u003c/p\u003e\n\u003cp\u003eWhen we connect to an HTTPS server our client checks the certificate on the server. If the certificate was issued by a trusted certificate authority then the connection goes thru otherwise it fails. Let’s imagine a case where I’m sitting in a coffee shop connected to the local wifi, I try to connect to gmail to check my email. Since I use HTTPS to Google I trust my connection is secure.\u003c/p\u003e","title":"Certificate Verification, Avoid SSL Pinning Vulnerability"},{"content":"\nOur eclipse IDE support has been around for quite a while now but has never stood up to the quality and update pace of NetBeans. Recently even our IntelliJ/IDEA support has surpassed the quality of our eclipse plugin and the blame should be on us.\nOne of the problems is that our team doesn’t use eclipse and uses a diverse set of OS’s (Macs/Windows) which is problematic when sharing workspaces. Integrating the eclipse plugin build into our standard release process proved really hard and it ended up eventually as something we need to do but never got around to do it…​\nWe’ve spent the last couple of weeks trying to get eclipse to work with the release build process and it seems we got it right. Our latest version of the eclipse plugin was released with the other plugins and from now on we hope all the plugins will be released together!\nPlease try updating the eclipse plugin, it should be 3.6.0 right now and would ideally be in sync with the versions from the other IDE’s.\nWe integrated the new demos that are already a part of the newer IDE’s and we’ll try to better keep up with the changes from now on. The one major feature that is still missing from the eclipse plugin is support for cn1lib creation which we hope to add as we move forward.\nAs part of this work I was very impressed by the improvements made in eclipse neon which is much better than previous iterations of eclipse (speaking as a Mac user). The IDE has been responsive and the UI has been closer to what one would expect in such a case.\nIf you run into weird errors or regressions in the new eclipse plugin update please let us know ASAP. These might be related to the codebase transition and it’s important we get a handle on them quickly!\n__ Update: It seems older versions of eclipse didn’t react well to the new plugin so with the new plugin we requite Neon and Java 8 New Updates to All Plugins We just released new updates to all the plugins for the 3.6 release. We are now in a week long code freeze and if there are no regressions there won’t be an update for the next two weeks. If we do find a regression we’ll push out a new 3.6 release candidate during the week and possibly postpone a weekly update after that. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\ndingfelder — January 12, 2018 at 8:37 am (permalink) dingfelder says:\nHi – I’m using the eclipse version – a quick comment: the build process isn’t copying all the files the way I would expect – for instance, the sql demo requires a db file to be copied to the cn folder – currently this has to be done manually. I suspect this is hitting anyone trying to run the demos. cheers\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/first-class-eclipse-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/first-class-eclipse-support/eclipse.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOur eclipse IDE support has been around for quite a while now but has never stood up to the quality and update pace of NetBeans. Recently even our IntelliJ/IDEA support has surpassed the quality of our eclipse plugin and the blame should be on us.\u003c/p\u003e\n\u003cp\u003eOne of the problems is that our team doesn’t use eclipse and uses a diverse set of OS’s (Macs/Windows) which is problematic when sharing workspaces. Integrating the eclipse plugin build into our standard release process proved really hard and it ended up eventually as something we need to do but never got around to do it…​\u003c/p\u003e","title":"First Class Eclipse Support"},{"content":"\nOn occasion developers ask us for cn1lib dependencies, e.g. allowing one cn1lib to use functionality in another cn1lib. This isn’t something we rolled into the cn1lib infrastructure because we strongly believe in simplicity. Dependency management solutions become fragile once nesting sets in and often mask over-engineering which is really dangerous for a tool that depends on small footprint.\nA cn1lib is really just an ant project that packages the results into a zip containing nested zips with the data relevant to all the platforms. To add another cn1lib lib to the classpath first you need to unzip that cn1lib.\nThe main.zip file from the cn1lib will include the classes you need to compile. Now we can just add that main.zip to our compile path by editing the build.xml file. We can change the javac statement to include that file:\n\u0026lt;javac destdir=\u0026quot;build/tmp\u0026quot; source=\u0026quot;1.8\u0026quot; target=\u0026quot;1.8\u0026quot; bootclasspath=\u0026quot;lib/CLDC11.jar\u0026quot; classpath=\u0026quot;myPathToUnzippedCN1Lib/main.zip:${javac.classpath}:${build.classes.dir}\u0026quot;\u0026gt; \u0026lt;src path=\u0026quot;${src.dir}\u0026quot;/\u0026gt; \u0026lt;/javac\u0026gt; This will only solve a part of the problem, we also need to edit the classpath in the IDE settings if you are in NetBeans we can do this for both NetBeans and IntelliJ by editing the nbproject/project.properties file:\njavac.classpath= ${file.reference.CLDC11.jar}: ${file.reference.CodenameOne.jar}: ${file.reference.CodenameOne_SRC.zip}: ${file.reference.MyCn1Lib-override}: ${file.reference.main.zip} file.reference.main.zip=myPathToUnzippedCN1Lib/main.zip Now the dependency will exist, notice you will need to have both your cn1lib and the dependent cn1lib installed in the project. That’s why our library extension tool supports the declaration of dependencies when you submit your library. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nKapeutini Jean Voisin — March 13, 2018 at 5:27 pm (permalink) Kapeutini Jean Voisin says:\nokay, I’ll not use it, thanks\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-nest-cn1libs-cross-dependencies/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-nest-cn1libs-cross-dependencies/just-the-tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOn occasion developers ask us for cn1lib dependencies, e.g. allowing one cn1lib to use functionality in another cn1lib. This isn’t something we rolled into the cn1lib infrastructure because we strongly believe in simplicity. Dependency management solutions become fragile once nesting sets in and often mask over-engineering which is really dangerous for a tool that depends on small footprint.\u003c/p\u003e\n\u003cp\u003eA cn1lib is really just an ant project that packages the results into a zip containing nested zips with the data relevant to all the platforms. To add another cn1lib lib to the classpath first you need to unzip that cn1lib.\u003c/p\u003e","title":"TIP: Nest cn1libs Cross Dependencies"},{"content":"\nWe thought about skipping the release today and going strait for a release on the day of the code freeze but this might create a situation where a regression is missed because you didn’t have enough time with the code. This means we might have more than one update until the 16th release of 3.6 so please bare with us.\nWe will release plugin updates with the code freeze and they should include the release candidate of 3.6 within them.\nDue to the holidays stack overflow was relatively calm depite our week long absence…​\nFaugan Bidi asked how to add a tree to the overflow menu. This isn’t really possible because the overflow menu is really a list. However, I did provide another way that is more elegant to achieve what is effectively the same result.\nalejandromay asked and answered a question about a build error with an enterprise certificate. There are some edge cases with those certificates, we’ve made the UI of the settings a bit more intuitive for these various flags in the next update.\ntizbn asked about an omission in the current Codename One API for side menu. Right now commands can only be added with a box Y layout and can’t have more elaborate layout. Since this isn’t the first time I ran into this complexity I took it up and got it wrong myself 3 times already…​ Just goes to show you that we should always try again and again!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-37/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-37/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe thought about skipping the release today and going strait for a release on the day of the code freeze but this might create a situation where a regression is missed because you didn’t have enough time with the code. This means we might have more than one update until the 16th release of 3.6 so please bare with us.\u003cbr\u003e\nWe will release plugin updates with the code freeze and they should include the release candidate of 3.6 within them.\u003c/p\u003e","title":"Questions of the Week 37"},{"content":"\nJust a couple of weeks ago I was offering tips on how to search the website in lieu of a search engine. Having gone thru the process repeatedly and trying many different approaches and off the shelf solutions we decided to build something simple of our own and we did.\nThis is a compromise, search works on the server instead of using the fact that the site is statically generated. As a result it is far from ideal but it’s still pretty comprehensive and finds the right answers for most of the stuff we threw at it.\nOne of the features we added as an \u0026ldquo;afterthought\u0026rdquo; is probably the most important feature: the alternative search buttons…​\nWhen you search for something e.g. https://www.codenameone.com/search?q=floating+action+button\nYou are offered to try the search on Google, StackOveflow (Codename One tag) or our Google Group (Discussion Forum). This might sound mundane because you can just go to each of those resources and search but it’s crucial as many developers miss those resources…​\nWe considered adding github resources as well such as searching the sources or the issues but that might have created such an overwhelming amount of options that developers won’t check the other options.\nPlease try the new site search, let us know what you think and how we can improve this feature.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/site-search/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/site-search/new-features-4.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eJust a couple of weeks ago I was offering tips on how to search the website in lieu of a search engine. Having gone thru the process repeatedly and trying many different approaches and off the shelf solutions we decided to build something simple of our own and \u003ca href=\"/search.html\"\u003ewe did\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eThis is a compromise, search works on the server instead of using the fact that the site is statically generated. As a result it is far from ideal but it’s still pretty comprehensive and finds the right answers for most of the stuff we threw at it.\u003c/p\u003e","title":"Site Search"},{"content":"\nWe will release Codename One 3.6 on the 16th of January, this means we will enter code freeze on the 9th during which only critical bugs will be fixed with peer review. Since Codename One is a SaaS product release cycles aren’t as crucial for most of us but they provide a framework both for versioned builds and for us to focus on the more mundane aspects of product maintenence.\nWith 3.6 we are fine tuning the 4 releases per year approach we took in the past to a more convenient 3 – release per year cycle. This will allow us to deliver more refined releases while still delivering them which is harder to do without a fixed roadmap.\nOver the past few weeks we had to postpone many issues that we wanted to have in 3.6 due to the pressures of the looming release. We hope to address these issues early in the 3.7 release cycle. One such pain point is the support for z-ordering in peer components on iOS and other platforms (besides Android). This is a challenging feature and we just couldn’t justify something \u0026ldquo;half baked\u0026rdquo; so close to a stable release.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-3-6-release-plan/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-3-6-release-plan/codenameone-3-6.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe will release Codename One 3.6 on the 16th of January, this means we will enter code freeze on the 9th during which only critical bugs will be fixed with peer review. Since Codename One is a SaaS product release cycles aren’t as crucial for most of us but they provide a framework both for versioned builds and for us to focus on the more mundane aspects of product maintenence.\u003c/p\u003e","title":"Codename One 3.6 Release Plan"},{"content":"\n__ This is the third post in a three-part series on In-App purchase. Please check out Part I: Introduction to In-App Purchase and Part 2: Implementing Non-Renewable Subscriptions. Auto-renewable subscriptions provide, arguably, an easier path to recurring revenue than non-renewable subscriptions because all of the subscription stuff is handled by the app store. You defer almost entirely to the app store (iTunes for iOS, and Play for Android) for billing and management.\nIf there is a down-side, it would be that you are also subject to the rules of each app store – and they take their cut of the revenue. On iOS, you keep 70% of the revenue for the first year of a subscription. This increases to 85% after the first year. Google also let’s you keep 70% of the revenue on subscriptions. I read a number of news articles from June 2016, stating that they planned to increase this to 85% to match Apple but I haven’t been able to find any corroborating information on the Play site itself, so at the time of writing, it appears that they are still on the 70/30 split model.\nFor more information about Apple’s auto-renewable subscription features and rules see this document.\nFor more information about subscriptions in Google play, see this document.\nAuto-Renewable vs Non-Renewable. Best Choice? When deciding between auto-renewable and non-renewable subscriptions, as always, the answer will depend on your needs and preferences. Auto-renewables are nice because it takes the process completely out of your hands. You just get paid. On the other hand, there are valid reasons to want to use non-renewables. E.g. You can’t cancel an auto-renewable subscription for a user. They have to do that themselves. You may also want more control over the subscription and renewal process, in which case a non-renewable might make more sense.\nI recommend this blog post for a well-informed, critical review of Apple’s auto-renew process. (TLDR\u0026gt; He says to never use auto-renewables). I don’t have as much experience with in-app purchase as that author, but from my experiments, the auto-renewable option seems like a perfectly good solution.\nLearning By Example The remainder of this post describes the general workflow of subscription management on the server. It also demonstrates how use Apple’s and Google’s web services to validate receipts and stay informed of important events (such as when users cancel or renew their subscriptions).\nBuilding the IAP Demo Project To aid in this process, I’ve created a fully-functional in-app purchase demo project that includes both a client app and a server app.\nSetting up the Client Project Create a new Codename One project in Netbeans, and choose the \u0026ldquo;Bare-bones Hello World Template\u0026rdquo;. You should make your package name something unique so that you are able to create real corresponding apps in both Google Play and iTunes connect.\nOnce the project is created, copy this source file contents into your main class file. Then change the package name, and class name in the file to match your project settings. E.g. change package ca.weblite.iapdemo; to package \u0026lt;your.package.name.here\u0026gt;; and class IAPDemo implements PurchaseCallback to class YourClassName implements PurchaseCallback.\nAdd the Generic Web Service Client library to your project by going to \u0026ldquo;Codename Settings\u0026rdquo; \u0026gt; \u0026ldquo;Extensions\u0026rdquo;, finding that library, and click \u0026ldquo;Download\u0026rdquo;. Then \u0026ldquo;Refresh CN1 libs\u0026rdquo; as it suggests.\nChange the localHost property to point to your local machine’s network address. Using \u0026ldquo;http://localhost\u0026rdquo; is not going to cut it here because when the app is running on a phone, it needs to be able to connect to your web server over the network. This address will be your local network address (e.g. 192.168.0.9, or something like that).\nprivate static final String localHost = \u0026quot;http://10.0.1.32\u0026quot;; Add the ios.plistInject build hint to your project with the value \u0026lt;key\u0026gt;NSAppTransportSecurity\u0026lt;/key\u0026gt; \u0026lt;dict\u0026gt; \u0026lt;key\u0026gt;NSAllowsArbitraryLoads\u0026lt;/key\u0026gt; \u0026lt;true/\u0026gt; \u0026lt;/dict\u0026gt;. This is so that we can use http urls in iOS. Since we don’t intend to full publish this app, we can cut corners like this. If you were creating a real app, you would use proper secure URLs.\n__ In the client project, you’ll notice some places where we use Purchase.purchase(sku) for purchasing a product, and other places where we use Purchase.subscribe(sku). The correct method will depend on how you have set up the product in the Google Play store. If the product is set up as a subscription, you must use subscribe(). Otherwise, you should use purchase(). Setting up the Server Project Download the CN1-IAP-Server demo project from Github, and run its \u0026ldquo;install-deps\u0026rdquo; ANT task in order to download and install its dependencies to your local Maven repo.\n__ For the following commands to work, make sure you have \u0026ldquo;ant\u0026rdquo;, \u0026ldquo;mvn\u0026rdquo;, and \u0026ldquo;git\u0026rdquo; in your environment PATH. $ git clone https://github.com/shannah/cn1-iap-demo-server $ cd cn1-iap-demo-server $ ant install-deps Open the project in Netbeans\nSetting up the Database Create a new database in your preferred DBMS. Call it anything you like.\nCreate a new table named \u0026ldquo;RECEIPTS\u0026rdquo; in this database with the following structure:\ncreate TABLE RECEIPTS ( TRANSACTION_ID VARCHAR(128) not null, USERNAME VARCHAR(64) not null, SKU VARCHAR(128) not null, ORDER_DATA VARCHAR(32000), PURCHASE_DATE BIGINT, EXPIRY_DATE BIGINT, CANCELLATION_DATE BIGINT, LAST_VALIDATED BIGINT, STORE_CODE VARCHAR(20) default '' not null, primary key (TRANSACTION_ID, STORE_CODE) ) Open the \u0026ldquo;persistence.xml\u0026rdquo; file in the server netbeans project.\nChange the data source to the database you just created. If you’re not sure how to create a data source, see my previous tutorial on connecting to a MySQL database.\nTesting the Project At this point we should be able to test out the project in the Codename One simulator to make sure it is working.\nBuild and Run the server project in Netbeans. You may need to tell it which application server you wish to run it on. I am running it on the Glassfish 4.1 that comes bundled with Netbeans.\nBuild and run the client project in Netbeans. This should open the Codename One simulator.\nWhen the app first opens you’ll see a screen as follows:\nThis screen is for testing consumable products, so we won’t be making use of this right now.\nOpen the hamburger menu and select \u0026ldquo;Subscriptions\u0026rdquo;. You should see something like this:\nClick on the \u0026ldquo;Subscribe 1 Month No Ads\u0026rdquo; button. You will be prompted to accept the purchase:\nUpon completion, the app will submit the purchase to your server, and if all went well, it will retrieve the updated list of receipts from your server also, and update the label on this form to say \u0026ldquo;No Ads. Expires \u0026lt;some date\u0026gt;\u0026rdquo;:\n__ This project is set up to use an expedited expiry date schedule for purchases from the simulator. 1 month = 5 minutes. 3 months = 15 minutes. This helps for testing. That is why your expiry date may be different than expected. Just to verify that the receipt was inserted correctly, you should check the contents of your \u0026ldquo;RECEIPTS\u0026rdquo; table in your database. In Netbeans, I can do this easily from the \u0026ldquo;Services\u0026rdquo; pane. Expand the database connection down to the RECEIPTS table, right click \u0026ldquo;RECEIPTS\u0026rdquo; and select \u0026ldquo;View Data\u0026rdquo;. This will open a data table similar the the following:\nA few things to mention here:\nThe \u0026ldquo;username\u0026rdquo; was provided by the client. It is hard-coded to \u0026ldquo;admin\u0026rdquo;, but the idea is that you would have the user log in and you would have access to their real username.\nAll dates are stored as unix timestamps in milliseconds.\nIf you delete the receipt from your database, then press the \u0026ldquo;Synchronize Receipts\u0026rdquo; button in your app, the app will again say \u0026ldquo;No subscriptions.\u0026rdquo; Similarly if you wait 5 minutes and hit \u0026ldquo;Synchronize receipts\u0026rdquo; the app will say no subscriptions found, and the \u0026ldquo;ads\u0026rdquo; will be back.\nTroubleshooting Let’s not pretend that everything worked for you on the first try. There’s a lot that could go wrong here. If you make a purchase and nothing appears to happen, the first thing you should do is check the Network Monitor in the simulator (\u0026ldquo;Simulate\u0026rdquo; \u0026gt; \u0026ldquo;Network\u0026rdquo; \u0026gt; \u0026ldquo;Network Monitor\u0026rdquo;). You should see a list of network requests. Some will be GET requests and there will be at least one POST request. Check the response of these requests to see if they succeeded.\nAlso check the Glassfish server log to see if there is an exception.\nCommon problems would be that the URL you have set in the client app for endpointURL is incorrect, or that there is a database connection problem.\nLooking at the Source of the App Now that we’ve set up and built the app, let’s take a look at the source code so you can see how it all works.\nClient Side I use the Generic Webservice Client Library from inside my ReceiptStore implementation to load receipts from the web service, and insert new receipts to the database.\nThe source for my ReceiptStore is as follows:\nprivate ReceiptStore createReceiptStore() { return new ReceiptStore() { RESTfulWebServiceClient client = createRESTClient(receiptsEndpoint); @Override public void fetchReceipts(SuccessCallback\u0026lt;Receipt[]\u0026gt; callback) { RESTfulWebServiceClient.Query query = new RESTfulWebServiceClient.Query() { @Override protected void setupConnectionRequest(RESTfulWebServiceClient client, ConnectionRequest req) { super.setupConnectionRequest(client, req); req.setUrl(receiptsEndpoint); } }; client.find(query, rowset-\u0026gt;{ List\u0026lt;Receipt\u0026gt; out = new ArrayList\u0026lt;Receipt\u0026gt;(); for (Map m : rowset) { Result res = Result.fromContent(m); Receipt r = new Receipt(); r.setTransactionId(res.getAsString(\u0026quot;transactionId\u0026quot;)); r.setPurchaseDate(new Date(res.getAsLong(\u0026quot;purchaseDate\u0026quot;))); r.setQuantity(1); r.setStoreCode(m.getAsString(\u0026quot;storeCode\u0026quot;)); r.setSku(res.getAsString(\u0026quot;sku\u0026quot;)); if (m.containsKey(\u0026quot;cancellationDate\u0026quot;) \u0026amp;\u0026amp; m.get(\u0026quot;cancellationDate\u0026quot;) != null) { r.setCancellationDate(new Date(res.getAsLong(\u0026quot;cancellationDate\u0026quot;))); } if (m.containsKey(\u0026quot;expiryDate\u0026quot;) \u0026amp;\u0026amp; m.get(\u0026quot;expiryDate\u0026quot;) != null) { r.setExpiryDate(new Date(res.getAsLong(\u0026quot;expiryDate\u0026quot;))); } out.add(r); } callback.onSucess(out.toArray(new Receipt[out.size()])); }); } @Override public void submitReceipt(Receipt r, SuccessCallback\u0026lt;Boolean\u0026gt; callback) { Map m = new HashMap(); m.put(\u0026quot;transactionId\u0026quot;, r.getTransactionId()); m.put(\u0026quot;sku\u0026quot;, r.getSku()); m.put(\u0026quot;purchaseDate\u0026quot;, r.getPurchaseDate().getTime()); m.put(\u0026quot;orderData\u0026quot;, r.getOrderData()); m.put(\u0026quot;storeCode\u0026quot;, r.getStoreCode()); client.create(m, callback); } }; } Notice that we are not doing any calculation of expiry dates in our client app, as we did in the previous post (on non-renewable receipts). Since we are using a server now, it makes sense to move all of that logic over to the server.\nThe createRESTClient() method shown there simply creates a RESTfulWebServiceClient and configuring it to use basic authentication with a username and password. The idea is that your user would have logged into your app at some point, and you would have a username and password on hand to pass back to the web service with the receipt data so that you can connect the subscription to a user account. The source of that method is listed here:\n/** * Creates a REST client to connect to a particular endpoint. The REST client * generated here will automatically add the Authorization header * which tells the service what platform we are on. * @param url The url of the endpoint. * @return */ private RESTfulWebServiceClient createRESTClient(String url) { return new RESTfulWebServiceClient(url) { @Override protected void setupConnectionRequest(ConnectionRequest req) { try { req.addRequestHeader(\u0026quot;Authorization\u0026quot;, \u0026quot;Basic \u0026quot; + Base64.encode((getUsername()+\u0026quot;:\u0026quot;+getPassword()).getBytes(\u0026quot;UTF-8\u0026quot;))); } catch (Exception ex) {} } }; } Server-Side On the server-side, our REST controller is a standard JAX-RS REST interface. I used Netbeans web service wizard to generate it and then modified it to suit my purposes. The methods of the ReceiptsFacadeREST class pertaining to the REST API are shown here:\n@Stateless @Path(\u0026quot;com.codename1.demos.iapserver.receipts\u0026quot;) public class ReceiptsFacadeREST extends AbstractFacade\u0026lt;Receipts\u0026gt; { // ... @POST @Consumes({\u0026quot;application/xml\u0026quot;, \u0026quot;application/json\u0026quot;}) public void create(Receipts entity) { String username = credentialsWithBasicAuthentication(request).getName(); entity.setUsername(username); // Save the receipt first in case something goes wrong in the validation stage super.create(entity); // Let's validate the receipt validateAndSaveReceipt(entity); // validates the receipt against appropriate web service // and updates database if expiry date has changed. } // ... @GET @Override @Produces({\u0026quot;application/xml\u0026quot;, \u0026quot;application/json\u0026quot;}) public List\u0026lt;Receipts\u0026gt; findAll() { String username = credentialsWithBasicAuthentication(request).getName(); return getEntityManager() .createNamedQuery(\u0026quot;Receipts.findByUsername\u0026quot;) .setParameter(\u0026quot;username\u0026quot;, username) .getResultList(); } The magic happens inside that validateAndSaveReceipt() method, which I’ll cover in detail later on in this post.\nNotifications It is important to note that you will not be notified by apple or google when changes are made to subscriptions. It is up to you to periodically \u0026ldquo;poll\u0026rdquo; their web service to find if any changes have been made. Changes we would be interested in are primarily renewals and cancellations. In order to deal with this, set up a method to run periodically (once-per day might be enough). For testing, I actually set it up to run once per minute as shown below:\nprivate static final long ONE_DAY = 24 * 60 * 60 * 1000; private static final long ONE_DAY_SANDBOX = 10 * 1000; @Schedule(hour=\u0026quot;*\u0026quot;, minute=\u0026quot;*\u0026quot;) public void validateSubscriptionsCron() { System.out.println(\u0026quot;----------- DOING TIMED TASK ---------\u0026quot;); List\u0026lt;Receipts\u0026gt; res = null; final Set\u0026lt;String\u0026gt; completedTransactionIds = new HashSet\u0026lt;String\u0026gt;(); for (String storeCode : new String[]{Receipt.STORE_CODE_ITUNES, Receipt.STORE_CODE_PLAY}) { while (!(res = getEntityManager().createNamedQuery(\u0026quot;Receipts.findNextToValidate\u0026quot;) .setParameter(\u0026quot;threshold\u0026quot;, System.currentTimeMillis() - ONE_DAY_SANDBOX) .setParameter(\u0026quot;storeCode\u0026quot;, storeCode) .setMaxResults(1) .getResultList()).isEmpty() \u0026amp;\u0026amp; !completedTransactionIds.contains(res.get(0).getTransactionId())) { final Receipts curr = res.get(0); completedTransactionIds.add(curr.getTransactionId()); Receipts[] validatedReceipts = validateAndSaveReceipt(curr); em.flush(); for (Receipts r : validatedReceipts) { completedTransactionIds.add(r.getTransactionId()); } } } } That method simply finds all of the receipts in the database that haven’t been validated in some period of time, and validates it. Again, the magic happens inside the validateAndSaveReceipt() method which we cover later.\n__ In this example we only validate receipts from the iTunes and Play stores because those are the only ones that we currently support auto-renewing subscriptions on. The CN1-IAP-Validator Library For the purpose of this tutorial, I created a library to handle receipt validation in a way that hides as much of the complexity as possible. It supports both Google Play receipts and iTunes receipts.\nThe general usage is as follows:\nIAPValidator validator = IAPValidator.getValidatorForPlatform(receipt.getStoreCode()); if (validator == null) { // no validators were found for this store // Do custom validation } else { validator.setAppleSecret(APPLE_SECRET); validator.setGoogleClientId(GOOGLE_DEVELOPER_API_CLIENT_ID); validator.setGooglePrivateKey(GOOGLE_DEVELOPER_PRIVATE_KEY); Receipt[] result = validator.validate(receipt); ... } As you can see from this snippet, the complexity of receipt validation has been reduced to entering three configuration strings:\nAPPLE_SECRET – This is a \u0026ldquo;secret\u0026rdquo; string that you will get from iTunes connect when you set up your in-app products.\nGOOGLE_DEVELOPER_API_CLIENT_ID – A client ID that you’ll get from the google developer API console when you set up your API service credentials.\nGOOGLE_DEVELOPER_PRIVATE_KEY – A PKCS8 encoded string with an RSA private key that you’ll receive at the same time as the GOOGLE_DEVELOPER_API_CLIENT_ID.\nI will go through the steps to obtain these values later on in this post.\nThe validateAndSaveReceipt() Method You are now ready to see the full magic of the validateAndSaveReceipt() method in all its glory:\n/** * Validates a given receipt, updating the expiry date, * @param receipt The receipt to be validated * @param forInsert If true, then an expiry date will be calculated even if there is no validator. */ private Receipts[] validateAndSaveReceipt(Receipts receipt) { EntityManager em = getEntityManager(); Receipts managedReceipt = getManagedReceipt(receipt); // managedReceipt == receipt if receipt is in database or null otherwise if (Receipt.STORE_CODE_SIMULATOR.equals(receipt.getStoreCode())) { __**(1)** if (receipt.getExpiryDate() == null \u0026amp;\u0026amp; managedReceipt == null) { //Not inserted yet and no expiry date set yet Date dt = calculateExpiryDate(receipt.getSku(), true); if (dt != null) { receipt.setExpiryDate(dt.getTime()); } } if (managedReceipt == null) { // Receipt is not in the database yet. Add it em.persist(receipt); return new Receipts[]{receipt}; } else { // The receipt is already in the database. Update it. em.merge(managedReceipt); return new Receipts[]{managedReceipt}; } } else { // It is not a simulator receipt IAPValidator validator = IAPValidator.getValidatorForPlatform(receipt.getStoreCode()); if (validator == null) { // Receipt must have come from a platform other than iTunes or Play // Because there is no validator if (receipt.getExpiryDate() == null \u0026amp;\u0026amp; managedReceipt == null) { // No expiry date. // Generate one. Date dt = calculateExpiryDate(receipt.getSku(), false); if (dt != null) { receipt.setExpiryDate(dt.getTime()); } } if (managedReceipt == null) { em.persist(receipt); return new Receipts[]{receipt}; } else { em.merge(managedReceipt); return new Receipts[]{managedReceipt}; } } // Set credentials for the validator validator.setAppleSecret(APPLE_SECRET); validator.setGoogleClientId(GOOGLE_DEVELOPER_API_CLIENT_ID); validator.setGooglePrivateKey(GOOGLE_DEVELOPER_PRIVATE_KEY); // Create a dummy receipt with only transaction ID and order data to pass // to the validator. Really all it needs is order data to be able to validate Receipt r2 = Receipt(); r2.setTransactionId(receipt.getTransactionId()); r2.setOrderData(receipt.getOrderData()); try { Receipt[] result = validator.validate(r2); // Depending on the platform, result may contain many receipts or a single receipt // matching our receipt. In the case of iTunes, none of the receipt transaction IDs // might match the original receipt's transactionId because the validator // will set the transaction ID to the *original* receipt's transaction ID. // If none match, then we should remove our receipt, and update each of the returned // receipts in the database. Receipt matchingValidatedReceipt = null; for (Receipt r3 : result) { if (r3.getTransactionId().equals(receipt.getTransactionId())) { matchingValidatedReceipt = r3; break; } } if (matchingValidatedReceipt == null) { // Since the validator didn't find our receipt, // we should remove the receipt. The equivalent // is stored under the original receipt's transaction ID if (managedReceipt != null) { em.remove(managedReceipt); managedReceipt = null; } } List\u0026lt;Receipts\u0026gt; out = new ArrayList\u0026lt;Receipts\u0026gt;(); // Now go through and for (Receipt r3 : result) { if (r3.getOrderData() == null) { // No order data found in receipt. Setting it to the original order data r3.setOrderData(receipt.getOrderData()); } Receipts eReceipt = new Receipts(); eReceipt.setTransactionId(r3.getTransactionId()); eReceipt.setStoreCode(receipt.getStoreCode()); Receipts eManagedReceipt = getManagedReceipt(eReceipt); if (eManagedReceipt == null) { copy(eReceipt, r3); eReceipt.setUsername(receipt.getUsername()); eReceipt.setLastValidated(System.currentTimeMillis()); em.persist(eReceipt); out.add(eReceipt); } else { copy(eManagedReceipt, r3); eManagedReceipt.setUsername(receipt.getUsername()); eManagedReceipt.setLastValidated(System.currentTimeMillis()); em.merge(eManagedReceipt); out.add(eManagedReceipt); } } return out.toArray(new Receipts[out.size()]); } catch (Exception ex) { // We should probably store some info about the failure in the // database to make it easier to find receipts that aren't validating, // but for now we'll just log it. Log.p(\u0026quot;Failed to validate receipt \u0026quot;+r2); Log.p(\u0026quot;Reason: \u0026quot;+ex.getMessage()); Log.e(ex); return new Receipts[]{receipt}; } } } __1 | We need to handle the case where the app is being used in the CN1 simulator. We’ll treat this\nas a non-renewable receipt, and we’ll calculate the expiry date using an \u0026ldquo;accelerated\u0026rdquo; clock to assist in testing. __ In many of the code snippets for the Server-side code, you’ll see references to both a Receipts class and a Receipt class. I know this is slightly confusing. The Receipts class is a JPA entity the encapsulates a row from the \u0026ldquo;receipts\u0026rdquo; table of our SQL database. The Receipt class is com.codename1.payment.Receipt. It is used to interface with the IAP validation library. Google Play Setup Creating the App in Google Play In order to test out in-app purchase on an Android device, you’ll need to create an app the Google Play Developer Console. I won’t describe the process in this post, but there is plenty of information around the internet on how to do this. Some useful references for this include:\nGetting Started With Publishing – If you don’t already have an account with Google to publish your apps.\nLaunch Checklist\nGraphics, Icons, etc.. You are required to upload some screenshots and feature graphics. Don’t waste time making these perfect. For the screenshots, you can just use the \u0026ldquo;Screenshot\u0026rdquo; option in the simulator. (Use the Nexus 5 skin). For the feature graphics, I used this site that will generate the graphics in the correct dimensions for Google Play. You can also just leave the icon as the default Codename One icon.\nCreating Test Accounts __ You cannot purchase in-app products from your app using your publisher account. You need to set up at least one test account for the purpose of testing the app. In order to test your app, you need to set up a test account. A test account must be associated with a real gmail email address. If you have a domain that is managed by Google apps, then you can also use an address from that domain.\nThe full process for testing in-app billing can be found in this google document. However, I personally found this documentation difficult to follow.\nFor your purposes, you’ll need to set up a tester list in Google Play. Choose \u0026ldquo;Settings\u0026rdquo; \u0026gt; \u0026ldquo;Tester Lists\u0026rdquo;. Then create a list with all of the email address that you want to have treated as test accounts. Any purchases made by these email addresses will be treated as \u0026ldquo;Sandbox\u0026rdquo; purchases, and won’t require real money to change hands.\nAlpha Channel Distribution In order to test in-app purchase on Android, you must first publish your app. You can’t just build and install your app manually. The app needs to be published on the Play store, and it must be installed through the play store for in-app purchase to work. Luckily you can publish to an Alpha channel so that your app won’t be publicly available.\nFor more information about setting up alpha testing on Google play see this Google support document on the subject.\nOnce you have set your app up for alpha testing, you can send an invite link to your test accounts. You can find the link in the Google Play console under the APK section, under the \u0026ldquo;Alpha\u0026rdquo; tab (and assuming you’ve enabled alpha testing.\nThe format of the link is [https://play.google.com/apps/testing/\u0026lt;your-app-id\u0026gt;](https://play.google.com/apps/testing/\u0026lt;your-app-id\u0026amp;gt); in case you can’t find it. You can email this to your alpha testers. Make sure that you have added all testers to your tester lists so that their purchases will be made in the sandbox environment.\n__ Make sure that you install the app on your device using the test account that you set up and NOT your Google publisher account. Test purchases are always carried out by the account that installed the app. To install the app under a specific user, open the play store app on your device, then log out from your normal account, and log in using the test account. Then follow the install link for your app. If you accidentally install the app using the wrong user, it is a bit of a painful process to reset the clock. You can’t just simply uninstall and reinstall. I spent several hours caught in this purgatory, and the solution is worth of a blog post in itself. Also, before proceeding with testing in-app purchases, you need to add the in-app products in Google Play.\nAdding In-App Products After you have published your APK to the alpha channel, you can create the products. For the purposes of this tutorial, we’ll just add two products:\niapdemo.noads.month.auto – The 1 month subscription.\niapdemo.noads.3month.auto – The 3 month subscription.\n__ Since we will be adding products as \u0026ldquo;Subscriptions\u0026rdquo; in the pay store, your app must use the Purchase.subscribe(sku) method for initiating a purchase on these products, and not the Purchase.purchase(sku) method. If you accidentally use purchase() to purchase a subscription on Android, the payment will go through, but your purchase callback will receive an error. Adding 1 month Subscription\nOpen Google Play Developer Console, and navigate to your app.\nClick on \u0026ldquo;In-app Products\u0026rdquo; in the menu. Then click the \u0026ldquo;Add New Product\u0026rdquo; button.\nSelect \u0026ldquo;Subscription\u0026rdquo;, and enter \u0026ldquo;iapdemo.noads.month.auto\u0026rdquo; for the Product ID. Then click \u0026ldquo;Continue\u0026rdquo;\nNow fill in the form. You can choose your own price and name for the product. The following is a screenshot of the options I chose.\nAdding 3 month Subscription\nFollow the same process as for the 1 month subscription except use \u0026ldquo;iapdemo.noads.3month.auto\u0026rdquo; for the product ID, and select \u0026ldquo;3 months\u0026rdquo; for the billing period instead of \u0026ldquo;Monthly\u0026rdquo;.\nTesting The App At this point we should be ready to test our app. Assuming you’ve installed the app using the invite link you sent yourself from Google play, as a test account that is listed on your testers list , you should be good to go.\nOpen the app, click on \u0026ldquo;Subscriptions\u0026rdquo;, and try to purchase a 1-month subscription. If all goes well, it should insert the subscription into your database. But with no expiry date, since we haven’t yet implemented receipt validation yet. We’ll do that next.\nCreating Google Play Receipt Validation Credentials Google play receipt validation is accomplished via the android-publisher Purchases: get API. The CN1-IAP-Validation library shields you from most of the complexities of using this API, but you still need to obtain a \u0026ldquo;private key\u0026rdquo; and a \u0026ldquo;client id\u0026rdquo; to access this API. Both of these are provided when you set up an OAuth2 Service Account for your app.\n__ The following steps assume that you have already created your app in Google play and have published it to at least the alpha channel. See my previous post on this topic here (Link to be provided). Steps:\nOpen the Google API Developer Console, and select your App from the the menu.\nClick on the \u0026ldquo;Library\u0026rdquo; menu item in the left menu, and then click the \u0026ldquo;Google Play Developer API\u0026rdquo; link.\nClick on the button that says \u0026ldquo;Enable\u0026rdquo;. (If you already have it enabled, then just proceed to the next step). Click on the \u0026ldquo;Credentials\u0026rdquo; menu item in the left menu.\nIn the \u0026ldquo;Credentials\u0026rdquo; drop-down menu, select the \u0026ldquo;Service Account Key\u0026rdquo; option.\nYou will be presented with a new form. In the \u0026ldquo;Service Account\u0026rdquo; drop-down, select \u0026ldquo;New Service Account\u0026rdquo;. This will give you some additional options. Enter anything you like for the \u0026ldquo;Service account name\u0026rdquo;. For the role, we’ll select \u0026ldquo;Project\u0026rdquo; \u0026gt; \u0026ldquo;Owner\u0026rdquo; for now just so we don’t run into permissions issues. You’ll probably want to investigate further to fine a more limited role that only allows receipt verification, but for now, I don’t want any unnecessary road blocks for getting this to work. We’re probably going to run into \u0026ldquo;permission denied\u0026rdquo; errors at first anyways, so the fewer reasons for this, the better.\nIt will auto-generate an account ID for you.\nFinally, for the \u0026ldquo;Key type\u0026rdquo;, select \u0026ldquo;JSON\u0026rdquo;. Then click the \u0026ldquo;Create\u0026rdquo; button.\nThis should prompt the download of a JSON file that will have contents similar to the following:\n{ \u0026quot;type\u0026quot;: \u0026quot;service_account\u0026quot;, \u0026quot;project_id\u0026quot;: \u0026quot;iapdemo-152500\u0026quot;, \u0026quot;private_key_id\u0026quot;: \u0026quot;1b1d39f2bc083026b164b10a444ff7d839826b8a\u0026quot;, \u0026quot;private_key\u0026quot;: \u0026quot;-----BEGIN PRIVATE KEY----- ... some private key string -----END PRIVATE KEY-----n\u0026quot;, \u0026quot;client_email\u0026quot;: \u0026quot;[[email protected]](/cdn-cgi/l/email-protection)\u0026quot;, \u0026quot;client_id\u0026quot;: \u0026quot;117601572633333082772\u0026quot;, \u0026quot;auth_uri\u0026quot;: \u0026quot;https://accounts.google.com/o/oauth2/auth\u0026quot;, \u0026quot;token_uri\u0026quot;: \u0026quot;https://accounts.google.com/o/oauth2/token\u0026quot;, \u0026quot;auth_provider_x509_cert_url\u0026quot;: \u0026quot;https://www.googleapis.com/oauth2/v1/certs\u0026quot;, \u0026quot;client_x509_cert_url\u0026quot;: \u0026quot;https://www.googleapis.com/robot/v1/metadata/x509/iapdemo%40iapdemo-152500.iam.gserviceaccount.com\u0026quot; } This is where we get the information we’re looking for. The \u0026ldquo;client_email\u0026rdquo; is what we’ll use for your googleClientId, and the \u0026ldquo;private_key\u0026rdquo; is what we’ll use for the googlePrivateKey.\n__ Use the \u0026ldquo;client_email\u0026rdquo; value as our client ID, not the \u0026ldquo;client_id\u0026rdquo; value as you might be tempted to do. We’ll set these in our constants:\npublic static final String GOOGLE_DEVELOPER_API_CLIENT_ID=\u0026quot;[[email protected]](/cdn-cgi/l/email-protection)\u0026quot;; public static final String GOOGLE_DEVELOPER_PRIVATE_KEY=\u0026quot;-----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY-----n\u0026quot;; ... validator.setGoogleClientId(GOOGLE_DEVELOPER_API_CLIENT_ID); validator.setGooglePrivateKey(GOOGLE_DEVELOPER_PRIVATE_KEY); NOT DONE YET\nBefore we can use these credentials to verify receipts for our app, we need to link our app to this new service account from within Google Play.\nSteps:\nOpen the Google Play Developer Console, then click on \u0026ldquo;Settings\u0026rdquo; \u0026gt; \u0026ldquo;API Access\u0026rdquo;.\nYou should see your app listed on this page. Click the \u0026ldquo;Link\u0026rdquo; button next to your app.\nThis should reveal some more options on the page. You should see a \u0026ldquo;Service Accounts\u0026rdquo; section with a list of all of the service accounts that you have created. Find the one we just created, and click the \u0026ldquo;Grant Access\u0026rdquo; button in its row. This will open a dialog titled \u0026ldquo;Add New User\u0026rdquo;. Leave everything default, except change the \u0026ldquo;Role\u0026rdquo; to \u0026ldquo;Administrator\u0026rdquo;. This provides \u0026ldquo;ALL\u0026rdquo; permissions to this account, which probably isn’t a good idea for production. Later on, after everything is working, you can circle back and try to refine permissions. For the purpose of this tutorial, I just want to pull out all of the potential road blocks. Press the \u0026ldquo;Add User\u0026rdquo; button. At this point, the service account should be active so we can try to validate receipts.\nTesting Receipt Validation The ReceiptsFacadeREST class includes a flag to enable/disable play store validation. By default it is disabled. Let’s enable it:\npublic static final boolean DISABLE_PLAY_STORE_VALIDATION=true; Change this to false.\nThen build and run the server app. The validateSubscriptionsCron() method is set to run once per minute, so we just need to wait for the timer to come up and it should try to validate all of the play store receipts.\n__ I’m assuming you’ve already added a receipt in the previous test that we did. If necessary, you should purchase the subscription again in your app. After a minute or so, you should see \u0026ldquo;———– VALIDATING RECEIPTS ———\u0026rdquo; written in the Glassfish log, and it will validate your receipts. If it works, your receipt’s expiry date will get populated in the database, and you can press \u0026ldquo;Synchronize Receipts\u0026rdquo; in your app to see this reflected. If it fails, there will like be a big ugly stack trace and exception readout with some clues about what went wrong.\nRealistically, your first attempt will fail for some reason. Use the error codes and stack traces to help lead you to the problem. And feel free to post questions here.\niTunes Connect Setup The process for setting up and testing your app on iOS is much simpler than on Android (IMHO). It took me a couple hours to get the iTunes version working, vs a couple days on the Google Play side of things. One notable difference that makes things simpler is that you don’t need to actually upload your app to the store to test in-app purchase. You can just use your debug build on your device. It is also much easier to roll a bunch of test accounts than on Google Play. You don’t need to set up an alpha program, you just create a few \u0026ldquo;test accounts\u0026rdquo; (and this is easy to do) in your iTunes connect account, and then make sure to use one of these accounts when making a purchase. You can easily switch accounts on your device from the \u0026ldquo;Settings\u0026rdquo; app, where you can just log out of the iTunes store – which will cause you to be prompted in your app the next time you make a purchase.\nSetting up In-App Products The process to add products in iTunes connect is outlined in this apple developer document. We’ll add our two SKUs:\niapdemo.noads.month.auto – The 1 month subscription.\niapdemo.noads.3month.auto – The 3 month subscription.\nJust make sure you add them as auto-renewable subscriptions, and that you specify the appropriate renewal periods. Use the SKU as the product ID. Both of these products will be added to the same subscription group. Call the group whatever you like.\nCreating Test Accounts In order to test purchases, you need to create some test accounts. See this apple document for details on how to create these test accounts. Don’t worry, the process is much simpler than for Android. It should take you under 5 minutes.\nOnce you have the test accounts created, you should be set to test the app.\nMake sure your server is running.\nLog out from the app store. The process is described here.\nOpen your app.\nTry to purchase a 1-month subscription\nIf all went well, you should see the receipt listed in the RECEIPTS table of your database. But the expiry date will be null. We need to set up receipt verification in order for this to work.\nSetting up Receipt Verification In order for receipt verification to work we simply need to generate a shared secret in iTunes connect. The process is described here.\nOnce you have a shared secret, update the ReceiptsFacadeREST class with the value:\npublic static final String APPLE_SECRET = \u0026quot;your-shared-secret-here\u0026quot;; And enable iTunes store validation:\npublic static final boolean DISABLE_ITUNES_STORE_VALIDATION=true; Change this to false.\nIf you rebuild and run the server project, and wait for the validateSubscriptionsCron() method to run, it should validate the receipt. After about a minute (or less), you’ll see the text \u0026ldquo;———– VALIDATING RECEIPTS ———\u0026rdquo; written to the Glassfish log file, followed by some output from connecting to the iTunes validation service. If all went well, you should see your receipt expiration date updated in the database. If not, you’ll likely see some exception stack traces in the Glassfish log.\n__ Sandbox receipts in the iTunes store are set to run on an accelerated schedule. A 1 month subscription is actually 5 minutes, 3 months is 15 minutes etc…​ Also sandbox subscriptions don’t seem to persist in perpetuity until the user has cancelled it. I have found that they usually renew only 4 or 5 times before they are allowed to lapse by Apple. Summary Setting up in-app purchase is not for the faint of heart. Having to jump through a battery of hoops on Android is poison for the soul. On the other hand, it may all just be worth it. Once you have a working system up and running, it can mostly continue to run on its own. Despite the length of this post, I’m really only just scratching the surface on this topic. There are many other aspects that I simply ignored due to time constraints. I encourage you to take the code in this post and try to make it work for yourself. You’re in for some pain, but I guarantee that the reward at the end of it all is worth it. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — January 3, 2017 at 9:19 pm (permalink) Thanks Steve – great tutorial.\nsalah Alhaddabi — August 13, 2017 at 9:46 pm (permalink) Dear Steve,\nwhen I try to run the demo client, I get the following erros: (I have changed the package name to be com.salah.trails.iapdemo.IAPDemo)\njava.lang.ClassNotFoundException: com.salah.trails.iapdemo.IAPDemo\nat java.net.URLClassLoader.findClass(URLClassLoader.java:381)\nat java.lang.ClassLoader.loadClass(ClassLoader.java:424)\nat sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)\nat java.lang.ClassLoader.loadClass(ClassLoader.java:357)\nat java.lang.ClassLoader.findSystemClass(ClassLoader.java:1001)\nat com.codename1.impl.javase.ClassPathLoader.findClass(ClassPathLoader.java:100)\nat com.codename1.impl.javase.ClassPathLoader.loadClass(ClassPathLoader.java:50)\nat java.lang.Class.forName0(Native Method)\nat java.lang.Class.forName(Class.java:264)\nat com.codename1.impl.javase.Executor$[1.run](http://1.run)([Executor.java](http://Executor.java):86)\nat java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)\nat java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)\nat java.awt.EventQueue.access$500(EventQueue.java:97)\nat java.awt.EventQueue$[3.run](http://3.run)([EventQueue.java](http://EventQueue.java):709)\nat java.awt.EventQueue$[3.run](http://3.run)([EventQueue.java](http://EventQueue.java):703)\nat java.security.AccessController.doPrivileged(Native Method)\nat java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)\nat java.awt.EventQueue.dispatchEvent(EventQueue.java:726)\nat java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)\nat java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)\nat java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)\nat java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)\nat java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)\nat [java.awt.EventDispatchThrea…](http://java.awt.EventDispatchThread.run)([EventDispatchThread.java](http://EventDispatchThread.java):82)\nShai Almog — August 14, 2017 at 7:04 am (permalink) You refactored the package name without updating it in the codenameone_settings.proper…\nBrenden — June 11, 2019 at 9:15 am (permalink) Dear Steve\nAbove it says that there is no need to upload your app to the apple store to test the app , is this still valid now in 2019 ? or has this changed ?\nRegards Brenden\nShai Almog — June 12, 2019 at 4:11 am (permalink) Hi,\nit should work fine locally but you need to still configure everything in itunes connect otherwise it won’t work.\nRochana Sawatzky — November 27, 2019 at 1:36 am (permalink) Hey Steve – no matter what I seem to do, when trying to ant-install deps I get the error:\nCannot run program \u0026ldquo;mvn\u0026rdquo; (in directory …\u0026quot;): CreateProcess error=2, The system cannot find the file specified\nI have installed maven, and added it to my path, as well as adding maven_home, m2_home, java_home environment variables. I can run mvn -version fine, so I’m at a loss for why I’m getting the error. Any ideas?\nShai Almog — November 27, 2019 at 2:59 am (permalink) If you added it to the path in Windows GUI it might not impact the currently open shell. If you’re using windows shell this might conflict with spaces you have in the path so make sure you use quotes e.g. set PATH=\u0026quot;PATH TO MAVEN\u0026quot;;%PATH%\nIf this doesn’t help try to provide more details about your environment so we can help.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/autorenewing-subscriptions-in-ios-and-android/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/autorenewing-subscriptions-in-ios-and-android/in-app-purchase.jpg\"\u003e\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eThis is the third post in a three-part series on In-App purchase. Please check out \u003ca href=\"/blog/intro-to-in-app-purchase/\"\u003ePart I: Introduction to In-App Purchase\u003c/a\u003e and \u003ca href=\"/blog/in-app-purchase-non-renewable-subscriptions/\"\u003ePart 2: Implementing Non-Renewable Subscriptions\u003c/a\u003e.\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eAuto-renewable subscriptions provide, arguably, an easier path to recurring revenue than non-renewable subscriptions because all of the subscription stuff is handled by the app store. You defer almost entirely to the app store (iTunes for iOS, and Play for Android) for billing and management.\u003c/p\u003e","title":"Auto-Renewing Subscriptions in iOS and Android"},{"content":"\nOpening a demo or sample code from GIT is relatively easy if you are an experienced Codename One developer but for a lot of newer developers for whom samples are often more crucial this can be challenging. One of our solutions was placing the demos in the Codename One new project menu but that’s probably not enough.\nFirst before we begin with the step by step guide let’s explain what is happening…​\nWhy Doesn’t a Project \u0026ldquo;Just Work\u0026rdquo;? There are two major reasons:\nWe don’t include the required JAR files/cn1lib dependencies and some of the required empty folders\nProjects are usually built for NetBeans so if you use a different IDE they won’t work\nBoth of these are easy to fix, but with this post I’d like to show you a trivial trick to do this that will work in NetBeans/Eclipse \u0026amp; IntelliJ/IDEA. The trick is to create a new project and copy the sources on top of it for everything to work…​\nI’ll explain this thru an example by opening and running AlphabetScroll in the 3 IDE’s using these steps.\nGet the Main Class \u0026amp; Package Name Open the codenameone_setting.properties for the project. Within this file find two values:\ncodename1.mainName which in this case is Alphabet\ncodename1.packageName which in this case is com.codename1.demos.alphabetscroll\nCreate a new Project in the IDE You can leave everything in the default settings, the only two exceptions are the package name and main class name that must match the main class \u0026amp; package you found in the codenameone_settings.properties.\nFigure 1. Create a new project for Alphabet in NetBeans\nFigure 2. Create a new project for Alphabet in Eclipse\nFigure 3. Create a new project for Alphabet in IntelliJ/IDEA\nCopy the Files Open the project folder outside of the IDE, replace the src directory with the one from GIT and replace the codenameone_settings.properties you have with the one from GIT.\nIf the git project has a native directory copy it on top of yours.\nIf the lib directory within the git project has any cn1lib files copy them into your lib directory \u0026amp; use Refresh Libs in the right click menu under the Codename One menu.\nRun You can now run a project from GIT regardless of the IDE you are using, notice that if your plugin is old you might need one additional step. Right click the project and select Codename One → Codname One Settings.\nUnder the Basics menu click the Update Project Libs button (bottom left). This will update the jars to the latest allowing the project to run. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nThomasH99 — September 19, 2021 at 2:44 pm (permalink) I just posted this comment under the post \u0026ldquo;TIP: Using Git for Codename One Projects\u0026rdquo; but I think I should have posted it here instead:\n———————\nHi, is this approach is still the right way to use Git for CN1 projects using maven? (I’m no expert on either so maybe this is a basic question 🙂)\nShai Almog — September 20, 2021 at 1:47 am (permalink) Hi,\nno. I think maven is actually a bit simpler. You can just gitignor the target directory.\nThomasH99 — September 19, 2021 at 2:44 pm (permalink) I just posted this comment under the post \u0026ldquo;TIP: Using Git for Codename One Projects\u0026rdquo; but I think I should have posted it here instead:\n———————\nHi, is this approach is still the right way to use Git for CN1 projects using maven? (I’m no expert on either so maybe this is a basic question 🙂)\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-setup-codename-one-demo-from-git/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-setup-codename-one-demo-from-git/just-the-tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOpening a demo or sample code from GIT is relatively easy if you are an experienced Codename One developer but for a lot of newer developers for whom samples are often more crucial this can be challenging. One of our solutions was placing the demos in the Codename One new project menu but that’s probably not enough.\u003c/p\u003e\n\u003cp\u003eFirst before we begin with the step by step guide let’s explain what is happening…​\u003c/p\u003e","title":"TIP: Setup a Codename One Project from Git"},{"content":"\nHappy holidays, Merry Christmas, happy new year to all. All of us here at Codename One hope you have\na lovely vacation if you are taking one. Since half of our readership is from countries that celebrate these\nholidays it seems like a good time to take a short blogging vacation as well.\nWe’re still working here and will make releases/offer support as usual but we’ll update you on the changes we\nhad in our 2017 posts. We’ll be back to blogging on January 2nd.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/blog-vacation/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/blog-vacation/happy-holidays.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eHappy holidays, Merry Christmas, happy new year to all. All of us here at Codename One hope you have\u003cbr\u003e\na lovely vacation if you are taking one. Since half of our readership is from countries that celebrate these\u003cbr\u003e\nholidays it seems like a good time to take a short blogging vacation as well.\u003c/p\u003e\n\u003cp\u003eWe’re still working here and will make releases/offer support as usual but we’ll update you on the changes we\u003cbr\u003e\nhad in our 2017 posts. We’ll be back to blogging on January 2nd.\u003c/p\u003e","title":"Blog Vacation"},{"content":"\nOne of the fallouts from the new encrypted storage API we added last week is the fact that it encrypts things\nlike preferences making them unusable if you expected them to work before/after encryption was applied.\nTo workaround this we added a new API to the Preferences class:\npublic static void setPreferencesLocation(String storageFileName) public static String getPreferencesLocation() These API’s allow us to determine the storage file in which the preferences are stored (not to be confused\nwith FileSystemStorage file). By default preferences are stored in CN1Preferences but you can use any file\nname you want. This is useful if your app allows several logins and you might want to use preferences\ndifferently for every login.\nLocation Popup A while back a user contributed a change the triggered the simulator location dialog popup automatically when\nworking with the location API. This seemed like a good idea at the time but proved to be one of the most\nannoying features if you have things like background location tracking.\nSo until we have a configuration to enable/disable it by default we decided to turn this off. You can still open the\nlocation popup from the simulator menu if you want it.\nArgument Order We recently ran into a weird misbehavior in the Amazon AWS API where they relied on the order of the post\nvalues and would fail if they weren’t delivered in a specific order within the body of the request.\nUnfortunately, we used a Map to store the elements and the elements in Java maps are ordered based on their\nhashCode() method value which doesn’t comply to the key/value order. With the next update we’ll replace the\ninternal Map with LinkedHashMap which preserves the addition order and that way addArgument will determine\nthe order in which the element appears in the URL/body of a request.\nThis actually has some merit. With an upload Amazon can evaluate values of small fields before the full file\nis uploaded to S3. That way it can reject something quickly before the server/network or device do the actual\nupload. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJérémy MARQUER — December 21, 2016 at 1:00 pm (permalink) Jérémy MARQUER says:\nHappy to read that we can now manage (without any implementation) multi account preference ! Thanks.\nM Usman Nu — February 1, 2017 at 7:27 pm (permalink) M Usman Nu says:\nIf I close the application then preferences are cleared. Is there any way to make it permanent ?\nShai Almog — February 2, 2017 at 6:19 am (permalink) Shai Almog says:\nUse the store() method just like standard Java\nPeng — April 13, 2017 at 9:46 am (permalink) Peng says:\nHi, I’m struggling with writing unencrypted Preferences after EncryptedStorage is installed. My use case is that I need to read certain Preferences before the user logs in. During login the EncryptedStorage is installed. After that some Preferences need to be written which are needed for the next launch of the app (before the login).\nIs there a way to accomplish this? According to what I’ve read in this article, changing the preferences location should have the desired effect, but I cannot figure out how. Putting the following snippet into the init method of a generated project always (even after restarting the app) results in NULL being returned by Preferences.get():\n// before login\nPreferences.setPreferencesLocation(\u0026ldquo;SomeOtherLocation\u0026rdquo;);\nPreferences.get(\u0026ldquo;Key\u0026rdquo;, null); // This always returns null\n// login\nEncryptedStorage.install(\u0026ldquo;Secret\u0026rdquo;);\n// after login\nPreferences.set(\u0026ldquo;Key\u0026rdquo;, \u0026ldquo;Value\u0026rdquo;);\nThe invocation of the Preferences.get() method during the first launch just returns NULL, during the second launch also an EOFException is logged to the console before the NULL value is returned.\nShai Almog — April 14, 2017 at 4:36 am (permalink) Shai Almog says:\nOnce encryption is in place a file read/written without/with encryption won’t work. What you are doing here is:\nsetting location for preferences\nGetting/setting a key (creating unencrypted file)\nEncrypting\nGetting key from unencrypted file which seems corrupt to the system now.\nThe idea is to keep two preferences files, one encrypted and one unencrypted and call set preferences location AFTER encrypting so one doesn’t break the other.\nYou obviously can’t share a key between those two so if you need a key to exist in both you will need to transfer it thru a variable in memory as once encryption is on everything is \u0026ldquo;gone\u0026rdquo;.\nPeng — April 19, 2017 at 8:11 am (permalink) Peng says:\nThank you for your answer. Unfortunately, transfer throught a variable in memory is not an option for me. I need to store a piece of information AFTER encrypting that would be available during the next launch of the app BEFORE the EncryptedStorage.install call.\nTo make my question more comprehensive, here’s my situation: I need to store the password hash of the user somehow unencrypted to check during login. The same password is used during login to decrypt the storage. Now, while still logged in, the user may change his password. The hash of this new password then needs to be stored for the next login.\nIf I got your answer right, there is no built-in way to accomplish this, using only the Storage/EncryptedStorage and Preferences APIs. As there is no \u0026ldquo;EncryptedStorage.uninstall\u0026rdquo; method, one cannot write plaintext data to storage after EncryptedStorage.install was called.\nBased on your experience, what solution would you recommend, especially in terms of portability? Would using e.g. Properties and FileSystemStorage directly be a good idea or are there better alternatives?\nShai Almog — April 20, 2017 at 4:45 am (permalink) Shai Almog says:\nYou can store things in FileSystemStorage under the home directory of the user and they won’t be encrypted. Only Storage is encrypted.\nRe-encrypting is a bit tedious as this wasn’t designed for that and might be error prone. I would suggest this:\nUse a random generated value to encrypt the data\nThen encrypt the random key using your password and save that in FileSystemStorage. That way you just need to update one file with every change of the password…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/preferences-location-popup-order/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/preferences-location-popup-order/new-features-5.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the fallouts from the new encrypted storage API we added last week is the fact that it encrypts things\u003cbr\u003e\nlike preferences making them unusable if you expected them to work before/after encryption was applied.\u003cbr\u003e\nTo workaround this we added a new API to the \u003ccode\u003ePreferences\u003c/code\u003e class:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003epublic static void setPreferencesLocation(String storageFileName)\npublic static String getPreferencesLocation()\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThese API’s allow us to determine the storage file in which the preferences are stored (not to be confused\u003cbr\u003e\nwith \u003ccode\u003eFileSystemStorage\u003c/code\u003e file). By default preferences are stored in \u003ccode\u003eCN1Preferences\u003c/code\u003e but you can use any file\u003cbr\u003e\nname you want. This is useful if your app allows several logins and you might want to use preferences\u003cbr\u003e\ndifferently for every login.\u003c/p\u003e","title":"Preferences, Location, Popup \u0026 Order"},{"content":"\n__ This is the second post in a three-part series on In-App purchase. Please check out Part I: Introduction to In-App Purchase and Part 3: Auto-renewing Subscriptions in iOS and Android. In my last post we looked at one-off in-app purchases. In this post we’ll look at subscriptions. As we discussed before, there are two types of subscriptions:\nNon-renewable\nAuto-renewable\nNon-renewable subscriptions are really the same as consumable products, except that they are shareable across all of a user’s devices. Auto-renewable subscriptions, on the other hand, will continue as long as the user doesn’t cancel it. They will be re-billed automatically by the appropriate app-store when the chosen period expires, and all management of the subscription is handled by the the app-store itself.\n__ The concept of an \u0026ldquo;Non-renewable\u0026rdquo; subscription is an invention of the iTunes store. There is no formal equivalent in Google play. In order to create a non-renewable subscription SKU that behaves the same in your iOS and Android apps you would create it as a regular product in Google play, and a Non-renewable subscription in the iTunes store. We’ll learn more about that in a later post when we go into the specifics of app store setup. The Server-Side Since a subscription purchased on one user device needs to be available across all of the user’s devices (Apple’s rules for non-renewable subscriptions), our app will need to have a server-component. In this post, we’ll gloss over that requirement and just \u0026ldquo;mock\u0026rdquo; the server interface. We’ll go into the specifics of the server-side in a later post.\nThe Receipts API Subscriptions, in Codename One are handled using a new \u0026ldquo;Receipts\u0026rdquo; API. It is up to you to register a receipt store with the In-App purchase instance, which allows Codename one to load receipts (presumably from your server), and submit new receipts (presumably to your server). A Receipt includes information such as:\nStore code (since you may be dealing with receipts from multiple stores)\nSKU\nTransaction ID (store specific)\nExpiry Date\nCancellation date\nPurchase date\nOrder Data (can be used on the server-side to verify the receipt and load additional receipt details directly from the store it originated from).\nThe Purchase provides a set of methods for interacting with the receipt store, such as:\nisSubscribed([skus]) – Checks to see if the user is currently subscribed to any of the provided skus.\ngetExpiryDate([skus]) – Checks the expiry date for a set of skus.\nsynchronizeReceipts() – Synchronizes the receipts with the receipt store. This will attempt to submit any pending purchase receipts to the receipt store, and the reload receipts from the receipt store.\nIn order for any of this to work, you must implement the ReceiptStore interface, and register it with the Purchase instance. Your receipt store must implement two methods:\nfetchReceipts(SuccessCallback\u0026lt;Receipt[]\u0026gt; callback) – Loads all of the receipts from your receipt store for the current user.\nsubmitReceipt(Receipt receipt, SuccessCallback\u0026lt;Boolean\u0026gt; callback) – Submits a receipt to your receipt store. This gives you an opportunity to add additional details to the receipt such as an expiry date.\nThe \u0026ldquo;Hello World\u0026rdquo; of Non-Renewable Subscriptions We’ll expand on the theme of \u0026ldquo;Buying\u0026rdquo; the world for this app, except, this time we will just \u0026ldquo;Rent\u0026rdquo; the world for a period of time. We’ll have two products:\nA 1 month subscription\nA 1 year subscription\npublic static final String SKU_WORLD_1_MONTH = \u0026ldquo;com.codename1.world.subscribe.1month\u0026rdquo;; public static final String SKU_WORLD_1_YEAR = \u0026ldquo;com.codename1.world.subscribe.1year\u0026rdquo;;\npublic static final String[] PRODUCTS = { SKU_WORLD_1_MONTH, SKU_WORLD_1_YEAR };\nNotice that we create two separate SKUs for the 1 month and 1 year subscription. Each subscription period must have its own SKU. I have created an array (PRODUCTS) that contains both of the SKUs. This is handy, as you’ll see in the examples ahead, because all of the APIs for checking status and expiry date of a subscription take all of the SKUs in a \u0026ldquo;subscription group\u0026rdquo; as input. This is\n__ Multiple SKUs that sell the same service/product but for different periods form a \u0026ldquo;subscription group\u0026rdquo;. Conceptually, customers are not subscribing to a particular SKU, they are subscribing to the subscription group of which that SKU is a member. As an example, if a user purchases a 1 month subscription to \u0026ldquo;the world\u0026rdquo;, they are actually just subscribing to \u0026ldquo;the world\u0026rdquo; subscription group. It is up to you to know how your SKUs are grouped together, and any methods in the Purchase class that check subscription status or expiry date of a SKU should be passed all SKUs of that subscription group. E.g. If you want to know if the user is subscribed to the SKU_WORLD_1_MONTH subscription, it would not be sufficient to call iap.isSubscribed(SKU_WORLD_1_MONTH), because that wouldn’t take into account if the user had purchased a 1 year subscription. The correct way is to always call iap.isSubscribed(SKU_WORLD_1_MONTH, SKU_WORLD_1_YEAR), or simply iap.isSubscribed(PRODUCTS) since I have placed both SKUs into my PRODUCTS array.\nImplementing the Receipt Store __ The receipt store is intended to interface with a server so that the subscriptions can be synced with multiple devices, as required by Apple’s guidelines. For this post we’ll just store our receipts on device using internal storage. Moving the logic to a server is a simple matter that we will cover in a future post when we cover the server-side. A basic receipt store needs to implement just two methods:\nfetchReceipts\nsubmitReceipt\nGenerally we’ll register it in our app’s init() method so that it is always available.\npublic void init(Object context) { ... Purchase.getInAppPurchase().setReceiptStore(new ReceiptStore() { @Override public void fetchReceipts(SuccessCallback\u0026lt;Receipt[]\u0026gt; callback) { // Fetch receipts from storage and pass them to the callback } @Override public void submitReceipt(Receipt receipt, SuccessCallback\u0026lt;Boolean\u0026gt; callback) { // Save a receipt to storage. Make sure to call callback when done. } }); } These methods are designed to be called asynchronously since real-world apps will always be connecting to some sort of network service. Therefore, instead of returning a value, both of these methods are passed instances of the SuccessCallback class. It is important to make sure to call callback.onSuccess() ALWAYS when the methods have completed, even if there is an error, or the Purchase class will just assume that you’re taking a long time to complete the task, and will continue to wait for you to finish.\nOnce implemented, our fetchReceipts() method will look like:\n// static declarations used by receipt store // Storage key where list of receipts are stored private static final String RECEIPTS_KEY = \u0026quot;RECEIPTS.dat\u0026quot;; @Override public void fetchReceipts(SuccessCallback\u0026lt;Receipt[]\u0026gt; callback) { Storage s = Storage.getInstance(); Receipt[] found; synchronized(RECEIPTS_KEY) { if (s.exists(RECEIPTS_KEY)) { List\u0026lt;Receipt\u0026gt; receipts = (List\u0026lt;Receipt\u0026gt;)s.readObject(RECEIPTS_KEY); found = receipts.toArray(new Receipt[receipts.size()]); } else { found = new Receipt[0]; } } // Make sure this is outside the synchronized block callback.onSucess(found); } This is fairly straight forward. We’re checking to see if we already have a list of receipts stored. If so we return that list to the callback. If not we return an empty array of receipts.\n__ Receipt implements Externalizable so you are able to write instances directly to Storage. The submitReceipt() method is a little more complex, as it needs to calculate the new expiry date for our subscription.\n@Override public void submitReceipt(Receipt receipt, SuccessCallback\u0026lt;Boolean\u0026gt; callback) { Storage s = Storage.getInstance(); synchronized(RECEIPTS_KEY) { List\u0026lt;Receipt\u0026gt; receipts; if (s.exists(RECEIPTS_KEY)) { receipts = (List\u0026lt;Receipt\u0026gt;)s.readObject(RECEIPTS_KEY); } else { receipts = new ArrayList\u0026lt;Receipt\u0026gt;(); } // Check to see if this receipt already exists // This probably won't ever happen (that we'll be asked to submit an // existing receipt, but better safe than sorry for (Receipt r : receipts) { if (r.getStoreCode().equals(receipt.getStoreCode()) \u0026amp;\u0026amp; r.getTransactionId().equals(receipt.getTransactionId())) { // If we've already got this receipt, we'll just this submission. return; } } // Now try to find the current expiry date Date currExpiry = new Date(); List\u0026lt;String\u0026gt; lProducts = Arrays.asList(PRODUCTS); for (Receipt r : receipts) { if (!lProducts.contains(receipt.getSku())) { continue; } if (r.getCancellationDate() != null) { continue; } if (r.getExpiryDate() == null) { continue; } if (r.getExpiryDate().getTime() \u0026gt; currExpiry.getTime()) { currExpiry = r.getExpiryDate(); } } // Now set the appropriate expiry date by adding time onto // the end of the current expiry date Calendar cal = Calendar.getInstance(); cal.setTime(currExpiry); switch (receipt.getSku()) { case SKU_WORLD_1_MONTH: cal.add(Calendar.MONTH, 1); break; case SKU_WORLD_1_YEAR: cal.add(Calendar.YEAR, 1); } Date newExpiry = cal.getTime(); receipt.setExpiryDate(newExpiry); receipts.add(receipt); s.writeObject(RECEIPTS_KEY, receipts); } // Make sure this is outside the synchronized block callback.onSucess(Boolean.TRUE); } The main logic of this method involves iterating through all of the existing receipts to find the latest current expiry date, so that when the user purchases a subscription, it is added onto the end of the current subscription (if one exists) rather than going from today’s date. This enables users to safely renew their subscription before the subscription has expired.\nIn the real-world, we would implement this logic on the server-side.\n__ The iTunes store and Play store have no knowledge of your subscription durations. This is why it is up to you to set the expiry date in the submitReceipt method. Non-renewable subscriptions are essentially no different than regular consumable products. It is up to you to manage the subscription logic – and Apple, in particular, requires you to do so using a server. Synchronizing Receipts In order for your app to provide you with current data about the user’s subscriptions and expiry dates, you need to synchronize the receipts with your receipt store. Purchase provides a set of methods for doing this. Generally I’ll call one of them inside the start() method, and I may resynchronize at other strategic times if I suspect that the information may have changed.\nThe following methods can be used for synchronization:\nsynchronizeReceipts() – Asynchronously synchronizes receipts in the background. You won’t be notified when it is complete.\nsynchronizeReceiptsSync() – Synchronously synchronizes receipts, and blocks until it is complete. This is safe to use on the EDT as it employs invokeAndBlock under the covers.\nsynchronizeReceipts(final long ifOlderThanMs, final SuccessCallback\u0026lt;Boolean\u0026gt; callback) – Asynchronously synchronizes receipts, but only if they haven’t been synchronized in the specified time period. E.g. In your start() method you might decide that you only want to synchronize receipts once per day. This also includes a callback that will be called when synchronization is complete.\nsynchronizeReceiptsSync(long ifOlderThanMs) – A synchronous version that will only refetch if data is older than given time.\nIn our hello world app we synchronize the subscriptions in a few places.\nAt the end of the start() method:\npublic void start() { ... // Now synchronize the receipts iap.synchronizeReceipts(0, res-\u0026gt;{ // Update the UI as necessary to reflect }); } And I also provide a button to allow the user to manually synchronize the receipts.\nButton syncReceipts = new Button(\u0026quot;Synchronize Receipts\u0026quot;); syncReceipts.addActionListener(e-\u0026gt;{ iap.synchronizeReceipts(0, res-\u0026gt;{ // Update the UI }); }); Expiry Dates and Subscription Status Now that we have a receipt store registered, and we have synchronized our receipts, we can query the Purchase instance to see if a SKU or set of SKUs is currently subscribed. There are three useful methods in this realm:\nboolean isSubscribed(String…​ skus) – Checks to see if the user is currently subscribed to any of the provided SKUs.\nDate getExpiryDate(String…​ skus) – Gets the latest expiry date of a set of SKUs.\nReceipt getFirstReceiptExpiringAfter(Date dt, String…​ skus) – This method will return the earliest receipt with an expiry date after the given date. This is needed in cases where you need to decide if the user should have access to some content based on its publication date. E.g. If you published an issue of your e-zine on March 1, and the user purchased a subscription on March 15th, then they should get access to the March 1st issue even though it doesn’t necessarily fall in the subscription period. Being able to easily fetch the first receipt after a given date makes it easier to determine if a particular issue should be covered by a subscription.\nIf you need to know more information about subscriptions, you can always just call getReceipts() to obtain a list of all of the current receipts and determine for yourself what the user should have access to.\nIn the hello world app we’ll use this information in a few different places. On our main form we’ll include a label to show the current expiry date, and we allow the user to press a button to synchronize receipts manually if they think the value is out of date.\n// ... SpanLabel rentalStatus = new SpanLabel(\u0026quot;Loading rental details...\u0026quot;); Button syncReceipts = new Button(\u0026quot;Synchronize Receipts\u0026quot;); syncReceipts.addActionListener(e-\u0026gt;{ iap.synchronizeReceipts(0, res-\u0026gt;{ if (iap.isSubscribed(PRODUCTS)) { rentalStatus.setText(\u0026quot;World rental expires \u0026quot;+iap.getExpiryDate(PRODUCTS)); } else { rentalStatus.setText(\u0026quot;You don't currently have a subscription to the world\u0026quot;); } hi.revalidate(); }); }); Allowing the User to Purchase the Subscription You should now have all of the background required to implement the Hello World Subscription app. So we’ll return to the code and see how the user purchases a subscription.\nIn the main form, I want two buttons to subscribe to the \u0026ldquo;World\u0026rdquo;, for one month and one year respectively. They look like:\nPurchase iap = Purchase.getInAppPurchase(); // ... Button rentWorld1M = new Button(\u0026quot;Rent World 1 Month\u0026quot;); rentWorld1M.addActionListener(e-\u0026gt;{ String msg = null; if (iap.isSubscribed(PRODUCTS)) { __**(1)** msg = \u0026quot;You are already renting the world until \u0026quot; +iap.getExpiryDate(PRODUCTS) __**(2)** +\u0026quot;. Extend it for one more month?\u0026quot;; } else { msg = \u0026quot;Rent the world for 1 month?\u0026quot;; } if (Dialog.show(\u0026quot;Confirm\u0026quot;, msg, \u0026quot;Yes\u0026quot;, \u0026quot;No\u0026quot;)) { Purchase.getInAppPurchase().purchase(SKU_WORLD_1_MONTH); __**(3)** } }); Button rentWorld1Y = new Button(\u0026quot;Rent World 1 Year\u0026quot;); rentWorld1Y.addActionListener(e-\u0026gt;{ String msg = null; if (iap.isSubscribed(PRODUCTS)) { msg = \u0026quot;You are already renting the world until \u0026quot;+ iap.getExpiryDate(PRODUCTS)+ \u0026quot;. Extend it for one more year?\u0026quot;; } else { msg = \u0026quot;Rent the world for 1 year?\u0026quot;; } if (Dialog.show(\u0026quot;Confirm\u0026quot;, msg, \u0026quot;Yes\u0026quot;, \u0026quot;No\u0026quot;)) { Purchase.getInAppPurchase().purchase(SKU_WORLD_1_YEAR); } }); __1 In the event handler we check if the user is subscribed by calling isSubscribed(PRODUCTS). Notice that we check it against the array of both the one month and one year subscription SKUs. __2 We are able to tell the user when the current expiry date is so that they can gauge whether to proceed. __3 Since this is a non-renewable subscription, we use the Purchase.purchase() method. See following note about subscribe() vs purchase() subscribe() vs purchase() The Purchase class includes two methods for initiating a purchase:\npurchase(sku)\nsubscribe(sku)\nWhich one you use depends on the type of product that is being purchased. If your product is set up as a subscription in the Google Play store, then you should use subscribe(sku). Otherwise, you should use purchase(sku).\nHandling Purchase Callbacks The purchase callbacks are very similar to the ones that we implemented in the regular in-app purchase examples:\n@Override public void itemPurchased(String sku) { Purchase iap = Purchase.getInAppPurchase(); // Force us to reload the receipts from the store. iap.synchronizeReceiptsSync(0); ToastBar.showMessage(\u0026quot;Your subscription has been extended to \u0026quot;+iap.getExpiryDate(PRODUCTS), FontImage.MATERIAL_THUMB_UP); } @Override public void itemPurchaseError(String sku, String errorMessage) { ToastBar.showErrorMessage(\u0026quot;Failure occurred: \u0026quot;+errorMessage); } Notice that, in itemPurchased() we don’t need to explicitly create any receipts or submit anything to the receipt store. This is handled for you automatically. We do make a call to synchronizeReceiptsSync() but this is just to ensure that our toast message has the new expiry date loaded already.\nFull Source View the full source listing of this application\nScreenshots Summary This post demonstrated how to set up an app to use non-renewable subscriptions using in-app purchase. Non-renewable subscriptions are the same as regular consumable products except for the fact that they are shared by all of the user’s devices, and thus, require a server component. The app store has no knowledge of the duration of your non-renewable subscriptions. It is up to you to specify the expiry date of purchased subscriptions on their receipts when they are submitted. Google play doesn’t formally have a \u0026ldquo;non-renewable\u0026rdquo; subscription product type. To implement them in Google play, you would just set up a regular product. It is how you handle it internally that makes it a subscription, and not just a regular product.\nCodename One uses the Receipt class as the foundation for its subscriptions infrastructure. You, as the developer, are responsible for implementing the ReceiptStore interface to provide the receipts. The Purchase instance will load receipts from your ReceiptStore, and use them to determine whether the user is currently subscribed to a subscription, and when the subscription expires.\nUp Next: Auto-Renewable Subscriptions The next post in this series covers Auto-renewable subscriptions. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nGiri Sugu — December 7, 2017 at 6:37 am (permalink) Hi. In non-renewable subscriptions i have a couple of questions,\n1. if i have 200 products means, do i want to add that all 200 products in iTunes connect\n2.is it possible to set the price and expiry date which i want.(bcoz if i am adding 200 products on iTunes connect i have to set the price.But in that we can able to choose the tier they mentioned.)So is it possible to set the prices\nShai Almog — December 8, 2017 at 6:51 am (permalink) Hi,\n1. Yes.\n2. I think there is an ability to pick a price but that makes it hard with international sales and coin fluctuations so tiers might be better overall.\nJulien Sosin — February 9, 2018 at 7:21 am (permalink) Hello. An user cancel his purchase but Apple didn’t send the cancellation_date when I refresh the receipts and I can’t know that the user had cancel his purchase. What can I do ?\nShai Almog — February 10, 2018 at 6:01 am (permalink) Hi,\nNot much. If Apple doesn’t send the cancellation it’s a problem. Generally with in-app-purchase you should only sell stuff you don’t mind losing occasionally on.\nJulien Sosin — February 10, 2018 at 8:57 am (permalink) Hi Almog. I guess I should check manually :/\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/in-app-purchase-non-renewable-subscriptions/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/in-app-purchase-non-renewable-subscriptions/in-app-purchase.jpg\"\u003e\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eThis is the second post in a three-part series on In-App purchase. Please check out \u003ca href=\"/blog/intro-to-in-app-purchase/\"\u003ePart I: Introduction to In-App Purchase\u003c/a\u003e and \u003ca href=\"/blog/autorenewing-subscriptions-in-ios-and-android/\"\u003ePart 3: Auto-renewing Subscriptions in iOS and Android\u003c/a\u003e.\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eIn \u003ca href=\"/blog/intro-to-in-app-purchase/\"\u003emy last post\u003c/a\u003e we looked at one-off in-app purchases. In this post we’ll look at subscriptions. As we discussed before, there are two types of subscriptions:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003eNon-renewable\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eAuto-renewable\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eNon-renewable subscriptions are really the same as consumable products, except that they are shareable across all of a user’s devices. Auto-renewable subscriptions, on the other hand, will continue as long as the user doesn’t cancel it. They will be re-billed automatically by the appropriate app-store when the chosen period expires, and all management of the subscription is handled by the the app-store itself.\u003c/p\u003e","title":"Implementing Non-Renewable Subscriptions with In-App Purchase"},{"content":"\nOne of the most painful aspects in any mobile app is input, besides the difficulty of viewing the details on a\ntiny cramped screen the input via the virtual keyboard is nowhere near the input comfort of a full fledged computer\nor even a tablet.\nA great app adapts to the screen size and uses the available space more effectively, we tried to do this in the kitchen\nsink demo where user input appears like this in portrait:\nFigure 1. The kitchen sink input demo in portrait mode\nFigure 2. The kitchen sink input demo in landscape mode\nYou will notice that the demo uses table layout when in landscape (or running on a tablet) and a box layout\non the Y_AXIS when running in a phone in portrait to use the space better. One of the things that isn’t obvious\nfrom the screenshots above is the nice animation we get when rotating the device.\nThe code that makes this possible is really simple and should be easily adaptable to any input form you might\nhave:\nprivate void addComps(Form parent, Container cnt, Component... cmps) { __**(1)** if(Display.getInstance().isTablet() || !Display.getInstance().isPortrait()) { __**(2)** TableLayout tl = new TableLayout(cmps.length / 2, 2); cnt.setLayout(tl); tl.setGrowHorizontally(true); for(Component c : cmps) { if(c instanceof Container) { __**(3)** cnt.add(tl.createConstraint().horizontalSpan(2), c); } else { cnt.add(c); } } } else { cnt.setLayout(BoxLayout.y()); for(Component c : cmps) { cnt.add(c); } } if(cnt.getClientProperty(\u0026quot;bound\u0026quot;) == null) { __**(4)** cnt.putClientProperty(\u0026quot;bound\u0026quot;, \u0026quot;true\u0026quot;); if(!Display.getInstance().isTablet()) { parent.addOrientationListener((e) -\u0026gt; { Display.getInstance().callSerially(() -\u0026gt; { cnt.removeAll(); __**(5)** addComps(parent, cnt, cmps); cnt.animateLayout(800); }); }); } } } addComps(parent, comps, new Label(\u0026quot;Name\u0026quot;, \u0026quot;InputContainerLabel\u0026quot;), name, new Label(\u0026quot;E-Mail\u0026quot;, \u0026quot;InputContainerLabel\u0026quot;), email, new Label(\u0026quot;Password\u0026quot;, \u0026quot;InputContainerLabel\u0026quot;), password, BorderLayout.center(new Label(\u0026quot;Birthday\u0026quot;, \u0026quot;InputContainerLabel\u0026quot;)). add(BorderLayout.EAST, birthday), new Label(\u0026quot;Bio\u0026quot;, \u0026quot;InputContainerLabel\u0026quot;), bio, BorderLayout.center(new Label(\u0026quot;Join Mailing List\u0026quot;, \u0026quot;InputContainerLabel\u0026quot;)). add(BorderLayout.EAST, joinMailingList)); __1 | The addComps method just adds all the components to a dynamically changing input. You can\nuse this method almost \u0026ldquo;as is\u0026rdquo; to get the effect above __2 In tablets/desktops we always use the table mode so the box layout only applies in portrait phones and nowhere else __3 We have a special case for container rows where we might have a custom UI element, in this case we always make it span the whole row even in a table layout mode __4 Without these lines the listener code would be bound twice and the layouts would blink __5 The animation logic just recurses the method so the elements are re-added with the right constraint then animated. Since the elements already have the right position the layout animation will produce that great rotation effect Final Word What makes an app delightful is the attention to detail, small changes like this make the UX of an app\nand it’s esthetic far more appealing. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nGareth Murfin — December 19, 2016 at 2:39 pm (permalink) Excellent functionality, I look forward to using this in my next apps, I am ready to swap to new gui editor now too I think :-)))) Keep up the good work.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-table-to-box/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-table-to-box/just-the-tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the most painful aspects in any mobile app is input, besides the difficulty of viewing the details on a\u003cbr\u003e\ntiny cramped screen the input via the virtual keyboard is nowhere near the input comfort of a full fledged computer\u003cbr\u003e\nor even a tablet.\u003c/p\u003e\n\u003cp\u003eA great app adapts to the screen size and uses the available space more effectively, we tried to do this in the kitchen\u003cbr\u003e\nsink demo where user input appears like this in portrait:\u003c/p\u003e","title":"TIP: Table to Box"},{"content":"Installing The Eclipse Plugin IMPORTANT: The IDE plugins are no longer supported. This page is here for historical purposes only. See Getting Started for discussion of the maven build process.\nHome Developers Installing The Eclipse Plugin The information in this page is out of date! Just type \u0026ldquo;Codename\u0026rdquo; in \u0026ldquo;Eclipse Marketplace\u0026rdquo; to install Codename One see this video.\nStartup Eclipse and click Help-\u0026gt;Install New Software. You should get this dialog: Click The Add Button On The Right Side And Fill Out The Entries Enter \u0026lsquo;CodenameOne\u0026rsquo; for the Name and \u0026lsquo;http://www.codenameone.com/files/eclipse/site.xml' for the Location. Select The Entries \u0026amp; Follow The Wizard To Install ","permalink":"https://www.codenameone.com/eclipse-plugin-installation/","summary":"\u003ch1 id=\"installing-the-eclipse-plugin\"\u003eInstalling The Eclipse Plugin\u003c/h1\u003e\n\u003cp\u003e\u003cstrong\u003eIMPORTANT:\u003c/strong\u003e The IDE plugins are no longer supported. This page is here for historical purposes only. See \u003ca href=\"/getting-started/\"\u003eGetting Started\u003c/a\u003e for discussion of the maven build process.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eDevelopers\u003c/li\u003e\n\u003cli\u003eInstalling The Eclipse Plugin\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"the-information-in-this-page-is-out-of-date\"\u003eThe information in this page is out of date!\u003c/h2\u003e\n\u003cp\u003eJust type \u0026ldquo;Codename\u0026rdquo; in \u0026ldquo;Eclipse Marketplace\u0026rdquo; to install Codename One see \u003ca href=\"/how-do-i---create-a-basic-hello-world-application--send-it-to-my-device-using-eclipse.html\"\u003ethis video\u003c/a\u003e.\u003c/p\u003e\n\u003ch2 id=\"startup-eclipse-and-click-help-install-new-software-you-should-get-this-dialog\"\u003eStartup Eclipse and click Help-\u0026gt;Install New Software. You should get this dialog:\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"Eclipse Install\" loading=\"lazy\" src=\"/uploads/eclipse_install_1.png\"\u003e\u003c/p\u003e","title":"Eclipse Plugin Installation"},{"content":"\nWe had to push out an update to the IntelliJ/IDEA plugin to workaround an issue that started happening with their\nlatest IDE update. The 3.5.11 version didn’t change much just fixed those specific issues. Other than that this\nweeks release includes some new In-App-Purchase features (that we will discuss next week) and the new\nseamless caching API discussed yesterday.\nOne of the features we didn’t mention this week in the posts is a new ability to set the default size of a floating\naction button using code like:\nFloatingActionButton.setIconDefaultSize(4); I didn’t mention this before because it was a result of\nthis question\nso please ask on stackoverflow and you might get a new feature…​\nHello World who asked that also had a question about\naudio capture timing.\nWe place so much emphasis on the Capture API that sometimes people don’t notice we can just record audio\ndirectly via the MediaManager class.\nI’ve been going back and forth with ravimaran over the process\nof uploading to S3.\nThis is actually pretty easy thanks to the multipart API. However, permissions/visibility settings in S3 aren’t trivial.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-36/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-36/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe had to push out an update to the IntelliJ/IDEA plugin to workaround an issue that started happening with their\u003cbr\u003e\nlatest IDE update. The 3.5.11 version didn’t change much just fixed those specific issues. Other than that this\u003cbr\u003e\nweeks release includes some new In-App-Purchase features (that we will discuss next week) and the new\u003cbr\u003e\nseamless caching API discussed yesterday.\u003c/p\u003e\n\u003cp\u003eOne of the features we didn’t mention this week in the posts is a new ability to set the default size of a floating\u003cbr\u003e\naction button using code like:\u003c/p\u003e","title":"Questions of the Week 36"},{"content":"\nCaching server data locally is a huge part of the advantage a native app has over a web app. Normally this is\nnon-trivial as it requires a delicate balance especially if you want to test the server resource for changes.\nHTTP provides two ways to do that the ETag and\nLast-Modified. While both are\ngreat they are non-trivial to use and by no definition seamless.\nWe just added an experimental feature to connection request that allows you to set the caching mode to one of\n4 states either globally or per connection request:\nOFF is the default meaning no caching.\nSMART means all get requests are cached intelligently and caching is \u0026ldquo;mostly\u0026rdquo; seamless\nMANUAL means that the developer is responsible for the actual caching but the system will not do a request on a resource that’s already \u0026ldquo;fresh\u0026rdquo;\nOFFLINE will fetch data from the cache and wont try to go to the server. It will generate a 404 error if data isn’t available\nYou can toggle these in the specific request by using setCacheMode(CachingMode) and set the global\ndefault using setDefaultCacheMode(CachingMode).\n__ Caching only applies to GET operations, it will not work for POST or other methods There are several methods of interest to keep an eye for:\nprotected InputStream getCachedData() throws IOException; protected void cacheUnmodified() throws IOException; public void purgeCache(); public static void purgeCacheDirectory() throws IOException; getCachedData() This returns the cached data. This is invoked to implement readResponse(InputStream) when running offline\nor when we detect that the local cache isn’t stale.\nThe smart mode implements this properly and will fetch the right data. However, the manual mode doesn’t\nstore the data and relies on you to do so. In that case you need to return the data you stored at this point and must\nimplement this method for manual mode.\ncacheUnmodified() This is a callback that’s invoked to indicate a cache hit, meaning that we already have the data.\nThe default implementation still tries to call all the pieces for compatibility (e.g. readResponse).\nHowever, if this is unnecessary you can override that method with a custom implementation or even a blank\nimplementation to block such a case.\npurgeCache \u0026amp; purgeCacheDirectory These methods are pretty self explanatory. Notice one caveat though…​\nWhen you download a file or a storage element we don’t cache them and rely on the file/storage element to\nbe present and serve as \u0026ldquo;cache\u0026rdquo;. When purging we won’t delete a file or storage element you downloaded and\nthus these might remain.\nHowever, we do remove the ETag and Last-Modified data so the files might get refreshed the next time around.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/automatic-caching/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/automatic-caching/networking.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCaching server data locally is a huge part of the advantage a native app has over a web app. Normally this is\u003cbr\u003e\nnon-trivial as it requires a delicate balance especially if you want to test the server resource for changes.\u003c/p\u003e\n\u003cp\u003eHTTP provides two ways to do that the \u003ca href=\"https://en.wikipedia.org/wiki/HTTP_ETag\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eETag\u003c/a\u003e and\u003cbr\u003e\n\u003ca href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eLast-Modified\u003c/a\u003e. While both are\u003cbr\u003e\ngreat they are non-trivial to use and by no definition seamless.\u003c/p\u003e\n\u003cp\u003eWe just added an experimental feature to connection request that allows you to set the caching mode to one of\u003cbr\u003e\n4 states either globally or per connection request:\u003c/p\u003e","title":"Automatic Caching"},{"content":"\n__ This is the first post in a three-part series on In-App purchase. Please check out Part 2: Introduction to In-App Purchase and Part 3: Auto-renewing Subscriptions in iOS and Android. In-app purchase is a helpful tool for making app development profitable. Codename One has supported in-app purchases of consumable and non-consumable products on Android and iOS for some time now, and with the next update we are adding support for subscriptions. For such a seemingly simple task, in-app purchase involves a lot of moving parts – especially when it comes to subscriptions. For this reason, I’ll be splitting this topic up into a few different blog posts. This post will provide a light introduction to in-app purchase and subscriptions, and show you how to support them in your app. In subsequent posts, I’ll go deeper into some more advanced topics such as receipt validation, server-side subscription management (which is required for subscriptions in the iTunes store), and the specifics of how to set up in-app purchases in both Google Play and the iTunes stores.\nThe SKU In-app purchase support is centered around your set of SKUs that you want to sell. Each product that you sell, whether it be a 1-month subscription, an upgrade to the \u0026ldquo;Pro\u0026rdquo; version, \u0026ldquo;10 disco credits\u0026rdquo;, will have a SKU (stock-keeping-unit). Ideally you will be able to use the same SKU across all of the stores that you sell your app in.\nTypes of Products There are generally 4 classifications for products:\nNon-consumable Product – This is a product that the user purchases once, and they \u0026ldquo;own\u0026rdquo; it. They cannot re-purchase it. One example is a product that upgrades your app to a \u0026ldquo;Pro\u0026rdquo; version.\nConsumable Product – This is a product that the user can purchase multiple times. E.g. You might have a product for \u0026ldquo;10 Credits\u0026rdquo; that allow the user to buy things in a game.\nNon-Renewable Subscription – A subscription that is purchased once, and will not be \u0026ldquo;auto-renewed\u0026rdquo; by the app store. These are almost identical to consumable products, except that subscriptions need to be transferable across all of the user’s devices. This means that non-renewable subscriptions require that you have a server server to keep track of the subscriptions.\nRenewable Subscriptions – A subscription that is completely managed by the app store. The user will be automatically billed when the subscription period ends, and the subscription will be renewed.\n__ These subscription categories may not be explicitly supported by a given store, or they may be called different things. However each type of product can be implemented in a Codename One app in a cross-platform way. E.g. In Google Play there is no distinction between consumable products and non-renewable subscriptions, but in iTunes there is a distinction. The \u0026ldquo;Hello World\u0026rdquo; of In-App Purchase Let’s start with a simple example of an app that sells \u0026ldquo;Worlds\u0026rdquo;. The first thing we do is pick the SKU for our product. I’ll choose com.codename1.world for the SKU.\npublic static final String SKU_WORLD = \u0026quot;com.codename1.world\u0026quot;; Next, our app’s main class needs to implement the PurchaseCallback interface\npublic class HelloWorldIAP implements PurchaseCallback { .... @Override public void itemPurchased(String sku) { ... } @Override public void itemPurchaseError(String sku, String errorMessage) { ... } @Override public void itemRefunded(String sku) { ... } @Override public void subscriptionStarted(String sku) { ... } @Override public void subscriptionCanceled(String sku) { ... } @Override public void paymentFailed(String paymentCode, String failureReason) { ... } @Override public void paymentSucceeded(String paymentCode, double amount, String currency) { ... } } Using these callbacks, we’ll be notified whenever something changes in our purchases. For our simple app we’re only interested in itemPurchased() and itemPurchaseError().\nNow in the start method, we’ll add a button that allows the user to buy the world:\npublic void start() { if(current != null){ current.show(); return; } Form hi = new Form(\u0026quot;Hi World\u0026quot;); Button buyWorld = new Button(\u0026quot;Buy World\u0026quot;); buyWorld.addActionListener(e-\u0026gt;{ if (Purchase.getInAppPurchase().wasPurchased(SKU_WORLD)) { Dialog.show(\u0026quot;Can't Buy It\u0026quot;, \u0026quot;You already Own It\u0026quot;, \u0026quot;OK\u0026quot;, null); } else { Purchase.getInAppPurchase().purchase(SKU_WORLD); } }); hi.addComponent(buyWorld); hi.show(); } At this point, we already have a functional app that will track the sale of the world. To make it more interesting, let’s just add some feedback with the ToastBar to show when the purchase completes.\n@Override public void itemPurchased(String sku) { ToastBar.showMessage(\u0026quot;Thanks. You now own the world\u0026quot;, FontImage.MATERIAL_THUMB_UP); } @Override public void itemPurchaseError(String sku, String errorMessage) { ToastBar.showErrorMessage(\u0026quot;Failure occurred: \u0026quot;+errorMessage); } See full code listing\n__ You can test out this code in the simulator without doing any additional setup and it will work. If you want the code to work properly on Android and iOS, you’ll need to set up the app and in-app purchase settings in the Google Play and iTunes stores respectively. I will cover that in a subsequent post. When the app first opens we see our button:\nIn the simulator, clicking on the \u0026ldquo;Buy World\u0026rdquo; button will bring up a prompt to ask you if you want to approve the purchase.\nNow if I try to buy the product again, it pops up the dialog to let me know that I already own it.\nMaking it Consumable In the \u0026ldquo;Buy World\u0026rdquo; example above, the \u0026ldquo;world\u0026rdquo; product was non-consumable, since it could only be purchased once. We could easily change it to a consumable product by simply disregarding whether it had been purchased before and keeping track of how many times it had been purchased.\nWe’ll use storage to keep track of the number of worlds that have been purchased. We need two methods to manage this count. One to get the number of worlds that we currently own, and another to add a world to this count.\nprivate static final String NUM_WORLDS_KEY = \u0026quot;NUM_WORLDS.dat\u0026quot;; public int getNumWorlds() { synchronized (NUM_WORLDS_KEY) { Storage s = Storage.getInstance(); if (s.exists(NUM_WORLDS_KEY)) { return (Integer)s.readObject(NUM_WORLDS_KEY); } else { return 0; } } } public void addWorld() { synchronized (NUM_WORLDS_KEY) { Storage s = Storage.getInstance(); int count = 0; if (s.exists(NUM_WORLDS_KEY)) { count = (Integer)s.readObject(NUM_WORLDS_KEY); } count++; s.writeObject(NUM_WORLDS_KEY, new Integer(count)); } } Now we’ll change our purchase code as follows:\nbuyWorld.addActionListener(e-\u0026gt;{ if (Dialog.show(\u0026quot;Confirm\u0026quot;, \u0026quot;You own \u0026quot;+getNumWorlds()+ \u0026quot; worlds. Do you want to buy another one?\u0026quot;, \u0026quot;Yes\u0026quot;, \u0026quot;No\u0026quot;)) { Purchase.getInAppPurchase().purchase(SKU_WORLD); } }); And our itemPurchased() callback will need to add a world:\n@Override public void itemPurchased(String sku) { addWorld(); ToastBar.showMessage(\u0026quot;Thanks. You now own \u0026quot;+getNumWorlds()+\u0026quot; worlds\u0026quot;, FontImage.MATERIAL_THUMB_UP); } Show full code listing\n__ When we eventually set up the products in the iTunes store we will need to mark the product as a consumable product or iTunes will prevent us from purchasing it multiple times. Next Up: Non-Renewable Subscriptions Read more: Part 2: Introduction to In-App Purchase Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nsalah Alhaddabi — December 28, 2016 at 7:38 pm (permalink) Very nice Steve.\nCN1 is an amazing framework for mobile apps really!!\nPlease continue with these posts they are the best!!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/intro-to-in-app-purchase/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/intro-to-in-app-purchase/in-app-purchase.jpg\"\u003e\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eThis is the first post in a three-part series on In-App purchase. Please check out \u003ca href=\"/blog/in-app-purchase-non-renewable-subscriptions/\"\u003ePart 2: Introduction to In-App Purchase\u003c/a\u003e and \u003ca href=\"/blog/autorenewing-subscriptions-in-ios-and-android/\"\u003ePart 3: Auto-renewing Subscriptions in iOS and Android\u003c/a\u003e.\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eIn-app purchase is a helpful tool for making app development profitable. Codename One has supported in-app purchases of consumable and non-consumable products on Android and iOS for some time now, and with the next update we are adding support for subscriptions. For such a seemingly simple task, in-app purchase involves a lot of moving parts – especially when it comes to subscriptions. For this reason, I’ll be splitting this topic up into a few different blog posts. This post will provide a light introduction to in-app purchase and subscriptions, and show you how to support them in your app. In subsequent posts, I’ll go deeper into some more advanced topics such as receipt validation, server-side subscription management (which is required for subscriptions in the iTunes store), and the specifics of how to set up in-app purchases in both Google Play and the iTunes stores.\u003c/p\u003e","title":"Introduction to In-App Purchase"},{"content":"Developing In Codename One The first steps, guides, tutorials and resources you need.\nHome Developing In Codename One Documentation \u0026amp; Demo Source Code JavaDocs of the API\u0026rsquo;s Developer Guide How Do I? Get quick video answers and short tutorials for common questions.\nThe Codename One Blog The Codename One Tutorials \u0026amp; Courses Hello World Tutorial Shows off how to create a simple hello world application and work with the Codename One plugin to produce a simple hello world application that works on all devices and looks native to all devices.\nCodename One Academy A complete set of 3 courses that cover everything from basics to full featured real world application development.\nHow Do I? Short video tutorials that walk you thru common concepts of Codename One and teach simple/basic ideas\nTutorials \u0026amp; Documentation List An exhaustive list of the tutorials/references both written and in video form that are available to Codename One Developers\nTutorial Tag In the Blog The Codename One blog posts tutorials on a regular basis and you can follow those right in this tag\n","permalink":"https://www.codenameone.com/ios-mobile-app-development-tutorial-and-course/","summary":"\u003ch1 id=\"developing-in-codename-one\"\u003eDeveloping In Codename One\u003c/h1\u003e\n\u003cp\u003eThe first steps, guides, tutorials and resources you need.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eDeveloping In Codename One\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"documentation--demo-source-code\"\u003eDocumentation \u0026amp; Demo Source Code\u003c/h2\u003e\n\u003ch4 id=\"javadocs-of-the-apis\"\u003eJavaDocs of the API\u0026rsquo;s\u003c/h4\u003e\n\u003ch4 id=\"developer-guide\"\u003eDeveloper Guide\u003c/h4\u003e\n\u003ch4 id=\"how-do-i\"\u003eHow Do I?\u003c/h4\u003e\n\u003cp\u003eGet quick video answers and short tutorials for common questions.\u003c/p\u003e\n\u003ch4 id=\"the-codename-one-blog\"\u003eThe Codename One Blog\u003c/h4\u003e\n\u003ch2 id=\"the-codename-one-tutorials--courses\"\u003eThe Codename One Tutorials \u0026amp; Courses\u003c/h2\u003e\n\u003ch4 id=\"hello-world-tutorial\"\u003eHello World Tutorial\u003c/h4\u003e\n\u003cp\u003eShows off how to create a simple hello world application and work with the Codename One plugin to produce a simple hello world application that works on all devices and looks native to all devices.\u003c/p\u003e","title":"IOS Mobile App Development Tutorial and Course"},{"content":"\nWe’ve had quite a few interesting features land last week and didn’t get a chance to cover them. First we have\naccess to the OS’s caches directory where you can store files that you don’t really need as cache. Both iOS \u0026amp;\nAndroid have such a directory and files stored there might be purged without notice if the OS runs out of space.\nThis is a good place to store files you don’t really need such as images or downloads you just need for \u0026ldquo;right now\u0026rdquo;.\nTo use this we added two new API’s to FileSystemStorage:\npublic boolean hasCachesDir(); public String getCachesDir(); Normally we would use hasCachesDir() to indicate whether the caches dir should be used and if not we would just\nwrite fallback code that uses the home directory. Notice that the caches dir will only work on iOS \u0026amp; Android and\nwill return false everywhere else at this time. We plan to integrate this into various features of Codename One\nto make usage easier e.g. URLImage and an upcoming feature I’ll discuss later in the week.\nSorted Properties Starting with this release properties are sorted and no longer add a timestamp comment every time they are saved.\nThe comment makes no sense as it never provided any value beyond the file date/time stamp. The sorting of the\nproperties solves a major problem with the properties API. Saving is inconsistent.\nWe did this to fix a bug in our settings tool where codenameone_settings.properties gets jumbled whenever you\nsave because the order of the hashmap is based on the hashCode method. This way the order is consistent and\nremains that way when checking the file into version control.\nFixing this for our application only would solve our problem but I’m guessing the jumbled properties that you need\nto sort thru every time doesn’t make sense for any application ever…​\nThis way you can have a consistent human understandable order for machine saved properties. Notice this is a\n\u0026ldquo;write only\u0026rdquo; feature so you don’t need to sort your properties for parsing to work.\nPreferences Listener We got a pull request that allows you to observe\nthe Preferences API. This is useful if you have some generic code that relies on this API for settings.\nThis request lets you do something like:\nPreferences.addPreferenceListener(\u0026quot;MySetting\u0026quot;, (pref, oldValue, newValue) -\u0026gt; Log.p(pref + \u0026quot; changed to \u0026quot; + newValue)); This allows you to monitor changes to preferences individually and apply them instantly when they happen\nwithout the need to wrap all calls to preferences in a generic method. This observability allows different parts\nof your application to remain decoupled while supporting a single setting attribute. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — December 13, 2016 at 11:46 pm (permalink) bryan says:\nSo should use something like:\nFileSystemStorage.getInstance().openOutputStream(FileSystemStorage.getInstance().getChacheDir() + \u0026ldquo;/ \u0026quot; + fname);\nShai Almog — December 14, 2016 at 5:12 am (permalink) Shai Almog says:\nNot quite. getCachesDir() will be null for cases where there is no such directory. E.g. on the simulator we don’t have a caches dir so this will fail. So you need a strategy that will no how to deal with a null cache directory. E.g. this is new code for a feature I’m blogging about later this week:\nprivate String getCacheFileName() {\nString root;\nif(FileSystemStorage.getInstance().hasCachesDir()) {\nroot = FileSystemStorage.getInstance().getCachesDir() + \u0026ldquo;cn1ConCache/\u0026rdquo;;\n} else {\nroot = FileSystemStorage.getInstance().getAppHomePath()+ \u0026ldquo;cn1ConCache/\u0026rdquo;;\n}\nFileSystemStorage.getInstance().mkdir(root);\nreturn root + Base64.encodeNoNewline(createRequestURL().getBytes()).replace(‘/’, ‘-‘).replace(‘+’, ‘_’);\n}\nThis will use the caches dir if it’s available but fallback to normal if not.\nAlso notice that directories in Codename One should always end with the / character so the + \u0026ldquo;/\u0026rdquo; is redundant.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/cache-sorted-properties-preferences-listener/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/cache-sorted-properties-preferences-listener/new-features-5.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve had quite a few interesting features land last week and didn’t get a chance to cover them. First we have\u003cbr\u003e\naccess to the OS’s caches directory where you can store files that you don’t really need as cache. Both iOS \u0026amp;\u003cbr\u003e\nAndroid have such a directory and files stored there might be purged without notice if the OS runs out of space.\u003c/p\u003e\n\u003cp\u003eThis is a good place to store files you don’t really need such as images or downloads you just need for \u0026ldquo;right now\u0026rdquo;.\u003c/p\u003e","title":"Cache, Sorted Properties and Preference Listener"},{"content":"\nA frequent complaint we get is the lack of a search feature on the site and we get that. It’s frustrating to us too.\nWe’d like to add it but are still looking at the \u0026ldquo;right way\u0026rdquo; to do it which I’ll discuss at more length below but for\nnow I’d like to discuss a couple of relatively simple workarounds.\nThe Current Workarounds Google Site Search We can just type site:codenameone.com followed by your query into google when searching to search within the site\ne.g. like this https://www.google.co.il/search?q=site%3Acodenameone.com+Button\nThis is the same as Google’s custom search which some sites use but provides a \u0026ldquo;sub par\u0026rdquo; experience.\nJavaDoc Index I’ve discussed this in the past, if you are looking for a method, variable or class this is probably the best place\nto start: \u0026lt;/javadoc/index-all/\u0026gt;\nThis is the full \u0026ldquo;index\u0026rdquo; of our JavaDoc. It doesn’t include everything obviously it doesn’t include cn1libs and some\ninformation might be missing but the ability to use the browser search within that page is very valuable.\nDeveloper Guide PDF The developer guide is available in PDF form and that\nis easily searchable. It contains a lot of useful information on almost everything.\n3rd Party Hosts One of the bigger problems is that a lot of our content isn’t on our site. Searching stackoverflow is rather convenient\nbut you should do it within the tag itself otherwise it might be needle in a haystack: http://stackoverflow.com/tags/codenameone\nGoogle Groups have a mediocre search experience but it’s usable, notice that you need to search the group\ndirectly as the main Google search often misses that and will not show that content for \u0026ldquo;site:\u0026rdquo; searches:\nhttps://groups.google.com/forum/#!forum/codenameone-discussions\nWhy don’t we \u0026ldquo;just\u0026rdquo; Implement Search? We use JBake for our backend. We still have a dynamic server and could do some logic (e.g.\nlucene) in there but it seems like a \u0026ldquo;mess\u0026rdquo; when dealing with static data. This is compounded by the fact that\nsome of our searchable data comes from different sources (e.g. JavaDoc). I’ll ignore stackoverflow and\nthe google group searches for now as they probably fall outside of the initial problem.\nWhat we really want is a static search tool that will work with the static site generation, this allows us to leverage\nsolutions like cloudflare to scale really well!\nThere are some tools like that which are pretty cool e.g. lunr.js but they don’t scale well to\nsites as large as ours. We have over 15,000 non-trivial unique single word keywords…​ Creating an index to\nmap this takes up at least 5mb just for the index of keywords in every page. This makes client side search a\nbit difficult.\nWe’ve played with some ideas such as a split index but there doesn’t seem to be a \u0026ldquo;ready made\u0026rdquo; solution.\nIf you are aware of something we’re missing that will play nicely with JBake on scale let us know. If not we\nmight have to build something of our own.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-search-the-website/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-search-the-website/just-the-tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA frequent complaint we get is the lack of a search feature on the site and we get that. It’s frustrating to us too.\u003cbr\u003e\nWe’d like to add it but are still looking at the \u0026ldquo;right way\u0026rdquo; to do it which I’ll discuss at more length below but for\u003cbr\u003e\nnow I’d like to discuss a couple of relatively simple workarounds.\u003c/p\u003e\n\u003ch3 id=\"the-current-workarounds\"\u003eThe Current Workarounds\u003c/h3\u003e\n\u003ch4 id=\"google-site-search\"\u003eGoogle Site Search\u003c/h4\u003e\n\u003cp\u003eWe can just type site:codenameone.com followed by your query into google when searching to search within the site\u003cbr\u003e\ne.g. like this \u003ca href=\"https://www.google.co.il/search?q=site%3Acodenameone.com\u0026#43;Button\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttps://www.google.co.il/search?q=site%3Acodenameone.com+Button\u003c/a\u003e\u003c/p\u003e","title":"TIP: Search the Website"},{"content":"\nThis week has been a bit slow with features and external progress as we’ve started to focus on the issues for\nthe January release of 3.6. During December we’ll probably pause blogging between December 22nd and January\n2nd as it would probably get lost to the ether for most of our audience.\nI’ll still be working and at least some of our team will, but we’ll focus on support and features/issues which will\ngive us a lot to write about when we get back.\nTodays update doesn’t include anything exceptional just a couple of new features and fixes.\nStuart Brand asks why the\nenter key doesn’t show on the text field\nbut this is somewhat misleading…​ Which is why you must always ask with your intention.\nAt first I thought he meant the standard return key so my answer reflected that, newline isn’t on by default\nwith TextField. But it seems he was looking for a \u0026ldquo;done\u0026rdquo; key which you can determine for Android using the\nclient properties to pass a hint to the text field.\n__ | Another wrong path here was the mixed terminology of \u0026ldquo;key\u0026rdquo;. In Codename One keys refer to physical\nkeys and not virtual keys Mamatha Damuluri asks\nhow one would know if an app is minimized.\nTim Weber provided a great answer for that. Lifecycle\nis one the harder things in mobile development. We tried to simplify it as much as possible but there\nare always pitfalls. Check out the first chapter of the developer guide when we cover some of these concepts…​\ntizbn asked how to\nset the icon gap variable within a command\nthis is pretty easy but a lot of people might not know the answer which again involves a client property.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-35/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-35/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis week has been a bit slow with features and external progress as we’ve started to focus on the issues for\u003cbr\u003e\nthe January release of 3.6. During December we’ll probably pause blogging between December 22nd and January\u003cbr\u003e\n2nd as it would probably get lost to the ether for most of our audience.\u003c/p\u003e\n\u003cp\u003eI’ll still be working and at least some of our team will, but we’ll focus on support and features/issues which will\u003cbr\u003e\ngive us a lot to write about when we get back.\u003c/p\u003e","title":"Questions of the Week 35"},{"content":"\nWe had support for bouncy castle encryption for quite a while but it is not as intuitive as we’d like it to be. This makes\nsecuring/encrypting your app painful and so we procrastinate and eventually skip that \u0026ldquo;feature\u0026rdquo; altogether.\nFrankly, I hate working on encryption it’s painful…​ That’s why we procrastinated on this feature until today!\nWe now support full encryption of the Storage (notice the distinction, Storage is not FileSystemStorage).\nThis is available by installing the latest bouncy castle cn1lib from the extensions menu then using one line of code\nEncryptedStorage.install(\u0026quot;your-pass-encryption-key\u0026quot;); __ Normally you would want that code within your init(Object) method Notice that you can’t use storage or preferences to store this data as it would be encrypted (Preferences uses\nStorage internally). You can use a password for this key and it would make it way more secure but if a user\nchanges his password you might have a problem. In that case you might need the old password to migrate to\na new password.\nThis works thru a new mechanism we added to storage where you can replace the storage instance with another\ninstance using:\nStorage.setStorageInstance(new MyCustomStorageSubclass()); We can leverage that knowledge to change the encryption password on the encryption storage using pseudo\ncode like this:\nEncryptedStorage.install(oldKey); InputStream is = Storage.getInstance().createInputStream(storageFileName); byte[] data = Util.readInputStream(is); EncryptedStorage.install(newKey); OutputStream o = Storage.getInstance().createOutputStream(\u0026quot;TestEncryption\u0026quot;); o.write(data); o.close(); __ It’s not a good idea to replace storage objects when an app is running so this is purely for this special case…​ Moving Forward We’d like Codename One apps to be more secure than native apps and they are already pretty good to begin with.\nBecause we use code and not a well known resource format and because we obfuscate by default our apps are\nmuch harder to reverse engineer.\nHowever, we think we can do more and we hope to do so. This specific feature was sponsored by an enterprise\ncustomer who needed that capability, we have other pending features in the IO section related to other enterprise\ncustomer RFE’s that are coming soon.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/seamless-storage-encryption/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/seamless-storage-encryption/new-features-6.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe had support for bouncy castle encryption for quite a while but it is not as intuitive as we’d like it to be. This makes\u003cbr\u003e\nsecuring/encrypting your app painful and so we procrastinate and eventually skip that \u0026ldquo;feature\u0026rdquo; altogether.\u003cbr\u003e\nFrankly, I hate working on encryption it’s painful…​ That’s why we procrastinated on this feature until today!\u003c/p\u003e\n\u003cp\u003eWe now support full encryption of the \u003ccode\u003eStorage\u003c/code\u003e (notice the distinction, \u003ccode\u003eStorage\u003c/code\u003e is not \u003ccode\u003eFileSystemStorage\u003c/code\u003e).\u003cbr\u003e\nThis is available by installing the latest bouncy castle cn1lib from the extensions menu then using one line of code\u003c/p\u003e","title":"Seamless Storage Encryption"},{"content":"\nThe validation framework makes it easy to verify input quickly and effectively. Up until now you had to define\nan emblem in order to create an error icon and if you didn’t you had to define an \u0026ldquo;Invalid\u0026rdquo; UIID for every entry.\nThis exists by default for text fields and other types but is still a big hassle just to check that we have a valid\nemail…​\nThe main reason for this is that when we introduced the validation framework we hadn’t yet integrated the\nmaterial icons into Codename One, this was remedied and starting with the next update we’ll have a default\nemblem. Notice that if you replace it manually your emblem will still be used…​\nHowever, we also changed the default behavior as a result. In the past we defaulted to HighlightMode.UIID\nwhich makes a lot of sense when you don’t have an emblem. This default no longer makes sense and so\nwe now have HighlightMode.EMBLEM as the default.\nSo if your code relies on the default behavior of the validator this will no longer behave in the same way. The\nworkaround is actually really simple, just add the call:\nmyValidator.setValidationFailureHighlightMode(Validator.HighlightMode.UIID); To force the same behavior as before.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/default-validation-emblem/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/default-validation-emblem/validation-emblem.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe validation framework makes it easy to verify input quickly and effectively. Up until now you had to define\u003cbr\u003e\nan emblem in order to create an error icon and if you didn’t you had to define an \u0026ldquo;Invalid\u0026rdquo; UIID for every entry.\u003cbr\u003e\nThis exists by default for text fields and other types but is still a big hassle just to check that we have a valid\u003cbr\u003e\nemail…​\u003c/p\u003e\n\u003cp\u003eThe main reason for this is that when we introduced the validation framework we hadn’t yet integrated the\u003cbr\u003e\nmaterial icons into Codename One, this was remedied and starting with the next update we’ll have a default\u003cbr\u003e\nemblem. Notice that if you replace it manually your emblem will still be used…​\u003c/p\u003e","title":"Default Validation Emblem"},{"content":"\nIn the first betas of Codename One we had a lot of bugs related to 2D arrays due to XMLVM.\nWe no longer use XMLVM but the recommendation to avoid 2D arrays remains. We still use them in some occasions\ne.g. in the creation of a DefaultTableModel but the implementation discards them in favor of an ArrayList internally.\n__ | To be fair, a 2D array will be faster than an ArrayList so in this case we discarded them due to their lack of\nflexibility What’s the Problem? To understand the problem of 2D arrays we need to understand how they work. When we write something like this:\nint[][] myArray = new int[] { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; What we are \u0026ldquo;effectively\u0026rdquo; doing is this:\nint[] a1 = {1, 2, 3}; int[] a2 = {4, 5, 6}; int[] a3 = {7, 8, 9}; Object[] myArray = {a1, a2, a3}; That sounds like a \u0026ldquo;small\u0026rdquo; semantic difference but it’s a huge one!\nThat means we have 4 arrays where we should have had just 1. That’s far more objects to GC \u0026amp; allocate. That\nalso means that every array lookup has to happen twice. The problem here is that these semantics are often\nused when processing large data such as screen images that might be pretty big at which case you need to\nmultiply that overhead by 1024.\nThere is one exception where the length of the individual entries isn’t uniform, however that’s a pretty rare use\ncase. Most such cases use collection classes and not multi-dimensional arrays.\nFaster Way We do a lot of image RGB manipulations and we always use a single dimension array. This is far more performant\nand pretty easy to use. When we want to access an individual pixel we can do:\npixels[x + y * width] = newValue; It might seem that the overhead of multiplication and addition would cancel out the benefit of the array lookup.\nThat’s not true as those operations are remarkably fast by comparison especially with AoT compilation. JIT’s might\nbe able to do some magic with 2D arrays but even if they can do that they would still need more GC and allocation\nwork as both of those are unavoidable. So a 1D array would always be superior in Java.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-avoid-2d-arrays/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-avoid-2d-arrays/just-the-tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIn the first betas of Codename One we had a lot of bugs related to 2D arrays due to XMLVM.\u003cbr\u003e\nWe no longer use XMLVM but the recommendation to avoid 2D arrays remains. We still use them in some occasions\u003cbr\u003e\ne.g. in the creation of a \u003ccode\u003eDefaultTableModel\u003c/code\u003e but the implementation discards them in favor of an \u003ccode\u003eArrayList\u003c/code\u003e internally.\u003c/p\u003e\n\u003cp\u003e__ |  To be fair, a 2D array will be faster than an \u003ccode\u003eArrayList\u003c/code\u003e so in this case we discarded them due to their lack of\u003c/p\u003e","title":"TIP: Avoid 2D Arrays"},{"content":"\nWhile I find these posts useful I think it’s time to re-think this post which is overly mechanical and only post\ninteresting news from the week rather than \u0026ldquo;everything\u0026rdquo;. So this week we’ll try something new, I’ll discuss the\nnews in general and the questions/answers I find valuable only. I’ll ignore the other questions and this should\nmake the post more \u0026ldquo;digestible\u0026rdquo;.\npeopletookallthegoodnames asked\nabout Storage to FileSystemStorage mapping here.\nThis is a problematic subject. Storage is an abstraction, the fact that the implementation can be seen sometimes\nwithin the FileSystemStorage is a \u0026ldquo;leak\u0026rdquo; within the abstraction.\nWe considered hardening the abstraction by making this impractical in the simulator but that would break running\napps and we don’t want to get into that at this time.\nHelloWorld showed why it’s important to ask on stackoverflow…​\nWe don’t currently support Java 8 operations in native Android code but following\nhis question\nwe added an experimental feature that might allow this.\nStefan literally took the sample code from our javascript\nJavaDocs and tried to run it and it seems\nit didn’t work\napparently this code should be executed after the page loads which makes it a bit harder to bind properly.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-34/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-34/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhile I find these posts useful I think it’s time to re-think this post which is overly mechanical and only post\u003cbr\u003e\ninteresting news from the week rather than \u0026ldquo;everything\u0026rdquo;. So this week we’ll try something new, I’ll discuss the\u003cbr\u003e\nnews in general and the questions/answers I find valuable only. I’ll ignore the other questions and this should\u003cbr\u003e\nmake the post more \u0026ldquo;digestible\u0026rdquo;.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://stackoverflow.com/users/1299498/peopletookallthegoodnames\" target=\"_blank\" rel=\"noopener noreferrer\"\u003epeopletookallthegoodnames\u003c/a\u003e asked\u003cbr\u003e\nabout \u003ccode\u003eStorage\u003c/code\u003e to \u003ccode\u003eFileSystemStorage\u003c/code\u003e mapping \u003ca href=\"http://stackoverflow.com/questions/40897107/codename-one-cant-get-correct-storage-path-on-android\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere\u003c/a\u003e.\u003cbr\u003e\nThis is a problematic subject. \u003ccode\u003eStorage\u003c/code\u003e is an abstraction, the fact that the implementation can be seen sometimes\u003cbr\u003e\nwithin the \u003ccode\u003eFileSystemStorage\u003c/code\u003e is a \u0026ldquo;leak\u0026rdquo; within the abstraction.\u003c/p\u003e","title":"Questions of the Week 34"},{"content":"\nSubclassing isn’t bad but it becomes tedious especially if it’s just there to implement something trivial. One of\nthe pain points we had with the ConnectionRequest API’s is the submission body wasn’t as convenient as it\nshould be.\nE.g. if my web service accepts JSON in the post argument I have to write something like this:\nConnectionRequest r = new ConnectionRequest(myURL, true) { protected void buildRequestBody(OutputStream os) throws IOException { os.write(myJSON.getBytes(\u0026quot;UTF-8\u0026quot;)); } }; This works great but does it really require subclassing?\nSo we added this:\nConnectionRequest r = new ConnectionRequest(myURL, true); { r.setRequestBody(myJSON); Notice that you must use post and if you have an argument (or try to add one later) it will fail as you can’t have both…​\nDialog Layouts A while back we fixed Form to have a constructor with a layout manager which reduces one line of code but\nis also a slight optimization as it saves an allocation of the default FlowLayout that would be there in the\nfirst place.\nWe now added two constructors to Dialog as well that allow you to create a Dialog with a layout manager and\na layout manager + title.\nBorder Layout Improvements I don’t like the syntax of border layout, the constraint argument makes it overly tedious to work with for\nmost cases but it is one of the best layouts as it’s remarkably consistent and predictable.\nTo make this slightly easier we added two new capabilities, first we added two new enclose methods:\npublic static Container centerEastWest(Component center, Component east, Component west) public static Container centerAbsoluteEastWest(Component center, Component east, Component west) These allow us to shorten the common use case of wrapping a component in a border layout, e.g. up until now\nif I wanted to add two components to a border layout one in the center and one in the west I had to do this:\nContainer c = BorderLayout.center(cmp1). add(BorderLayout.WEST, cmp2); Now I can do this which is a bit better:\nContainer c = BorderLayout.centerEastWest(cmp1, null, cmp2); Another common problem we had in the past is this, see if you can spot the error here:\npublic class MyClass extends Form { public MyClass() { super(new BorderLayout()); add(CENTER, new Label(\u0026quot;Hello World\u0026quot;)); } } Those of you who spotted this might think this won’t compile but it will…​ BorderLayout expects one of it’s constants\nthe string BorderLayout.CENTER but in this case we used Component.CENTER which is an int we\nderive thru Form.\nWhile this is a \u0026ldquo;mistake\u0026rdquo; in theory it occurred to me that there is no \u0026ldquo;real\u0026rdquo; mistake here. The programmers\nintention is clear, why force the usage of a specific constant?\nSo we added code into BorderLayout that will detect this case and do what you expect for the other constants\ntoo (BOTTOM, LEFT, TOP, RIGHT). I would still recommend using BorderLayout as it is slightly more efficient\n(no autoboxing allocation)\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/request-body-dialog-border-layout/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/request-body-dialog-border-layout/new-features-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSubclassing isn’t bad but it becomes tedious especially if it’s just there to implement something trivial. One of\u003cbr\u003e\nthe pain points we had with the \u003ccode\u003eConnectionRequest\u003c/code\u003e API’s is the submission body wasn’t as convenient as it\u003cbr\u003e\nshould be.\u003c/p\u003e\n\u003cp\u003eE.g. if my web service accepts JSON in the post argument I have to write something like this:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eConnectionRequest r = new ConnectionRequest(myURL, true) {\n    protected void buildRequestBody(OutputStream os) throws IOException {\n        os.write(myJSON.getBytes(\u0026quot;UTF-8\u0026quot;));\n    }\n};\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis works great but does it really require subclassing?\u003c/p\u003e","title":"Request Body, Dialog \u0026 Border Layout"},{"content":"\nI’ve written this in emails before and on quite a few occasions but this bares repeating. Gaining visibility in this industry is tough especially when the industry is driven by the likes of Google, Facebook \u0026amp; Apple.\nDespite years of effort, most Java developers or mobile developers haven’t heard about us and it’s still an uphill battle for awareness.\nIf you like our product and think we are doing something important it would be VERY helpful for us if you can help us with these small things.\nDoing everything below would take 5 minutes and every bit counts!\nHow Can You Help? If you are active on Reddit, Hackernews or any other community such as these and you think something we wrote is worthwhile for that site we’d really appreciate a share or shoutout on those sites.\nIf you have accounts in any of those networks listed below, we’d appreciate the help here.\n🔥 List of things you can do to help Codename One grow: __ Star \u0026amp; Fork on GitHub __ Follow \u0026amp; Star codenameone tag on StackOverflow __ Join our Subreddit for open discussion \u0026amp; support __ Follow \u0026amp; engage on social media __ Download, rate \u0026amp; review our app __ Enroll \u0026amp; share our courses on Codename One Academy What Else? Community engagement for Codename One is good but it can still be better. Ask us questions on StackOverflow, fork our projects on Github, contribute your work and submit pull requests.\nIf you ask a proper question on StackOverflow, you will get points (which are useful when you have a really hard question), so even if it isn’t the biggest problem in the world, ask…​\nIf you see something broken, report it or submit a pull request. You can just edit the Codename One sources/docs directly on the Github site. If JavaDoc isn’t clear or the developer guide was confusing just edit them directly and help the next person coming along. The developer guide is literally a wiki you can edit!\nLet us know if you have ideas how to improve the site and engage with us. Try to use the public forums e.g. comments, StackOverflow and discussion groups when engaging so other developers gain the benefits of the collective knowledge. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nHristo Vrigazov — December 2, 2016 at 6:21 pm (permalink) Hristo Vrigazov says:\nCodename One deserves way more visibility than it has.\nJaco Dt — February 2, 2017 at 6:07 am (permalink) Jaco Dt says:\nAgreed\nFrancesco Galgani — August 28, 2017 at 2:44 am (permalink) Francesco Galgani says:\nTo spread Codename One, I’m trying to encourage the Engineering students of my university to try it. I’m also added Codename One to my curriculum. Maybe I’ll also write an article about Codename One in my blog. I think that you, Shai, are doing a very important and useful job replying to almost all help requests on Stack Overflow and in this blog: your help is encouraging me in specializing in Codename One. Of course I hope that more Codename One developers will share their knowledge on StackOverflow.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/how-you-can-help-spread-codenameone/","summary":"\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/blog/how-you-can-help-spread-codenameone/guest-post-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve written this in emails before and on quite a few occasions but this bares repeating. Gaining visibility in this industry is tough especially when the industry is driven by the likes of Google, Facebook \u0026amp; Apple.\u003c/p\u003e\n\u003cp\u003eDespite years of effort, most Java developers or mobile developers haven’t heard about us and it’s still an uphill battle for awareness.\u003c/p\u003e\n\u003cp\u003eIf you like our product and think we are doing something important it would be \u003cstrong\u003eVERY\u003c/strong\u003e helpful for us if you can help us with these small things.\u003c/p\u003e","title":"How you can Help Spread Codename One"},{"content":"\nIn my last post I demonstrated how to integrate a MySQL database into a Codename One app using Xataface as a web service layer. In this installment, I’m going to demonstrate how we can build an equivalent app using a Java web service layer.\nRequirements For this tutorial, I’ll be using NetBeans 8.1 and its bundled GlassFish 4.0 container. If you don’t already have a MySQL database set up, then I recommend you install XAMPP XAMPP, as it provides a double-clickable installer for Mac and Windows and an easy administration console.\nThe Database The following setup instructions are identical to those in the previous post. They are included here for convenience:\nFor my database I’m going to use the Sakila sample database provided by MySQL. This database models a video rental store, including such aspects as customer information, staff info, film info, and actor info. The schema is as follows (schema taken from here):\nAs you can see, this database includes much more than contact information, but our app will focus only on contact info. This is actually quite a typical scenario for a mobile app. I frequently create ad-hoc mobile apps that consume specific parts from the data source in order to help with testing of the main app. Mobile apps, in my experience, work quite well when they are focused on doing one task well, rather than doing a whole bunch of tasks as you would expect in a desktop application.\nSo in this case, you can imagine that the store owners might want an app to help keep track of the contacts in the system. That is the app we will build here.\nInstalling the Database I’ll be using the mysql command-line client that is installed at /Applications/XAMPP/bin/mysql on my development machine. If yours is installed elsewhere then you’ll adjust your commands accordingly.\nFirst, download the Sakila database from here. (Link obtained from this page in case the direct link becomes broken later for some reason).\nWhen you extract the archive, you’ll find two SQL files:\nsakila-schema.sql – This contains the database schema. sakila-data.sql – This contains the sample data We’ll install both into our database with the following commands.\n$ mysql -u root -p \u0026lt; sakila-schema.sql $ mysql -u root -p \u0026lt; sakila-data.sql Once these have executed, you should be able to log into mysql and see see the tables listed:\n$mysql -u root -p USE sakila; Database changed SHOW TABLES; +----------------------------+ | Tables_in_sakila | +----------------------------+ | actor | | address | | category | | city | | country | | customer | | customer_list | | film | | film_actor | | film_category | | film_list | | film_text | | inventory | | language | | nicer_but_slower_film_list | | payment | | rental | | sales_by_film_category | | sales_by_store | | staff | | staff_list | | store | +----------------------------+ 22 rows in set (0.00 sec) SELECT COUNT(*) FROM film; +----------+ | COUNT(*) | +----------+ | 1000 | +----------+ 1 row in set (0.02 sec) SELECT COUNT(*) FROM film_text; +----------+ | COUNT(*) | +----------+ | 1000 | +----------+ 1 row in set (0.00 sec) The Web Service I’m going to use Netbeans and its handy wizards to generate the web service this time around. Before we begin, we’ll need to set up NetBeans to connect to our MySQL database.\nConfiguring Netbeans to use MySQL Click on the \u0026ldquo;Services\u0026rdquo; tab, and right click on \u0026ldquo;Databases\u0026rdquo;:\nSelect the \u0026ldquo;Register MySQL Server\u0026rdquo; option. This will bring up a setup dialog as follows. If you installed XAMPP, and are using the mysql server included with that, then your settings will look like mine. If not, you’ll need to customize them for your needs.\nAfter you have completed your settings, and clicked \u0026ldquo;OK\u0026rdquo;, you should see a new node appear under the \u0026ldquo;Databases\u0026rdquo; node named \u0026ldquo;MySQL Server at localhost:3306\u0026rdquo;. Expand this node to see all of your databases revealed.\nRight click on the \u0026ldquo;sakila\u0026rdquo; database, and select \u0026ldquo;Connect…​\u0026rdquo; as shown below:\nAt this point we should have all of the groundwork covered to create our server project.\nCreating the Web Service Project In Netbeans select \u0026ldquo;File\u0026rdquo; \u0026gt; \u0026ldquo;New Project…​\u0026rdquo;, then in the new project wizard select \u0026ldquo;Maven\u0026rdquo; \u0026gt; \u0026ldquo;Web Application\u0026rdquo;.\n__ I’m using Maven for this tutorial because I prefer it, but you could also use an ANT-based project under \u0026ldquo;Java Web\u0026rdquo; \u0026gt; \u0026ldquo;Web Application\u0026rdquo; and it should work fine. After completing the new project wizard, you should see the SakilaRESTServer project in the project navigator, as shown here.\nGenerating the Web Services Currently the project is a generic web application without any web services or database access defined. Let’s add that now.\nRight click on the \u0026ldquo;SakilaRESTServer\u0026rdquo; project in the project explorer, and select \u0026ldquo;New\u0026rdquo; \u0026gt; \u0026ldquo;RESTful Web Services from Database\u0026rdquo; as shown below:\nIn the dialog that appears, in the Data Source select list, select \u0026ldquo;New Data Source…​\u0026rdquo;.\nEnter \u0026ldquo;jdbc/sakila\u0026rdquo; as the JNDI name, and then select the JDBC connection string for the sakila database from the pull-down:\nAfter clicking \u0026ldquo;OK\u0026rdquo;, you should see the \u0026ldquo;Available Tables\u0026rdquo; list populated as shown below.\nFor this application, you should uncheck the \u0026ldquo;Include related tables\u0026rdquo; checkbox as we only want the \u0026ldquo;Customer\u0026rdquo; table, and the Customer_list view to be included. If you were to leave this checked, then all kinds of other information would be included by default in the REST responses which we don’t want.\nNow add the \u0026ldquo;Customer\u0026rdquo; and \u0026ldquo;Customer_List\u0026rdquo; tables to the \u0026ldquo;Selected Tables\u0026rdquo; list and click \u0026ldquo;Next\u0026rdquo;.\nThe next page we’ll leave default:\nAnd same with the next page.\nFinally, click the \u0026ldquo;Finish\u0026rdquo; button to let the magic begin.\nOnce the dust has settled, your project structure should look something like the following:\nA few things to notice here:\nEntity classes for Customer and CustomerList have been generated in the com.codename1.demos.sakila package. Corresponding web service facades have been generated in the com.codename1.demos.sakila. These are the actual web services that will handle requests. Take the time to browse through the entity classes and services to get a feel for what is going on. It should be reasonably straight forward.\nSpecify the ID field in CustomerList Since Customer_List is a view, Netbeans doesn’t know which column is the \u0026ldquo;id\u0026rdquo;, so we’ll need to add that. If you open the CustomerList class, you’ll see a compile error because of this.\nYou’ll need to add the @Id annotation to the \u0026ldquo;ID\u0026rdquo; field declaration. Netbeans will assist you with this if you expant the little light bulb icon in the left column of the error line.\nA Look at the Web Service Facades At this point our web service is done, but before proceeding, let’s take a look at some of the source so that we get a sense of how the web service will work.\nThe CustomerFacade class looks like:\npackage com.codename1.demos.sakilarestserver.service; // redacted imports @Stateless @Path(\u0026quot;com.codename1.demos.sakilarestserver.customer\u0026quot;) __**(1)** public class CustomerFacadeREST extends AbstractFacade\u0026lt;Customer\u0026gt; { @PersistenceContext(unitName = \u0026quot;com.codename1.demos_SakilaRESTServer_war_1.0-SNAPSHOTPU\u0026quot;) private EntityManager em; public CustomerFacadeREST() { super(Customer.class); } @POST @Override @Consumes({\u0026quot;application/xml\u0026quot;, \u0026quot;application/json\u0026quot;}) public void create(Customer entity) { __**(2)** super.create(entity); } @PUT @Path(\u0026quot;{id}\u0026quot;) @Consumes({\u0026quot;application/xml\u0026quot;, \u0026quot;application/json\u0026quot;}) public void edit(@PathParam(\u0026quot;id\u0026quot;) Short id, Customer entity) { __**(3)** super.edit(entity); } @DELETE @Path(\u0026quot;{id}\u0026quot;) public void remove(@PathParam(\u0026quot;id\u0026quot;) Short id) { __**(4)** super.remove(super.find(id)); } @GET @Path(\u0026quot;{id}\u0026quot;) @Produces({\u0026quot;application/xml\u0026quot;, \u0026quot;application/json\u0026quot;}) public Customer find(@PathParam(\u0026quot;id\u0026quot;) Short id) { __**(5)** return super.find(id); } @GET @Override @Produces({\u0026quot;application/xml\u0026quot;, \u0026quot;application/json\u0026quot;}) public List\u0026lt;Customer\u0026gt; findAll() { __**(6)** return super.findAll(); } @GET @Path(\u0026quot;{from}/{to}\u0026quot;) @Produces({\u0026quot;application/xml\u0026quot;, \u0026quot;application/json\u0026quot;}) public List\u0026lt;Customer\u0026gt; findRange(@PathParam(\u0026quot;from\u0026quot;) Integer from, @PathParam(\u0026quot;to\u0026quot;) Integer to) { __**(7)** return super.findRange(new int[]{from, to}); } @GET @Path(\u0026quot;count\u0026quot;) @Produces(\u0026quot;text/plain\u0026quot;) public String countREST() { __**(8)** return String.valueOf(super.count()); } @Override protected EntityManager getEntityManager() { return em; } } __1 The relative URL to the web service. To access this web service, you would append this value to the end of the URL for the web app. In our case \u0026lt;http://localhost:8080/SakilaRESTServer/com.codename1.demos.sakilarestserver.customer\u0026gt; is the full URL to this webservice. __2 Endpoint to insert a new record into the customer table. This can be accessed by sending a POST request to the webservice URL with appropriate XML or JSON data. __3 Endpoint to update an existing record. This can be accessed by sending a PUT request to {webservice_url}/{customer_id} with the appropriate XML or JSON data. For example, if we wanted to update the customer with customer_id=10 we would send our PUT request to \u0026lt;http://localhost:8080/SakilaRESTServer/com.codename1.demos.sakilarestserver.customer/10\u0026gt; __4 Endpoint to delete a record. This can be accessed by sending a DELETE request to {webservice_url}/{customer_id}. __5 Endpoint to find a record by ID. This can be accessed by sending a GET request to {webservice_url}/{customer_id}. By default the web service returns XML. You’ll need to add the header Accept: application/json to indicate that it should return JSON. __6 Endpoint to return a list of all records in the customer table. This can be accessed by sending a GET request to the webservice URL. As with other GET requests, you should use the Accept HTTP header to indicate whether you want the result in XML or JSON. __7 Endpoint to return a list of only rows in the specified range. Accessed with a GET request to {webservice_url}/{from}/{to}. E.g. to get only the first 3 records in the table, we would send a GET request to \u0026lt;http://localhost:8080/SakilaRESTServer/com.codename1.demos.sakilarestserver.customer/0/2\u0026gt; __8 Endpoint to return the number of rows in the customer table. This can be accessed by sending a GET request to {webservice_url}/count. Full class can be seen here\nRunning/Testing the Project In the project explorer, right click on the SakilaRESTServer project and select \u0026ldquo;Run\u0026rdquo;. This should automatically start the bundled GlassFish server, and deploy our app.\nIf all wend well, it should open your web browser to the index page which says \u0026ldquo;Hello World!\u0026rdquo;.\nNext, we’ll test out the actual webservices.\nIn the project explorer, uner the \u0026ldquo;RESTful Web Services\u0026rdquo; folder, you should see two web services listed. Right click on either of them and select \u0026ldquo;Test Resoure Uri\u0026rdquo; as shown here:\nThis should open up your web browser with an XML feed of all of the records in the customers table.\nThe Client App I’m changing very little of the Client app from the Xataface client version shown in my previous post. Instead of the CN1Xataface library, which is designed to consume a Xataface-powered web-service, I’m using the GenericWebserviceClient.cn1lib which is designed to consume a generic web service, with APIs like the web service that we just created. This library should be applicable to a most of the APIs in production today.\nThe GenericWebserviceClient.cn1lib includes a RESTfulWebServiceClient class with the following main methods:\n// Delete a record with id asynchronously public void delete(String id, SuccessCallback\u0026lt;Boolean\u0026gt; callback); // Create a new record with the given data asynchronously public void create(Map data, SuccessCallback\u0026lt;Boolean\u0026gt; callback); // Edit an existing record with given data asynchronously. public void edit(String id, Map data, SuccessCallback\u0026lt;Boolean\u0026gt; callback); // Count the number of records provided by the web service. public void count(SuccessCallback\u0026lt;Integer\u0026gt; callback); // Find records provided by the web service public void find(Query query, SuccessCallback\u0026lt;RowSet\u0026gt; callback) The Query class allows you to specify a find by record ID or on a range. It can be overridden to provide additional criteria to access other methods of a webservice API if they are required.\nYou can view the source of the RESTfulWebserviceClient class here.\nThe client App source is as follows (redacted for clarity):\npackage com.codename1.demos.sakila; // redacted imports ... import com.codename1.ws.RESTfulWebServiceClient; import com.codename1.ws.RESTfulWebServiceClient.Query; import com.codename1.ws.RESTfulWebServiceClient.RowSet; /** * This file was generated by \u0026lt;a href=\u0026quot;https://www.codenameone.com/\u0026quot;\u0026gt;Codename One\u0026lt;/a\u0026gt; for the purpose * of building native mobile applications using Java. */ public class SakilaDemo { // redacted member variables ... String customerEndpoint = \u0026quot;http://localhost:8080/SakilaRESTServer/webresources/com.codename1.demos.sakilarestserver.customer\u0026quot;; __**(1)** // Database Connection Properties RESTfulWebServiceClient client; // redacted utility methods ... // Lifecycle Methods ------------------------------------------------------- public void init(Object context) { theme = UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;); // Enable Toolbar on all Forms by default Toolbar.setGlobalToolbar(true); // Pro only feature, uncomment if you have a pro subscription // Log.bindCrashProtection(true); client = new RESTfulWebServiceClient(customerEndpoint); __**(2)** } public void start() { if(current != null){ current.show(); return; } Form hi = new Form(\u0026quot;Contacts\u0026quot;); hi.setLayout(new BorderLayout()); hi.show(); Display.getInstance().callSerially(()-\u0026gt;{ loadContacts(rowset-\u0026gt;{ __**(3)** hi.addComponent(BorderLayout.CENTER, createContactsList(hi, rowset)); }); }); } public void stop() { // redacted ... } public void destroy() { } // Web Service Methods ----------------------------------------------------- /** * Loads all of the contacts from the database asynchronously. On complete * the callback will be called with the resulting rowset as a parameter, or * null if there was an error. * @param callback Callback to handle the received rowset. */ private void loadContacts(SuccessCallback\u0026lt;RowSet\u0026gt; callback) { __**(4)** Query q = new Query(); __**(5)** client.find(q, callback); __**(6)** } /** * Convert a record from the \u0026quot;contact\u0026quot; table into a Contact object. * @param record A record from the \u0026quot;contact\u0026quot; table. * @return A Contact object */ private static Contact createContact(Map m) { __**(7)** Result record = Result.fromContent(m); Contact c = new Contact(); c.setFirstName(record.getAsString(\u0026quot;firstName\u0026quot;)); c.setFamilyName(record.getAsString(\u0026quot;lastName\u0026quot;)); c.setPrimaryEmail(record.getAsString(\u0026quot;email\u0026quot;)); return c; } /** * Convert a rowset (from the contact table) into an array of Contact * objects * @param rowset A rowset from the contact table. * @return An array of Contact records. */ private static Contact[] rowsetToContactsArray(RowSet rowset) { __**(8)** List\u0026lt;Contact\u0026gt; lst = new ArrayList\u0026lt;Contact\u0026gt;(); for (Map record : rowset) { lst.add(createContact(record)); } return lst.toArray(new Contact[lst.size()]); } // View Factory Methods ---------------------------------------------------- /** * Creates a list of contacts included in the specified rowset. * @param parentForm The parent form * @param rowset The rowset to encapsulate (from the \u0026quot;contact\u0026quot; table) * @return A container to be added to the form. */ private Container createContactsList(Form parentForm, RowSet rowset) { Contact[] contacts = rowsetToContactsArray(rowset); // redacted image creation stuff... final Container contactsDemo = new Container(BoxLayout.y()); contactsDemo.setScrollableY(true); for(Contact c : contacts) { Container row = createContactRow(c, contactsDemo); if (row != null) { contactsDemo.add(row); } } contactsDemo.revalidate(); finishedLoading = true; RowSet[] lastSet = new RowSet[]{rowset}; InfiniteScrollAdapter.createInfiniteScroll(contactsDemo, () -\u0026gt; { Query nextQuery = lastSet[0].getNextQuery(); __**(9)** if (nextQuery.getSkip() \u0026gt; lastSet[0].getSkip()) { client.find(nextQuery, newResult -\u0026gt; { __**(10)** if (newResult == null) { return; } List\u0026lt;Component\u0026gt; toAdd = new ArrayList\u0026lt;Component\u0026gt;(); for (Map row : newResult) { Container cntRow = createContactRow(createContact(row), contactsDemo); if (cntRow != null) { toAdd.add(cntRow); } } InfiniteScrollAdapter.addMoreComponents(contactsDemo, toAdd.toArray(new Component[toAdd.size()]), true); lastSet[0] = newResult; contactsDemo.revalidate(); }); } }); return contactsDemo; } /** * Creates a single row for the contact list that encapsulates the provided * contact. * @param c The contact to represent with this row. * @param parent The parent container to which the row is to be added. This method doesn't actually add the * row to the parent, but it does need to reference it for some of the listeners that are added to the row. The caller * should add the resulting row to the parent after calling this method. * @return A container encapsulating the row, or null if the contact didn't have a name. */ private Container createContactRow(Contact c, Container parent) { // redacted same 'ol same 'ol } } __1 The end point for the web service. We got this directly from the @Path annotation of the CustomerFacadeREST class on the server. __2 Instantiate a client for the web service. Notice that we passed the URL to the endpoint in the constructor. __3 We call loadContacts() to asynchronously load the contacts inside the start() method. __4 The implementation of loadContacts() which simply wraps a call to RESTfulWebServiceClient.find(). __5 Create a new Query for the find request. By default a query is set to load the first 30 rows of the end point. __6 We use the find() method to asynchronously load records from our end point. __7 createContact() is a convenience method to convert our Maps of customer data received from the web service into Contact objects which our UI was already set up to use. Note one difference from the Xataface version in the previous blog post is that the property names use camel-case instead of snake case. __8 rowsetToContactsArray converts an entire RowSet received from the web service into an array of Contact records. __9 We use the InfiniteScrollAdapter to progressively load more rows as required. RowSet includes a convenience getNextQuery() method to get query to produce the next page of results. __10 Finally we load the next page of results inside the InfiniteScrollAdapter using client.find(). See the full source here.\nThe Final Results This app is effectively identical to the one from our previous post, so it will look the same.\nSummary This brief tutorial demonstrated how you can set up a web service facade in front of a MySQL database to be consumed by a Codename One app. It introduced the GenericWebServiceClient library as tool to help you consume web services of this kind. This library should be applicable to the vast majority of RESTful APIs in production today, and it is easily extendible so you can customize it to suit your specific needs if they aren’t met out of the box.\n__ This post completely ignored security concerns. The examples here produced web services that are effectively open to the world. In a future post I may cover security, but for now, I leave it to you to make sure that you secure your web services. Having demonstrated two different ways to develop essentially the same app, you may be wondering which approach is better. My response would be that it depends. Using Xataface in the back-end provides quite a bit of query flexibility in the client for free. However, the Java solution will perform better under load. Personally I use Xataface a lot for setting up administration tools and ad-hoc apps. If I plan to build a service that will scale to millions of users (thousands of requests per second), I will move towards the JVM.\nResources The GenericWebService.cn1lib Repo on Github Github Repo for the projects in this tutorial Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nthunderkilll — April 24, 2018 at 9:10 am (permalink) thank you for this i hope you can make a video of it so we can understand more\nChris B — November 6, 2020 at 6:40 am (permalink) Is this possible in eclipse? I’m trying to connect a Codename One application I have built in eclipse to an AWS RDS database I’ve built. Both Codename One and AWS are brand new to me, and I have no idea what I am doing.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/connecting-to-a-mysql-database-part-2/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/connecting-to-a-mysql-database-part-2/connecting-mysql-to-codenameone.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIn my last post I demonstrated how to integrate a MySQL database into a Codename One app using Xataface as a web service layer. In this installment, I’m going to demonstrate how we can build an equivalent app using a Java web service layer.\u003c/p\u003e\n\u003ch2 id=\"requirements\"\u003eRequirements\u003c/h2\u003e\n\u003cp\u003eFor this tutorial, I’ll be using NetBeans 8.1 and its bundled GlassFish 4.0 container. If you don’t already have a MySQL database set up, then I recommend you install XAMPP \u003ca href=\"https://www.apachefriends.org/index.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eXAMPP\u003c/a\u003e, as it provides a double-clickable installer for Mac and Windows and an easy administration console.\u003c/p\u003e","title":"Connecting to a MySQL Database from Codename One Part 2: Pure Java"},{"content":"\nOne of the nice things in mobile development vs. desktop is the fact that updates are seamless. We supposedly\ndon’t need to worry about them and most newer OS’s turn them on by default. This keeps are users with the latest\nversion which is important, e.g. if we fixed a crucial bug or added a new monetization option…​\nHowever, the reality rarely fits into this nice image. In practice an update can be delayed because of permission\nchanges user settings and many other problems. As a result old and even discontinued apps can still exist on\nuser devices and give you a hard time with user complaints.\n__ We still get notifications from apps that haven’t been listed in the stores for over 2 years! Over the years we developed a policy of update management that handles all potential edge cases:\nUpdate recommended – we have a new update out and we want you to switch to it but it isn’t crucial\nUpdate required – if you don’t update now we’d rather the app stops working\nSwitch App recommended – This app was discontinued, we suggest you switch to a new app. This can\nhappen when a product line changes or even if you lose your certificate an can no longer update the app\nSwitch App required – This app was discontinued but we have this alternative app you can migrate to, the\napp will stop working and activating it will launch that URL after an error message\nApp was discontinued but you can keep using for now\nApp was discontinued and will no longer work\nThose are all potential outcomes that we can forsee but there are a lot of things we can’t forsee so we need\nto make this process as generic as possible.\nThe Solution We store properties files in our servers as plain text, this is easy and requires almost no configuration. These\nproperties files use the following naming convention: AppName-OS-Status.properties.\nInside the properties file we have the following settings:\ndeprecatedVersion – the version number we no longer support but still run\nderprecatedMessage – a message to show users of the deprecated version\nderprecatedAltURL – URL to send users of the deprecated version to\nunsupportedVersion – the version we no longer support\nunsupportedMessage – a message we show to users of the unsupported version\nunsupportedAltURL – URL to send users of the unsupported version\nWe can leave most properties blank if they aren’t applicable and might not even have a file.\n__ | Host these files in your own domain under your control. A dropbox URL might change and might be blocked in\nsome cases and the same is true for github The Code Notice that this code needs to execute after the first form was shown and not in the init(Object) method.\nIt will fail gracefully and the app will keep working if there is no Internet connection.\nString url = \u0026quot;https://myurl.com/mydir/\u0026quot; + Display.getInstance().getProperty(\u0026quot;AppName\u0026quot;, \u0026quot;MyApp\u0026quot;) + \u0026quot;-\u0026quot; + Display.getInstance().getPlatformName() + \u0026quot;-Status.properties\u0026quot;; Log.p(\u0026quot;Checking update URL: \u0026quot; + url); ConnectionRequest c = new ConnectionRequest(url, false) { private Properties props; @Override protected void readResponse(InputStream input) throws IOException { props = new Properties(); props.load(input); } @Override protected void postResponse() { if(props != null) { float version = Float.parseFloat(Display.getInstance().getProperty(\u0026quot;AppVersion\u0026quot;, \u0026quot;1.0\u0026quot;)); float unsupportedVersion = Float.parseFloat(props.getProperty(\u0026quot;unsupportedVersion\u0026quot;, \u0026quot;-1\u0026quot;)); if(version \u0026lt;= unsupportedVersion) { String message = props.getProperty(\u0026quot;unsupportedMessage\u0026quot;, \u0026quot;The current application version is no longer supported\u0026quot;); String url = props.getProperty(\u0026quot;unsupportedAltURL\u0026quot;, null); if(url == null) { Dialog.show(\u0026quot;Unsupported Version\u0026quot;, message, \u0026quot;OK\u0026quot;, null); Display.getInstance().exitApplication(); } else { if(!Dialog.show(\u0026quot;Unsupported Version\u0026quot;, message, \u0026quot;OK\u0026quot;, \u0026quot;Exit\u0026quot;)) { Display.getInstance().exitApplication(); } Display.getInstance().execute(url); Display.getInstance().exitApplication(); } } float deprecatedVersion = Float.parseFloat(props.getProperty(\u0026quot;deprecatedVersion\u0026quot;, \u0026quot;-1\u0026quot;)); if(version \u0026lt;= deprecatedVersion) { String message = props.getProperty(\u0026quot;derprecatedMessage\u0026quot;, \u0026quot;A new version of the app is available, please update\u0026quot;); String url = props.getProperty(\u0026quot;derprecatedAltURL\u0026quot;, null); if(url == null) { Dialog.show(\u0026quot;New Version\u0026quot;, message, \u0026quot;OK\u0026quot;, null); } else { if(Dialog.show(\u0026quot;New Version\u0026quot;, message, \u0026quot;Download\u0026quot;, \u0026quot;OK\u0026quot;)) { Display.getInstance().execute(url); } } } } } }; c.setFailSilently(true); NetworkManager.getInstance().addToQueue(c); Now you will need properties files matching these URL’s, notice that the name is OS specific to allow you to have\ndifferent version deprecation policies for different OS’s (e.g. for the case of losing the Android certificate). Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJérémy MARQUER — November 28, 2016 at 2:31 pm (permalink) Jérémy MARQUER says:\nInteresting post but what about offline app or online app that can work offline ? I mean, for example, exiting application in case of unsupported version will work only if device is connected …\nShai Almog — November 30, 2016 at 4:05 am (permalink) Shai Almog says:\nThis fails silently when offline.\nI wanted to keep the code simple so I didn’t go into the more complex situation of a \u0026ldquo;user turns on airplane mode to use the app\u0026rdquo;. I think that if a user resorts to that rather than just update the app he’ll also download an illegal APK/IPA and jailbrake his device so this ventures into another domain.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-cross-platform-update-available-strategy/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-cross-platform-update-available-strategy/just-the-tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the nice things in mobile development vs. desktop is the fact that updates are seamless. We supposedly\u003cbr\u003e\ndon’t need to worry about them and most newer OS’s turn them on by default. This keeps are users with the latest\u003cbr\u003e\nversion which is important, e.g. if we fixed a crucial bug or added a new monetization option…​\u003c/p\u003e\n\u003cp\u003eHowever, the reality rarely fits into this nice image. In practice an update can be delayed because of permission\u003cbr\u003e\nchanges user settings and many other problems. As a result old and even discontinued apps can still exist on\u003cbr\u003e\nuser devices and give you a hard time with user complaints.\u003c/p\u003e","title":"TIP: Cross Platform Update Available Strategy"},{"content":"\nThis has been a very busy week, we published new information on the properties approach\nwhich I’m excited about but I’m not sure if I can drum up your enthusiasm…​\nSteve made a big post about mysql support too.\nTodays library update includes new simulator code that might\nbreak some apps if you’ve refactored stuff around so be vigilant and let us know if something suddenly stops working.\nOn stack overflow things were as usual:\nRefresh list of images without reloading the page I am Working on an app with requirement where we need to create a dynamic image gallery which refreshes after few minutes.When refresh happens three things should happen without reloading the page 1)…​\nRead on stackoverflow…​\nCan’t install iOs App anymore I made some fixes for my App and wanted to try it out today on my iPhone and now I can’t install it on the device anymore. I’m getting the error \u0026ldquo;Unable to Download App\u0026rdquo; on the phone. I haven’t …​\nRead on stackoverflow…​\nHow to upload file using codenameone? How to get the InputStream of the uploaded file from codenameone app to my rest full webservices so,that i can able to store blob type of the file in my database table?\nRead on stackoverflow…​\nConsume .NET web service in Codename One by requesting parameters How to consume webservice dataset values in codename one? My webservice returns results by passing three paramenters?\nRead on stackoverflow…​\nWhy is my TableLayout modified when going back from another Form? Here is my problem: I have a Form which contains several tabs. In the first one, I have a Table which contains information. My problem is that, when I open a new Form (let’s say, a Dialog) and then …​\nRead on stackoverflow…​\nWhy my CodenameOne-App was not working with HTTPS in ios devices My App until last two weeks was making all requests using http. All was working fine. since last week , back-end server changed its protocol to HTTPS. I did some corrections in my code, changing http …​\nRead on stackoverflow…​\nHow to focus certain component I have added one container with boxlayout with Y axis and adds multiple buttons and I want to focus to certain position of the container how it can be done ?\nRead on stackoverflow…​\nCharset in browsercomponent I’ve got a problem when using the BrowserComponent in Codenameone: When calling the dropbox authorization URL in the BrowserComponent within the simulator, the page is displayed, but the charset seems …​\nRead on stackoverflow…​\nCodename1 side menu misplacement I am trying to specify sidemenu width with the follow code: Hashtable\u0026lt;String, Integer\u0026gt; h = new Hashtable\u0026lt;\u0026gt;(); h.put(\u0026ldquo;sideMenuSizePortraitInt\u0026rdquo;, 50); h.put(\u0026quot;…​\nRead on stackoverflow…​\nDebugging Codename One app on Android Studio I need to debug my CN1 app on Android. That’s why I successfully followed the instructions given in this Codename One tutorial (I copied and updated the gradle files dependencies content as explained)…​.\nRead on stackoverflow…​\nRedirect to page Contact Phone IOS in cordova-Codenameone I use Cordova Hybrid Apps in Codename One and My question is : \u0026ldquo;How can I call, from AngularJS, the contacts page of my IPhone\u0026rdquo;. Thanks\nRead on stackoverflow…​\nHow to use slide transition for images on the same form in codename one Pls how can i use slide transition for Images on the same Form? I used this code, but it shows and error Label lab = new Label(); lab.setUIID(\u0026ldquo;IMAGE\u0026rdquo;); lab.setTransitionOutAnimator(…​\nRead on stackoverflow…​\nJava IO exception feature is supported from different Java Version I am currently working on a class project with codename one and am running into issues with the built in InputStream and MediaManager classes. It keeps telling me that the feature I am attempting to …​\nRead on stackoverflow…​\nMake swipeable container swipe only to the left I just added swipeable container to my app and it is working perfectly, only thing is I want it to only to swipe to the left, from what I read in the documentary is, that I can either make it swipe to …​\nRead on stackoverflow…​\nRotate a fontImage in codenameone Image shareIcon = FontImage.createMaterial(FontImage.MATERIAL_REPLY, s); shareIcon = shareIcon.rotate(180); ShareButton shareButton = new ShareButton(); shareButton.setIcon(shareIcon); How can I flip …​\nRead on stackoverflow…​\nCodename One Geofencing If you are experiencing an issue please mention the full platform your issue applies to: IDE: NetBeans/Eclipse/IDEA Desktop OS Simulator Device If you are experiencing an issue please mention the …​\nRead on stackoverflow…​\nHow to force permission \u0026ldquo;android.permission.CAMERA\u0026rdquo; to be added to manifest in Codename one I am trying to show a live preview of the rear facing camera in Codename One. I use for that the native interface (I am targetting Android first). To allow my app to use the camera without messing …​\nRead on stackoverflow…​\nCodename One: Scale down Image with scrolling I currently have a Logo of my app on the top of every form. Since it takes a lot of space, I want it’s size to scale down the more the user scrolls down, just the way a lot of apps do it. My Logo is …​\nRead on stackoverflow…​\nHow to use title Animations in codename one Pls how do i use Title Animations in CN1 to animate pictures in src directory. I followed the developer guide which I used the sample code. When I ran the code the picture did not perform any …​\nRead on stackoverflow…​\nIntelliJ: Sending build does nothing suddenly I am trying to build my App but when sending the build nothing really happens and it won’t show up on the build server as well. I have built it several times before, I don’t know whats wrong. He …​\nRead on stackoverflow…​\nHow to manage/control font/component size in Javascript Build apps I found my Javascript build apps’s font/control size show differently in different platform, e.g. it show normal in iphone’s safari browser, but shown \u0026ldquo;huge\u0026rdquo; in android chrome browser. It also shown …​\nRead on stackoverflow…​\nUsing SwipableContainer under Tabs This creates a SwipeableContainer inside a Tab, but the swipe gesture is always detected by both the SwipeableContainer and the Tab (i.e. It shows the button under SwipeableContainer and move the page …​\nRead on stackoverflow…​\nHow to make a ComponentGroup that stretches to fill the available space? I’d like a ComponentGroup to automatically stretch fill up the space (eg the width of the Form). I’ve tried various ways, e.g. enclosing it in a BoxLayout.y but haven’t found a way that works. Anyone …​\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-33/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-33/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis has been a very busy week, we published new information on the \u003ca href=\"/blog/properties.html\"\u003eproperties approach\u003c/a\u003e\u003cbr\u003e\nwhich I’m excited about but I’m not sure if I can drum up your enthusiasm…​\u003cbr\u003e\nSteve made a \u003ca href=\"/blog/connecting-to-a-mysql-database.html\"\u003ebig post\u003c/a\u003e about mysql support too.\u003c/p\u003e\n\u003cp\u003eTodays library update includes \u003ca href=\"/blog/fail-fast-margin-padding-performance.html\"\u003enew simulator code\u003c/a\u003e that might\u003cbr\u003e\nbreak some apps if you’ve refactored stuff around so be vigilant and let us know if something suddenly stops working.\u003c/p\u003e\n\u003cp\u003eOn stack overflow things were as usual:\u003c/p\u003e","title":"Questions of the Week 33"},{"content":"\nIn the following series of blog posts I’m going to shift some attention to server-side development in so much as it can complement a Codename One client application. In this post I’ll demonstrate how you can combine a MySQL database, a web-service layer, and a Codename One client to produce a \u0026ldquo;Contacts\u0026rdquo; app. I’m going to steal the Contacts code from the Kitchen Sink demo for the UI, but I’ll implement a different datasource that loads the contacts from a remote MySQL database instead of from the phone’s internal contacts.\nRequirements I’ll be using Xataface (which is built with PHP) for the web service, and MySQL for the database, so I’ll need to have a LAMP stack installed on my server with PHP 5 or higher, and MySQL 5 or higher. For development, I am going to use XAMPP because it provides everything with a simple installer – and it works on both Mac and Windows. If you’re on Linux, then it’s arguably easier – but I won’t cover it here. I’m using a Mac OS X development machine.\n__ While I am using a PHP-based solution for the web service, this tutorial doesn’t require you to have any knowledge of PHP, and, in fact, doesn’t involve a single line of PHP code. The Database For my database I’m going to use the Sakila sample database provided by MySQL. This database models a video rental store, including such aspects as customer information, staff info, film info, and actor info. The schema is as follows (schema taken from here):\nAs you can see, this database includes much more than contact information, but our app will focus only on contact info. This is actually quite a typical scenario for a mobile app. I frequently create ad-hoc mobile apps that consume specific parts from the data source in order to help with testing of the main app. Mobile apps, in my experience, work quite well when they are focused on doing one task well, rather than doing a whole bunch of tasks as you would expect in a desktop application.\nSo in this case, you can imagine that the store owners might want an app to help keep track of the contacts in the system. That is the app we will build here.\nInstalling the Database I’ll be using the mysql command-line client that is installed at /Applications/XAMPP/bin/mysql on my development machine. If yours is installed elsewhere then you’ll adjust your commands accordingly.\nFirst, download the Sakila database from here. (Link obtained from this page in case the direct link becomes broken later for some reason).\nWhen you extract the archive, you’ll find two SQL files:\nsakila-schema.sql – This contains the database schema.\nsakila-data.sql – This contains the sample data\nWe’ll install both into our database with the following commands.\n$ mysql -u root -p \u0026lt; sakila-schema.sql $ mysql -u root -p \u0026lt; sakila-data.sql Once these have executed, you should be able to log into mysql and see see the tables listed:\n$mysql -u root -p USE sakila; Database changed SHOW TABLES; +----------------------------+ | Tables_in_sakila | +----------------------------+ | actor | | address | | category | | city | | country | | customer | | customer_list | | film | | film_actor | | film_category | | film_list | | film_text | | inventory | | language | | nicer_but_slower_film_list | | payment | | rental | | sales_by_film_category | | sales_by_store | | staff | | staff_list | | store | +----------------------------+ 22 rows in set (0.00 sec) SELECT COUNT(*) FROM film; +----------+ | COUNT(*) | +----------+ | 1000 | +----------+ 1 row in set (0.02 sec) SELECT COUNT(*) FROM film_text; +----------+ | COUNT(*) | +----------+ | 1000 | +----------+ 1 row in set (0.00 sec) The Web Service For the web service layer, I’m going to use Xataface because it requires about the least amount of configuration necessary for us to connect to a MySQL data source over HTTP.\nDISCLAIMER: I am the creator of Xataface. I developed and released the original version in 2005, and have used it on countless apps since that time. It is useful setting up an administration interface for a MySQL database quickly.\nThere are a few different ways to set up a Xataface application. The fastest, easiest way is using the Xataface Yeoman generator.\n__ You’ll need to have NodeJS and Yeoman installed on your development machine to use the Yeoman generator. Don’t worry, they will probably be the most painless installs you ever have to do. Setting up the Xataface App Open a command prompt and navigate to a web-accessible directory. In my case, I’m using XAMPP which stores the web documents in /Applications/XAMPP/htdocs, so that is where I will go:\n$ cd /Applications/XAMPP/htdocs At the prompt type:\n$ yo xataface sakila __ If your mysql binary is not in your environment PATH you’ll need to provide it via that --mysql option. Similarly if git is not in your environment path you’ll need to provide the --git option. The above command basically says \u0026ldquo;create a Xataface application in the directory named ‘sakila\u0026rsquo;\u0026rdquo;.\nNow, follow the prompts:\nFirst it will ask you for some database connection information.\n? MySQL Hostname localhost ? App Database Name sakila ? App Database Username sakila ? App Database Password ******** In our case the database host is localhost, the database name is \u0026ldquo;sakila\u0026rdquo;, and we are going to generate a user for this application named \u0026ldquo;sakila\u0026rdquo; with password \u0026ldquo;password\u0026rdquo; that has full access to the \u0026ldquo;sakila\u0026rdquo; database.\nNext it will ask us which tables to include in the main menu. This is only used by the web interface for the app, which is beyond the scope of this tutorial. We are merely using Xataface as a thin web-service layer to enable our Codename One app to query the database. Nonetheless, we need to include at least one table here, so we’ll add the \u0026ldquo;customer\u0026rdquo; table to the main menu.\n? List the tables that should be included in the main menu in the form: table1=L abel1,table2=Label2, etc... customer=Customers Next it will ask us about our authentication and permission preferences. Xataface provides a rich multi-user authentication and permissions system that will allow to decide exactly who can access what. This generator will setup the the default table-based authentication and add a \u0026ldquo;users\u0026rdquo; table to the database if you choose (and we will choose to do so). By default there are 3 levels of user accounts:\nADMIN\nUSER\n\u0026lt;NONE\u0026gt; (i.e. not logged in).\nBy default, ADMIN users can access everything, regular users can access everything, but in a read-only fashion, and the public (i.e. not logged in) can access nothing.\nDefault settings authentication are as follows: Table-based authentication with Users table definition: create table if not exists `users` ( `username` VARCHAR(100) NOT NULL PRIMARY KEY, `password` VARCHAR(64) NOT NULL, `role` ENUM('USER','ADMIN') DEFAULT 'USER', `email` VARCHAR(255) NOT NULL, UNIQUE KEY (`email`)); With sha1 encryption on the password field. ADMIN users are granted ALL permissions, logged in users are granted READ ONLY permissions, and the public (i.e. not logged-in users) are granted NO ACCESS. ? Would you like to use these default authentication settings? Yes At this point it will create the \u0026ldquo;sakila\u0026rdquo; directory and set up some of the scaffold file structure for the application.\nCloning xataface into /Applications/XAMPP/xamppfiles/htdocs/sakila Cloning into '/Applications/XAMPP/xamppfiles/htdocs/sakila/xataface'... remote: Counting objects: 11025, done. remote: Compressing objects: 100% (46/46), done. remote: Total 11025 (delta 23), reused 0 (delta 0), pack-reused 10979 Receiving objects: 100% (11025/11025), 16.87 MiB | 5.01 MiB/s, done. Resolving deltas: 100% (6630/6630), done. Checking connectivity... done. Checking out files: 100% (2458/2458), done. Copying .htaccess file Copying .htaccess file to templates_c Now it will ask us about modifications that need to be made to the databse.\n? Create the database sakila now? No ? Create the user sakila now? Yes ? Grant permissions to sakila now? Yes This generator needs to execute some SQL commands that require MySQL root permissions. This may include things like creating a database for the app, creating a MySQL user for the app to access the database or granting permissions to a MySQL user for the app to access the database. This username will not be used by the app itself and will not be stored anywhere. It is just for the purpose of setting up the app initially. ? Root MySQL Username root ? Create the table users now? Yes We told the generator to create a \u0026ldquo;users\u0026rdquo; table to store user accounts, but we haven’t added any user accounts yet. Next, the generator will allow us to enter a first \u0026ldquo;admin\u0026rdquo; account.\n? Insert Admin user in users table? Yes ? Admin username admin ? Admin password ******** ? Admin Email Address [[email protected]](/cdn-cgi/l/email-protection) Now, after running some SQL commands, the application should be set up.\nThe app has been successfully created at /Applications/XAMPP/xamppfiles/htdocs/sakila To verify that the app was set up correctly, we’ll point our web browser to the application. In my case the application is located at http://localhost/sakila\nIf all went well you should see a login form similar to the image below:\nYou should also verify that your admin user was set up correctly, but trying to log in on this form. You should see a list of customers:\nThe Client App On the client side, I’m going to use the CN1Xataface library to connect to the Xataface-powered web service that we just set up. Here is a redacted program listing of the entire app:\npackage com.mycompany.myapp; // ... redacted imports ... import com.xataface.query.XFClient; import com.xataface.query.XFQuery; import com.xataface.query.XFRecord; import com.xataface.query.XFRowSet; // ... redacted imports /** * This file was generated by \u0026lt;a href=\u0026quot;https://www.codenameone.com/\u0026quot;\u0026gt;Codename One\u0026lt;/a\u0026gt; for the purpose * of building native mobile applications using Java. */ public class MySQLContactsDemo { private Form current; private Resources theme; // redacted member declarations // Database Connection Properties private XFClient client; // ... redacted Style utility methods // Lifecycle Methods ------------------------------------------------------- public void init(Object context) { // redacted boilerplate init stuff ... client = new XFClient(\u0026quot;http://localhost/sakila/index.php\u0026quot;); __**(1)** } public void start() { if(current != null){ current.show(); return; } Form hi = new Form(\u0026quot;Contacts\u0026quot;); hi.setLayout(new BorderLayout()); hi.show(); // Wrap loading of contacts in callSerially so that it happens after the form // is shown.... Display.getInstance().callSerially(()-\u0026gt;{ loadContacts(rowset-\u0026gt;{ __**(2)** hi.addComponent(BorderLayout.CENTER, createContactsList(hi, rowset)); }); }); } public void stop() { // redacted boilerplate ... } public void destroy() { } // Web Service Methods ----------------------------------------------------- /** * Loads all of the contacts from the database asynchronously. On complete * the callback will be called with the resulting rowset as a parameter, or * null if there was an error. * @param callback Callback to handle the received rowset. */ private void loadContacts(SuccessCallback\u0026lt;XFRowSet\u0026gt; callback) { __**(3)** XFQuery q = new XFQuery(\u0026quot;customer\u0026quot;) .sort(XFQuery.SortOrder.ASCENDING, \u0026quot;last_name\u0026quot;) .select(\u0026quot;first_name\u0026quot;, \u0026quot;last_name\u0026quot;, \u0026quot;email\u0026quot;) .findAll(); client.find(q, callback); } /** * Convert a record from the \u0026quot;contact\u0026quot; table into a Contact object. * @param record A record from the \u0026quot;contact\u0026quot; table. * @return A Contact object */ private static Contact createContact(XFRecord record) { __**(4)** Contact c = new Contact(); c.setFirstName(record.getString(\u0026quot;first_name\u0026quot;)); c.setFamilyName(record.getString(\u0026quot;last_name\u0026quot;)); c.setPrimaryEmail(record.getString(\u0026quot;email\u0026quot;)); return c; } /** * Convert a rowset (from the contact table) into an array of Contact * objects * @param rowset A rowset from the contact table. * @return An array of Contact records. */ private static Contact[] rowsetToContactsArray(XFRowSet rowset) { __**(5)** List\u0026lt;Contact\u0026gt; lst = new ArrayList\u0026lt;Contact\u0026gt;(); for (XFRecord record : rowset) { lst.add(createContact(record)); } return lst.toArray(new Contact[lst.size()]); } // View Factory Methods ---------------------------------------------------- /** * Creates a list of contacts included in the specified rowset. * @param parentForm The parent form * @param rowset The rowset to encapsulate (from the \u0026quot;contact\u0026quot; table) * @return A container to be added to the form. */ private Container createContactsList(Form parentForm, XFRowSet rowset) { Contact[] contacts = rowsetToContactsArray(rowset); // redacted image generation code ... // Create the parent container final Container contactsDemo = new Container(BoxLayout.y()); contactsDemo.setScrollableY(true); // Add all of the rows to the container for(Contact c : contacts) { Container row = createContactRow(c, contactsDemo); if (row != null) { contactsDemo.add(row); } } contactsDemo.revalidate(); finishedLoading = true; // XFClient won't load the whole set all at once because that would be a waste of // network traffic. Default batch size is 30. We use InfiniteScrollAdapter // to load more of the result set as the user scrolls down the list. // Store reference to the last loaded rowset. We can use this // to obtain the \u0026quot;next\u0026quot; rowset, the next time the infinite scroll adapter // is fired. XFRowSet[] lastSet = new XFRowSet[]{rowset}; InfiniteScrollAdapter.createInfiniteScroll(contactsDemo, () -\u0026gt; { // Check if we have have already loaded all of the records in the found set. if (lastSet[0].getFound() \u0026gt; lastSet[0].getLast()) { // Use the previous rowset to get the query to obtain the next result set. XFQuery nextQuery = lastSet[0].getQuery().getNextQuery(); __**(6)** // Pass the query to the client to load the next result set asynchronously client.find(nextQuery, newResult -\u0026gt; { if (newResult == null) { return; } List\u0026lt;Component\u0026gt; toAdd = new ArrayList\u0026lt;Component\u0026gt;(); for (XFRecord row : newResult) { Container cntRow = createContactRow(createContact(row), contactsDemo); if (cntRow != null) { toAdd.add(cntRow); } } InfiniteScrollAdapter.addMoreComponents(contactsDemo, toAdd.toArray(new Component[toAdd.size()]), newResult.getLast() \u0026lt; newResult.getFound()); // Make sure to store this new result set as lastSet so that the next time // we load records we continue where we left off lastSet[0] = newResult; contactsDemo.revalidate(); }); } }); return contactsDemo; } /** * Creates a single row for the contact list that encapsulates the provided * contact. * @param c The contact to represent with this row. * @param parent The parent container to which the row is to be added. This method doesn't actually add the * row to the parent, but it does need to reference it for some of the listeners that are added to the row. The caller * should add the resulting row to the parent after calling this method. * @return A container encapsulating the row, or null if the contact didn't have a name. */ private Container createContactRow(Contact c, Container parent) { // redacted... no Database-specific code here. } } __1 Initialize the client __2 Load the contacts from Xataface Asynchronously __3 The method that loads the contacts. Simply wraps an XFQuery that is submitted to the client. __4 Utility method to convert an XFRecord into a Contact object __5 Utility method to convert XFRowSet into an array of Contact objects. __6 Use the getNextQuery() method to easily load the next batch of records. If you run the app in the Codename One simulator, it will look something like this:\nThe full program listing can be found here.\nIn redacting non-database-related sections from this program listing, I’m hoping to highlight just how easy it is to integrate data from our MySQL database into our Codename One app. All database requests are handled by the XFClient class which includes your basic CRUD methods:\n// Perform async query on db to retrieve rowset public void find( XFQuery query, SuccessCallback\u0026lt;XFRowSet\u0026gt; callback ); // Save record asynchronously public void save( XFRecord record, SuccessCallback\u0026lt;XFRecord\u0026gt; callback ); // Delete record asynchronously public void delete( XFRecord record, SuccessCallback\u0026lt;Boolean\u0026gt; callback ); In our app we created a new client inside the init() method:\nclient = new XFClient(\u0026quot;http://localhost/sakila/index.php\u0026quot;); __ We used the localhost address to the Xataface app, which will only work when we are running in the simulator on the same machine as the server. If you want to test on device, you’ll need to use an address that is reachable from the device. You should be able to check your computer’s network settings to see what your machine’s LAN address is (e.g. \u0026ldquo;192.0.0.8\u0026rdquo;, or \u0026ldquo;steves-imac.local\u0026rdquo;). And ultimately when you deploy your app to production, you’ll use the \u0026ldquo;real\u0026rdquo; server address that should be accessible over the entire internet. Authentication Notice that we didn’t include any username or password information in our client. The XFClient class does include setUsername() and setPassword() methods, but we’ve omitted them here to allow the end user to enter their own account. The first time we run our app, it will prompt the user with a login dialog:\nThe nice thing about allowing the user to log in, is it allows you to customize the permissions on a per-user basis on the server side. For my demo, I only created a single ADMIN account, but you are also able to add more limited accounts that only have access to certain tables, fields, or rows from certain tables.\nBuilding the Queries Database queries are encapsulated by the XFQuery class. Queries are always targeted on a single table. You can provide many types of filters on the results including, but not limited to:\nExact matches\nPartial matches\nRange matches (less than, greater than, less than or equal, greater than or equal, or in a range)\nFull-text, multi-column matches.\nIn our app the query that we used was:\nXFQuery q = new XFQuery(\u0026quot;customer\u0026quot;) __**(1)** .sort(XFQuery.SortOrder.ASCENDING, \u0026quot;last_name\u0026quot;) __**(2)** .select(\u0026quot;first_name\u0026quot;, \u0026quot;last_name\u0026quot;, \u0026quot;email\u0026quot;) __**(3)** .findAll(); __**(4)** client.find(q, callback); __1 Specifies query on the customer table __2 Sort results ascending by last name. __3 Include only the first_name, last_name, and email fields in the results. __4 Find all matches (as opposed to findOne() which will only fetch the first match. If we omit the select() call, it will just include all of the columns of the table in our result set. But this is a waste of bandwidth since we only need those 3 fields. It is also worth noting that we are only sorting on one column (last_name) here but we could chain multiple sort() calls into the query in order to sort on multiple fields.\nLet’s take a look at a few examples of how we could customize our query to get different results:\nFilter on last_name\nOnly include results with last name \u0026ldquo;Smith\u0026rdquo;\nq.matches(\u0026quot;last_name\u0026quot;, \u0026quot;Smith\u0026quot;); This would match \u0026ldquo;Smith\u0026rdquo; but not \u0026ldquo;Smithers\u0026rdquo;\nIf you want to match \u0026ldquo;Smith\u0026rdquo; or \u0026ldquo;Smithers\u0026rdquo; we could do:\nq.contains(\u0026quot;last_name\u0026quot;, \u0026quot;Smith\u0026quot;); This would match \u0026ldquo;Smith\u0026rdquo;, \u0026ldquo;Smithers\u0026rdquo;, or \u0026ldquo;Sexsmith\u0026rdquo;. If we wanted to exclude \u0026ldquo;Sexsmith\u0026rdquo; we could do something like:\nq.like(\u0026quot;last_name\u0026quot;, \u0026quot;Smith%\u0026quot;); Or something a little more commonly practical, if we wanted only those contacts whose last name begins with \u0026ldquo;S\u0026rdquo;:\nq.like(\u0026quot;last_name\u0026quot;, \u0026quot;S%\u0026quot;); __ We could achieve the same effect with q.in(\u0026quot;S\u0026quot;, \u0026quot;SZZZZZZ\u0026quot;) Filter on Dates\nSuppose we were only interested in customers that had been modified in the past day:\nCalendar cal = Calendar.getInstance(); cal.add(Calendar.DATE, -1); q.greaterThan(\u0026quot;modified\u0026quot;, cal.getTime()); Xataface supports many querying features not listed here. For more detailed information see the cn1-xataface docs.\nUsing MySQL Views One limitation of the XFQuery class is that queries are always only performed on a single table. What if you need to perform a more complex query that spans across multiple tables, as is a common requirement of datbase applications. The easiest solution is to create a view in your database that contains all of the data you need, and then query that. For example, in our application we used the customer table which included only the customer name and email address. However, the database stores quite a bit of information about the customer in other tables. Of interest are the customer’s address and phone number for an app like this, and the database designers provided a nice view that includes all of this information:\nCREATE VIEW `customer_list` AS select `cu`.`customer_id` AS `ID`, concat(`cu`.`first_name`,_utf8' ',`cu`.`last_name`) AS `name`, `a`.`address` AS `address`, `a`.`postal_code` AS `zip code`, `a`.`phone` AS `phone`, `city`.`city` AS `city`, `country`.`country` AS `country`, if(`cu`.`active`,_utf8'active',_utf8'') AS `notes`, `cu`.`store_id` AS `SID` from (( (`customer` `cu` join `address` `a` on((`cu`.`address_id` = `a`.`address_id`))) join `city` on((`a`.`city_id` = `city`.`city_id`))) join `country` on((`city`.`country_id` = `country`.`country_id`) )) Xataface will allow you to query a view just as if it were a regular table, except that you need to add a tiny bit of configuration to let it know what the primary key of the view is.\nJust to get you started down this path, let’s open the terminal and navigate to the sakila directory that we created for our app:\n$ cd /Applications/XAMPP/htdocs/sakila Now we’ll create a \u0026ldquo;fields.ini\u0026rdquo; file for the \u0026ldquo;customer_list\u0026rdquo; table (er view) at tables/customer_list/fields.ini.\n$ mkdir tables/customer_list $ touch tables/customer_list/fields.ini And inside the fields.ini file we place:\n[ID] Key=PRI This configuration marks the ID field as the primary key of the customer_list view.\nNow we can use the customer_list view from our Codename One app as if it were a regular table.\nTry out the App For your convenience, I have published the app on a development server so that you can try it out yourself. I have removed the \u0026ldquo;admin\u0026rdquo; user and added a read-only account. You should log in with:\nUsername: demo, Password: demo (case sensitive)\nXataface Admin Back-end\nContacts Demo (The Codename One app built using the Javascript port).\nDownload the .war file of the JS version and install/run it in your own servlet container.\nDownload APK for Android\nResources The CN1Xataface cn1lib\nThe Full Source Code of the server-side portion of this tutorial\nThe Full Source of the client app portion of this tutorial\nThe Xataface Website\nArchived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nToby Mundy — December 1, 2016 at 10:02 pm (permalink) I followed the tutorial but could not get the server setup properly. All appeared to go well but when I pointed the web browser at http://localhost/sakila to test the server setup I just got the following error in the browser:\nWarning: mysqli_connect(): (HY000/1045): Access denied for user ‘sakila’@’localhost’ (using password: YES) in C:xampphtdocssakilaxatafacexfdbdriversmysqli.php on line 4\nWarning: mysqli_error() expects exactly 1 parameter, 0 given in C:xampphtdocssakilaxatafacexfdbdriversmysqli.php on line 17\nFatal error: Uncaught exception ‘Exception’ with message ‘Error connecting to the database: ‘ in C:xampphtdocssakilaxatafaceDatafaceApplication.php:608 Stack trace: #0 C:xampphtdocssakilaxatafaceDatafaceApplication.php(1081): Dataface_Application-\u0026gt;Dataface_Application(NULL) #1 C:xampphtdocssakilaxatafacepublic-api.php(58): Dataface_Application::getInstance(NULL) #2 C:xampphtdocssakilaindex.php(4): df_init(‘C:\\xampp\\htdocs…’, ‘xataface’) #3 {main} thrown in C:xampphtdocssakilaxatafaceDatafaceApplication.php on line 608\nshannah78 — December 2, 2016 at 4:23 am (permalink) It appears that the database user wasn’t created properly. Check the conf.db.ini file. It should list the username and password that it is trying to connect with. Then ensure that mysql has that user.\nIf you need to add the user \u0026ldquo;username\u0026rdquo; with password \u0026ldquo;password\u0026rdquo; in mysql you can do it with:\ncreate user ‘username’@localhost identied by ‘password’;\ngrant all privileges to on sakila.* to username@localhost;\nflush privileges;\nToby Mundy — December 2, 2016 at 1:11 pm (permalink) Thanks, I had not added mysql to environment PATH.\nRudy Lemaitre — February 8, 2017 at 3:18 pm (permalink) Hi all,\ni have juste a question for the lib.\nI have copy / past the lib cn1-xtaface.cn1lib in my lib folder in eclipse project, i build the path.\nAfter i create importe the lib and create the private XFClient client, but eclipse note know the lib and methode.\nCan you help me ?\nthanks for your help\nsorry for my english\nthanks\nshannah78 — February 8, 2017 at 4:43 pm (permalink) Did you refresh cn1libs in your project after adding the cn1-xataface.cn1lib? Note: You can also install it via Codename One settings (in extensions). But you’d still need to to the refresh cn1libs step after that.\nRudy Lemaitre — February 8, 2017 at 6:14 pm (permalink) Rudy Lemaitre says:\nHi restart Eclipse, it’s the same ?\nI try refresh tomorrow, thanks\nRudy Lemaitre — February 9, 2017 at 8:30 am (permalink) Rudy Lemaitre says:\nhello,\ni refresh but it’s the same https://uploads.disquscdn.c…\nRudy Lemaitre — February 9, 2017 at 10:44 am (permalink) Rudy Lemaitre says:\nit\u0026quot;s ok now\ni make a new install of eclispe and works now 🙂\nthanks 😉\nChris — April 10, 2017 at 8:10 pm (permalink) Chris says:\nI’m new to this – do I need to install Xataface on my web server, or just as part of the app?\nshannah78 — April 11, 2017 at 3:58 pm (permalink) shannah78 says:\nXataface goes on your web server.\nChris — April 11, 2017 at 4:09 pm (permalink) Chris says:\nThanks – I use webspace from x10hosting, so presumably I can’t install Xataface on there? Or is it possible to do it when you are renting webspace?\nshannah78 — April 12, 2017 at 4:40 pm (permalink) shannah78 says:\nYes. You can use Xataface on any host that has PHP and MySQL. The instructions in this article assume you have your own server (or have shell access and server has npm installed). But you can also just upload xataface manually to your webspace. Here are some manual install instructions: http://xataface.com/wiki/Ho…\nBrutus — April 27, 2017 at 1:17 pm (permalink) Brutus says:\nHi steve can you please also give an example of how to upload a file thanks!\nShai Almog — April 28, 2017 at 5:24 am (permalink) Shai Almog says:\nhttps://www.codenameone.com…\nPawan Jain — September 13, 2020 at 8:01 pm (permalink) Pawan Jain says:\nHi,\nI am trying to create this project. I have successfully created and configured on server side and able to login and connect to Sakila database and fetch customers.\nHowever, I am facing issues when trying to set up codename one client in Eclipse (Oxygen). I have set up the project correctly, and also copied the cn1-xataface.cn1lib in lib folder and refreshed lib. I still continue to see errors – the following import statements continue to fail:\nimport com.xataface.query.XFClient;\nimport com.xataface.query.XFQuery;\nimport com.xataface.query.XFRecord;\nimport com.xataface.query.XFRowSet;\nAlso tried reboot my PC but still the same issue.\nMy codename one setup is correct that I can create simple demo Apps and run.\nAny suggestions please?\nThanks, Pawan\nSteve Hannah — September 16, 2020 at 9:52 pm (permalink) Steve Hannah says:\nIt sounds like it is having issues refreshing the xataface cn1lib. Try again, going through the cycle of \u0026ldquo;Codename One\u0026rdquo; \u0026gt; \u0026ldquo;Refresh Cn1libs\u0026rdquo;. Then a clean build. Check the \u0026ldquo;lib/impl/cls\u0026rdquo; directory (which is where the cn1lib classes get extracted to when they are installed), and ensure that the specified classes are there.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/connecting-to-a-mysql-database/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/connecting-to-a-mysql-database/connecting-mysql-to-codenameone.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIn the following series of blog posts I’m going to shift some attention to server-side development in so much as it can complement a Codename One client application. In this post I’ll demonstrate how you can combine a MySQL database, a web-service layer, and a Codename One client to produce a \u0026ldquo;Contacts\u0026rdquo; app. I’m going to steal the Contacts code from the Kitchen Sink demo for the UI, but I’ll implement a different datasource that loads the contacts from a remote MySQL database instead of from the phone’s internal contacts.\u003c/p\u003e","title":"Connecting to a MySQL Database from Codename One"},{"content":"\nOne of the frustrating parts in Codename One is builds failing in the cloud, the expectation is that a build that passes\nlocally would pass in the cloud and that is something we strive to have at all times. One of the more common\nfailures for new developers is due to refactoring of the main class or changing the signatures of the methods\ne.g. adding a throws clause to start().\nStarting with the next library update when you run a project it will use the main class defined in codenameone_settings.properties\nand not the one in the Run arguments. This means that developers who refactored a class will instantly see\nthis failing in the simulator before sending the build and would realize they did something wrong.\nWe will also fail if start() or one of the other methods in the main class declares a throws clause. This happens\na lot of times because new developers use IDE auto-correct suggestions and add a such a clause automatically.\nHopefully existing/working applications won’t be impacted by this…​\nFaster Margin/Padding Up until recently the official way to get the padding/margin of a component was something like this:\nint paddingLeft = style.getPadding(cmp.isRTL(), Component.LEFT); That seems simple enough but there are a lot of hidden problems here. Normally this wouldn’t be a big deal but\nboth padding and margin are used in performance critical paths for rendering which impacts performance directly.\n__ | Performance critical paths are places in the code that can be invoked 60 times per second e.g. in the\npainting logic, they must be really fast The get padding method is implemented like this:\npublic int getPadding(boolean rtl, int orientation) { int v = getPaddingValue(rtl, orientation); return convertUnit(paddingUnit, v, orientation); } public int getPaddingValue(boolean rtl, int orientation) { if (orientation \u0026lt; Component.TOP || orientation \u0026gt; Component.RIGHT) { throw new IllegalArgumentException(\u0026quot;wrong orientation \u0026quot; + orientation); } if (rtl) { switch(orientation) { case Component.LEFT: orientation = Component.RIGHT; break; case Component.RIGHT: orientation = Component.LEFT; break; } } return padding[orientation]; } I’ll skip the convertUnit call since that’s pretty much fixed but as you can see there are several problems:\nWe will always have an if on RTL even if we don’t need it. We don’t always need it e.g. in the case for\ntop/bottom or a case where we need both left \u0026amp; right\nWe need to check that the orientation is valid\nWe have a redundant method call to the value method\nAll of these get compounded for cases where we need 2 orientations at once\nTo solve these issues we replaced thru out the entire code all usage of these methods with these:\npublic int getPaddingLeft(boolean rtl); public int getPaddingRight(boolean rtl); public int getPaddingTop(); public int getPaddingBottom(); public int getPaddingLeftNoRTL(); public int getPaddingRightNoRTL(); public int getHorizontalPadding(); public int getVerticalPadding(); We did the same for margin which I’m not listing here as it is practically identical. As you can see from the implementation\nof getPaddingLeft it is much faster/smaller than getPadding :\npublic int getPaddingLeft(boolean rtl) { if (rtl) { return convertUnit(paddingUnit, padding[Component.RIGHT], Component.RIGHT); } return convertUnit(paddingUnit, padding[Component.LEFT], Component.LEFT); } The other methods provide similar optimizations that should align across the board.\nThe performance difference probably won’t be noticeable for most use cases. However I still think there is value\nin understanding this. If you understand this change you can look for similar problematic usages in your code\nand also within ours. When a method is deep enough within the call stack it becomes invisible to profilers and\nwe no longer see it. It’s important to challenge that and inspect the low level implementations especially if they have\nbeen in the code for years. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nLinsong Wang — December 1, 2016 at 5:57 pm (permalink) Linsong Wang says:\nOne request for this codenameone_settings.proper… file: please do not automatically update the timestamp in the comment lines at the top of file, or remove comments completely. And, please keep a defined order of these properties.\nThe constant change of this file (even there is no real content change) causes headache when team members work together with one git repo.\nShai Almog — December 2, 2016 at 5:30 am (permalink) Shai Almog says:\nThat’s a great idea, it was annoying to me too but I didn’t think of a solution until you asked… The problem is that we use java.util.Properties which uses Hashtable and is effectively broken in that sense. I can probably adapt this http://stackoverflow.com/qu… to use globally and keep a consistent order.\nWe’ll still need to update the libVersion but it would make merging easier.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/fail-fast-margin-padding-performance/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/fail-fast-margin-padding-performance/phone-espresso.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the frustrating parts in Codename One is builds failing in the cloud, the expectation is that a build that passes\u003cbr\u003e\nlocally would pass in the cloud and that is something we strive to have at all times. One of the more common\u003cbr\u003e\nfailures for new developers is due to refactoring of the main class or changing the signatures of the methods\u003cbr\u003e\ne.g. adding a throws clause to \u003ccode\u003estart()\u003c/code\u003e.\u003c/p\u003e","title":"Fail Fast \u0026 Margin/Padding Performance"},{"content":"\nWe usually just add a new feature and then tell you about it in these posts but properties is a special case and this\npost is intended not just as a tutorial but as a solicitation of feedback…​\nWe committed properties as a deprecated API because we aren’t\nsure yet. This could be a very important API moving forward and we want as much peer review as possible over this.\nWhat are Properties? In standard Java we usually have a POJO (Plain Old Java Object) which has getters/setters e.g. we can have a\nsimple Meeting class like this:\npublic class Meeting { private Date when; private String subject; private int attendance; public Date getWhen() { return when; } public String getSubject() { return subject; } public int getAttendance() { return attendance; } public void setWhen(Date when) { this.when = when; } public void setSubject(String subject) { this.subject = subject; } public void setAttendance(int attendance) { this.attendance = attendance; } } That’s a classic POJO and it is the force that underlies JavaBeans and quite a few tools in Java.\nThe properties are effectively the getters/setters e.g. subject, when etc. but properties have several features\nthat are crucial:\nThey can be manipulated in runtime by a tool that had no knowledge of them during compile time\nThey are observable – a tool can monitor changes to a value of a property\nThey can have meta-data associated with them\nThese features are crucial since properties allow us all kinds of magic e.g. hibernate/ORM uses properties to bind\nJava objects to a database represenation, jaxb does it to parse XML directly into Java objects and GUI builders\nuse them to let us customize UI’s visually.\nPOJO’s don’t support most of that so pretty much all Java based tools use a lot of reflection \u0026amp; bytecode manipulation.\nThis works but has a lot of downsides e.g. say I want to map an object both to the Database and to XML/JSON.\nWould the bytecode manipulation collide?\nWould it result in duplicate efforts?\nAnd how do I write custom generic code that uses such abilities? Do I need to manipulate the VM?\nProperties in Java These are all very abstract ideas, lets look at how we think properties should look in Java and how we can\nbenefit from this moving forward.\n__ The code below is preliminary and the syntax/classes might change without warning This is the same class as the one above written with properties:\npublic class Meeting implements PropertyBusinessObject { public final Property\u0026lt;Date,Meeting\u0026gt; when = new Property\u0026lt;\u0026gt;(\u0026quot;when\u0026quot;); public final Property\u0026lt;String,Meeting\u0026gt; subject = new Property\u0026lt;\u0026gt;(\u0026quot;subject\u0026quot;); public final Property\u0026lt;Integer,Meeting\u0026gt; attendance = new Property\u0026lt;\u0026gt;(\u0026quot;attendance\u0026quot;); private final PropertyIndex idx = new PropertyIndex(this, \u0026quot;Meeting\u0026quot;, when, subject, attendance); @Override public PropertyIndex getPropertyIndex() { return idx; } } This looks a bit like a handful so let’s start with usage which might clarify a few things then dig into the class itself.\nWhen we used a POJO we did this:\nMeeting meet = new Meeting(); meet.setSubject(\u0026quot;My Subject\u0026quot;); Log.p(meet.getSubject()); With properties we do this:\nMeeting meet = new Meeting(); meet.subject.set(\u0026quot;My Subject\u0026quot;); Log.p(meet.subject.get()); Encapsulation At first glance it looks like we just created public fields (which we did) but if you will look closely at the declaration\nyou will notice the final keyword:\npublic final Property\u0026lt;String,Meeting\u0026gt; subject = new Property\u0026lt;\u0026gt;(\u0026quot;subject\u0026quot;); This means that this code will not compile:\nmeet.subject = otherValue; So all setting/getting must happen thru the set/get methods and they can be replaced. E.g. this is valid syntax\nthat prevents setting the property to null and defaults it to an empty string:\npublic final Property\u0026lt;String,Meeting\u0026gt; subject = new Property\u0026lt;\u0026gt;(\u0026quot;subject\u0026quot;, \u0026quot;\u0026quot;) { public Meeting set(String value) { if(value == null) { return Meeting.this; } return super.set(value); } }; __ We’ll discuss the reason for returning the Meeting instance below Introspection \u0026amp; Observability Since Property is a common class it’s pretty easy for introspective code to manipulate properties. However,\nit can’t detect properties in an object without reflection.\nThat’s why we have the index object and the PropertyBusinessObject interface (which defines getPropertyIndex).\nThe PropertyIndex class provides meta data for the surrounding class including the list of the properties within.\nIt allows enumerating the properties and iterating over them making them accessible to all tools.\nFurthermore all properties are observable with the property change listener. I can just write this to instantly print\nout any change made to the property:\nmeet.subject.addChangeListener((p) -\u0026gt; Log.p(\u0026quot;New property value is: \u0026quot; + p.get())); The Cool Stuff That’s the simple stuff that can be done with properties, but they can do much more!\nFor starters all the common methods of Object can be implemented with almost no code:\npublic class Meeting implements PropertyBusinessObject { public final Property\u0026lt;Date,Meeting\u0026gt; when = new Property\u0026lt;\u0026gt;(\u0026quot;when\u0026quot;); public final Property\u0026lt;String,Meeting\u0026gt; subject = new Property\u0026lt;\u0026gt;(\u0026quot;subject\u0026quot;); public final Property\u0026lt;Integer,Meeting\u0026gt; attendance = new Property\u0026lt;\u0026gt;(\u0026quot;attendance\u0026quot;); private final PropertyIndex idx = new PropertyIndex(this, \u0026quot;Meeting\u0026quot;, when, subject, attendance); @Override public PropertyIndex getPropertyIndex() { return idx; } public String toString() { return idx.toString(); } @Override public boolean equals(Object obj) { return obj.getClass() == getClass() \u0026amp;\u0026amp; idx.equals(((TodoTask)obj).getPropertyIndex()); } @Override public int hashCode() { return idx.hashCode(); } } This is easy thanks to introspection…​\nWe already have some simple code that can convert an object to/from JSON Maps e.g. this can fill the property\nvalues from parsed JSON:\nmeet.getPropertyIndex().populateFromMap(jsonParsedData); And visa versa:\nString jsonString = meet.toJSON(); We also have a very simple ORM solution that maps values to table columns and can create tables. It’s no hibernate\nbut sqlite isn’t exactly big iron so it might be good enough.\nConstructors One of the problematic issues with constructors is that any change starts propagating everywhere. If I have\nfields in the constructor and I add a new field later I need to keep the old constructor for compatibility.\nSo we added a new syntax:\nMeeting meet = new Meeting(). subject.set(\u0026quot;My Subject\u0026quot;). when.set(new Date()); That is why every property in the definition needed the Meeting generic and the set method returns the Meeting\ninstance…​\nWe are pretty conflicted on this feature and are thinking about removing it.\nWithout this feature the code would look like this:\nMeeting meet = new Meeting(); meet.subject.set(\u0026quot;My Subject\u0026quot;); meet.when.set(new Date()); Is this feature valuable?\nIs it worth the cost of converting this:\npublic class Meeting implements PropertyBusinessObject { public final Property\u0026lt;Date\u0026gt; when = new Property\u0026lt;\u0026gt;(\u0026quot;when\u0026quot;); public final Property\u0026lt;String\u0026gt; subject = new Property\u0026lt;\u0026gt;(\u0026quot;subject\u0026quot;); public final Property\u0026lt;Integer\u0026gt; attendance = new Property\u0026lt;\u0026gt;(\u0026quot;attendance\u0026quot;); To this:\npublic class Meeting implements PropertyBusinessObject { public final Property\u0026lt;Date,Meeting\u0026gt; when = new Property\u0026lt;\u0026gt;(\u0026quot;when\u0026quot;); public final Property\u0026lt;String,Meeting\u0026gt; subject = new Property\u0026lt;\u0026gt;(\u0026quot;subject\u0026quot;); public final Property\u0026lt;Integer,Meeting\u0026gt; attendance = new Property\u0026lt;\u0026gt;(\u0026quot;attendance\u0026quot;); I’m personally conflicted here…​\nFeedback \u0026amp; Summary The reason for this post is feedback, we’d like feedback on all of the above and general thoughts on this.\nIs this something you are interested in?\nWhat features are important to you?\nIs setter based construction a good idea that is worth the compromise?\nDo you have ideas on improving the syntax further? Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nStefan Eder — November 23, 2016 at 9:50 am (permalink) Stefan Eder says:\nI like it a lot – and the fluent inferace via method chaining.\nShai Almog — November 24, 2016 at 6:05 am (permalink) Shai Almog says:\nThanks, that’s helpful!\nOrlando D\u0026rsquo;Free — December 6, 2016 at 12:01 am (permalink) Orlando D\u0026rsquo;Free says:\nVery interesting. I haven’t thought through the implications of returning Meeting (although I tend to like APIs that let me do method chaining), but here’s one thing I’d like to see: PropertyChangeListeners. For example, I might want to add a method, either in class Meeting or a more generic superclass, that looks like this:\npublic void addPropertyChangeListener(String propertyName, PropertyListener listener) {\nidx.addPropertyChangeListener(propertyName, listener);\n}\nThis would work if the PropertyIndex class had a method that added the listener to the appropriate Property object, and if the Property class would fire changes when the setter was called.\nShai Almog — December 6, 2016 at 6:11 am (permalink) Shai Almog says:\nNotice the observability section above:\nmeet.subject.addChangeListener((p) -\u0026gt; Log.p(\u0026ldquo;New property value is: \u0026quot; + p.get()));\nMark Daniel Henning — July 20, 2017 at 5:50 am (permalink) Mark Daniel Henning says:\nQuick question: Is there a concept of a virtual property? For instance, Say I have a PropertyBusinessObject called Length with a Property defined as\npublic final Property\u0026lt;double,length\u0026gt; metre = new Property\u0026lt;\u0026gt;(\u0026ldquo;metre\u0026rdquo;);\nIt would be useful to have a virtual property km such that Length.km.get() would return Length.metre.get() * .001\nand Length.km.set(val) would call Length.metre.set(val * 1000)\nthe PropertyIndex would only include metre so that toJSON would only store the metre value.\nIf not, how would one add methods to the class that would provide a consistent calling pattern?\nShai Almog — July 21, 2017 at 1:32 pm (permalink) Shai Almog says:\nSure that’s pretty important. See: https://gist.github.com/cod…\nNotice I used DoubleProperty instead of Property which has some advantages with things like ORM due to erasures.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/properties/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/properties/properties.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe usually just add a new feature and then tell you about it in these posts but properties is a special case and this\u003cbr\u003e\npost is intended not just as a tutorial but as a solicitation of feedback…​\u003cbr\u003e\nWe committed properties as a deprecated API because we aren’t\u003cbr\u003e\nsure yet. This could be a very important API moving forward and we want as much peer review as possible over this.\u003c/p\u003e","title":"Properties"},{"content":"\nI deal with a lot of questions every day and unfortunately most of them are phrased in a way that forces\nme to guess. There are some guidelines on how to ask a question\nbut I think they are mostly pretty bad. Asking a question \u0026ldquo;correctly\u0026rdquo; helps you tremendously both in getting\na correct answer faster and also in solving your own question. Following these three rules will significantly improve\nyour questions:\nExplain in no more than two sentences what are you really trying to accomplish\nExplain what you tried\nScreenshots, code snippets \u0026amp; error logs are crucial\nWhat are you really trying to accomplish Questions are a form of expressing our lack of knowledge, but when I bring someone else to help with my missing\npieces of knowledge that person is ignorant about me and what I’m trying to do. That’s why every question should\nfirst start with and explanation of what we are trying to do.\nE.g. I can ask a person where is the next pharmacy and he can send me two miles away, but if I ask \u0026ldquo;where can I buy\ngum?\u0026rdquo; he can send me around the block to a convenience store…​\nThis is very applicable to technical questions e.g. developers often ask \u0026ldquo;how can I add a button anywhere in the screen\u0026rdquo;.\nThe answer is \u0026ldquo;it’s problematic and varies\u0026rdquo;.\nA better question would start with \u0026ldquo;I am trying to place a button in the top right portion of the screen similar to this\nimage…​\u0026rdquo;.\n__ If you have an image use it, just make sure to highlight the element within the image you are interested in Explain what you Tried Stackoveflow highlights this requirement and for good reason. It’s not just there to show that you did some work\nbefore poping the question…​\nThis provides us insight into what doesn’t work so we don’t give an answer you already tried. It also provides insight\ninto the direction you are taking so if some things weren’t clear in your description this should seal the deal.\nA good explanation would also include the source URL where you got that information as it might provide further\nclues to why things didn’t work out.\n__ It’s OK to say \u0026ldquo;I don’t even know where to begin\u0026rdquo; or \u0026ldquo;I tried googling XYZ and came up blank\u0026rdquo; Screenshots, Code Snippets \u0026amp; Error Logs I can’t stress enough how important a screenshot is for any question, I’d like to recommend JING\nas it allows us to annotate screeshots very easily with text/arrows/boxes etc.\nThis makes a huge difference for visually oriented questions.\nI get a lot of questions that complain about an error and don’t include the log from the IDE or include a cut version\nof it…​ This is problematic.\nWith source the balance is more delicate, you should include source but this is a fine art. Include too much and\nwe will get lost when reading it. We will end up skimming the source and might miss an important nuance.\nInclude too little and we might not see the problem.\nFinal Word I would have written a shorter letter, but I did not have the time.\n— Blaise Pascal\nOne thing I didn’t get to is the length of the question, that’s because this stops being a tip about question asking\nand becomes a tip about good writing technique which is important but enters a whole new realm.\nThere are plenty of great books about writing and I wholly recommend them, good writing technique will impact\nyour work significantly. It will help you communicate with colleagues, customers and employers effectively. Despite\nthat it’s something that takes more work than these steps above all of which should be relatively trivial.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-how-to-ask-a-question/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-how-to-ask-a-question/just-the-tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI deal with a lot of questions every day and unfortunately most of them are phrased in a way that forces\u003cbr\u003e\nme to guess. There are some guidelines on \u003ca href=\"http://stackoverflow.com/help/how-to-ask\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehow to ask a question\u003c/a\u003e\u003cbr\u003e\nbut I think they are mostly pretty bad. Asking a question \u0026ldquo;correctly\u0026rdquo; helps you tremendously both in getting\u003cbr\u003e\na correct answer faster and also in solving your own question. Following these three rules will significantly improve\u003cbr\u003e\nyour questions:\u003c/p\u003e","title":"TIP: How to Ask a Question"},{"content":"\nI practically had a vacation from blogging these past two weeks with all the great posts from Steve. I’ve put some\nwork into something interesting but it’s not yet ready for prime time. If you follow the git commits you might have\nnoticed we’ll discuss it when we think it’s ready.\nThis week we (thankfully) aren’t releasing a plugin update and just releasing the standard weekly release as usual.\nHopefully, things will cool down a bit and we’ll be able to sprint to the 3.6 release easily.\nOn stack overflow things were as usual:\nCodename one Mock location permission is added, how to remove it? This is a feature we added for a user a while back, we provided a way to disable this in a build hint\nRead on stackoverflow…​\nCodename one project Run issue after it was running It’s important to keep the jars and classpath as they were\nRead on stackoverflow…​\nDetermine how much of a component is visible on screen This is problematic as the abstraction in the hierarchy can’t really tell that, but normally you don’t need to know that…​\nRead on stackoverflow…​\nMultiple image selection from gallery This isn’t supported currently\nRead on stackoverflow…​\nManually Editing Codename One (Old) UI Designer Built Project This is a bit challenging but possible\nRead on stackoverflow…​\nFile chooser dialog We just posted about this in yesterdays blog post\nRead on stackoverflow…​\nHow to call Codenameone java file from a html file? The JavaScript bridge is designed with this exact purpose in mind\nRead on stackoverflow…​\nPassword hide in textfield codenameone Various Android virtual keyboards act oddly sometimes\nRead on stackoverflow…​\nA webBrowser form crashes the app when backed There usually isn’t much we can do against a hard crash in Android unless it’s a known issue and even then…​\nRead on stackoverflow…​\nGetting Uncaught ReferenceError: camera is not defined The simulator can’t handle some of the more advanced HTML capabilities because of limitations in JavaFX\nRead on stackoverflow…​\ncaptureAudio example in codenameone not working on device simulator The simulator doesn’t support actual audio capture only using a file\nRead on stackoverflow…​\nWebBrowser issue (add infinite progress in web browser) Peer components are problematic with things like overlays on top\nRead on stackoverflow…​\nSide menu transition speed This can be controlled via theme constants although more often than not when people complain about this it means\nthe UI has some performance issues\nRead on stackoverflow…​\nGoogle Maps on iOS error: is depending on legacy on-demand authorization, which is not supported for new apps You need to define the iOS location string so positioning will work correctly\nRead on stackoverflow…​\nDownloading a pdf file of larger size(like 30Mb) fails Thre is probably a redirect involved here…​\nRead on stackoverflow…​\nIs it possible with Codename One to display the camera output in real time? Yes and no, at this time this requires native interfaces but it should be very possible\nRead on stackoverflow…​\nCodenameOne GoogleConnect success callback is not triggered on Android This seems to be a regression with the API level 23 migration\nRead on stackoverflow…​\nsend multiple binary files to server This is strait forward\nRead on stackoverflow…​\nRemoving TitleArea from a specific There are some artifacts that require some work to remove/change\nRead on stackoverflow…​\ncodenameone POST request BODY Both should be completely interchangeable in a seamless way\nRead on stackoverflow…​\nDisplay entire json response message not just a single node The answer just requires the removal of a single line of code…​.\nRead on stackoverflow…​\nTo show that the new update is available in app store I hope to blog about a simple method of doing this next week as we’d like to do this to some of our more elaborate deployment scenarios\nRead on stackoverflow…​\nBack from a form to a particular tab – codenameone This should be pretty seamless but often things don’t work as expected in the old GUI builder. In the new one this\njust wouldn’t happen…​\nRead on stackoverflow…​\nCodename one uwp build failed We introduced native interfaces support for UWP which broke some older cn1libs\nRead on stackoverflow…​\nPortrait images are rotated when displayed This is something we need to address…​\nRead on stackoverflow…​\nImplementing a fixed size virtual UI card We have such a UI in serveral demos most notably the kitchen sink\nRead on stackoverflow…​\nHow to call codenameone java class method from javascript? The JavaScript package goes a long way to help with such interaction\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-32/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-32/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI practically had a vacation from blogging these past two weeks with all the great posts from Steve. I’ve put some\u003cbr\u003e\nwork into something interesting but it’s not yet ready for prime time. If you follow the git commits you might have\u003cbr\u003e\nnoticed we’ll discuss it when we think it’s ready.\u003c/p\u003e\n\u003cp\u003eThis week we (thankfully) aren’t releasing a plugin update and just releasing the standard weekly release as usual.\u003cbr\u003e\nHopefully, things will cool down a bit and we’ll be able to sprint to the 3.6 release easily.\u003c/p\u003e","title":"Questions of the Week 32"},{"content":"\nCodename One has always provided access to the device’s photos and videos via Display.openGallery() but it hasn’t provided an API to open arbitrary file types because this type of functionality was not available on most mobile platforms. Times have changed and most platforms now offer support for more than just images and photos, so we decided to provide access to this functionality as a cn1lib. Here is a short introduction to the cn1-filechooser library.\nIntroduction by Example I recently developed an app that provided optical character recognition (OCR) on images and PDFs. As you might expect, an app like this needs to allow the user to select a PDF or an image to be converted by some mechanism. Using Display.openGallery() I could present the user with access to their images, but I also needed them to be able to select PDFs. The cn1-filechooser library comes to the rescue in this case:\nAfter installing the cn1-filechooser library into my project, I added the following snippet to respond to the event where the user taps the \u0026ldquo;open\u0026rdquo; button:\nActionListener callback = e-\u0026gt;{ if (e != null \u0026amp;\u0026amp; e.getSource() != null) { String filePath = (String)e.getSource(); // Now do something with this file } }; if (FileChooser.isAvailable()) { FileChooser.showOpenDialog(\u0026quot;.pdf,application/pdf,.gif,image/gif,.png,image/png,.jpg,image/jpg,.tif,image/tif,.jpeg\u0026quot;, callback); } else { Display.getInstance().openGallery(callback, Display.GALLERY_IMAGE); } The FileChooser.isAvailable() should return true on iOS, Android, Windows 10 (UWP), JavaSE (the Simulator), and Javascript, so it’s almost not necessary. Nonetheless, I do provide a fallback to the standard image gallery in case I happen to later want to build my app on another platform that doesn’t support the file chooser yet.\nNotice that the first parameter to showOpenDialog() is a string with a comma-delimited list of extensions and mimetypes. You can include both mime-types and extensions here. The syntax is designed to be compatible with the HTML file input’s accept attribute.\nScreenshots So let’s see what this looks like on the various platforms:\niOS :\nWhen you open the file chooser it gives you a list of your device’s installed document providers:\nIn my case I have my iCloud drive (everyone will have this), and Dropbox because I have the Dropbox app installed on my phone. But if you have other apps have DocumentProvider extensions, then those will also be listed.\nIt also includes an \u0026ldquo;Images\u0026rdquo; option that allows the user to browse their local images if they have included any \u0026ldquo;image\u0026rdquo; types in the call to showOpenDialog()\n__ On iOS, your App ID must include the iCloud entitlement, so, when you create your app ID in your apple developer account, make sure that you check this option. Android :\nOn android it will open a versatile file chooser that allows you to browse and select files in your Google Drive, local images, Downloads, or on internal storage.\nWindows Phone 10 :\nOn Windows Phone 10, the dialog allows users to browse their OneDrive, or local files.\nDesktop\nIn the desktop builds, the simulator, javascript (on the desktop), and Windows 10 Desktop, you will just see the name file chooser dialog.\nMore Information For more information, you can check out the cn1-filechooser github repo.\nThe best way to install this library is through the Extensions section of Codename One Settings.\nYou can also try out the OCR.net app which uses the cn1-filechooser plugin.\nOCR.net App in iTunes Store\nOCR.net App in Google Play\nOCR.net App in the Windows Store\nArchived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDave Gunawan — November 18, 2016 at 2:56 pm (permalink) for the FileChooser, how do I make it so that it takes all types of file ?\n(instead of just the one listed in the param in example below)\ncom.codename1.ext.filechooser.FileChooser.showOpenDialog(\u0026quot;.pdf,application/pdf,.gif,image/gif,.png,image/png,.jpg,image/jpg,.tif,image/tif,.jpeg\u0026quot;, callback);\nAlso I tried it in Simulator and real Android devices (OnePlus2, Nexus 5) and FileChooser.isAvailable() return false …. ?\nshannah78 — November 18, 2016 at 5:45 pm (permalink) Use \u0026ldquo;/\u0026rdquo; for all mimetypes. Or.. you should be able to just pass null for the type.\nRegarding it returning false in the simulator and on real android devices, there must be a problem in your project’s build.xml file. I’ve responded to your query in Codename One support.\nEDIT: I found that there is a bug in the current release. The Simulator doesn’t support \u0026ldquo;ALL\u0026rdquo; mimetypes right now. I have made some modifications, but it required changes in both the cn1 core and the lib. They’ll be available in the next plugin update. The cn1-filechooser extension is already updated, and all required changes are on GitHub. To get them before the next plugin update, you’ll need to build CN1 from source and use the modified JavaSE.jar in your project.\nStefan Blomen — January 18, 2017 at 11:33 am (permalink) 1.) The UWP build fails if FileChooser is used\n2.) On some versions of Android (maybe \u0026lt; 5) files with extensions unknwon to the system (i.e. \u0026ldquo;test.abc\u0026rdquo;) cannot be opened. The ActionEvent is null in this case. I tried several mime types including \u0026ldquo;/\u0026rdquo;. On an Android device with version 7 it works. Any clues?\nshannah78 — January 18, 2017 at 5:29 pm (permalink) shannah78 says:\n\u0026ldquo;The UWP build fails if FileChooser is used\u0026rdquo;\nI have a couple of UWP apps using the file chooser, and they seem to build and work OK. Please open an issue on this and include a simple test case that I can try.\n\u0026ldquo;On some versions of Android (maybe \u0026lt; 5) files with extensions unknwon to the system (i.e. \u0026ldquo;test.abc\u0026rdquo;) cannot be opened. \u0026quot;\nPlease open an issue on this too so it won’t get lost. All of my test cases so far were for common extensions.\nKai — February 7, 2017 at 1:00 pm (permalink) Kai says:\nIs it possible to use this FileChooser as a directory browser, to specify where I want to store a file from my app?\nShai Almog — February 8, 2017 at 8:35 am (permalink) Shai Almog says:\nNo.\nMobile devices don’t allow that. Notice that if you receive a file from this chooser it might not be the \u0026ldquo;actual file\u0026rdquo; you picked but rather a copy of it within the area that your app is allowed to access.\nFrancesco Galgani — May 7, 2018 at 4:37 pm (permalink) Francesco Galgani says:\nThank you for this library. For anyone that is in trouble on adding the iCloud entitlement to the App Id (maybe because it’s the first time), I suggest to follow these instructions (that helped me):\nhttps://stackoverflow.com/a…\nAnkush Sharma — October 11, 2018 at 9:28 am (permalink) Ankush Sharma says:\nHi, Will this work in unity? Is there any other dependency I should know about? Thanks!\nShai Almog — October 12, 2018 at 4:07 am (permalink) Shai Almog says:\nSee https://help.codenameone.co…\nThomas McNeill — December 26, 2018 at 5:56 pm (permalink) Thomas McNeill says:\nI was hoping to use the document provider to save to google drive or dropbox. Will we ever have this ability?\nShai Almog — December 27, 2018 at 4:28 am (permalink) Shai Almog says:\nThis should be easy to do with native interfaces. Whether we add it depends a lot on user requests. We didn’t get a lot of requests for this feature and no enterprise requests which tend to move things faster.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/native-file-open-dialogs/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/native-file-open-dialogs/file-chooser.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One has always provided access to the device’s photos and videos via \u003ccode\u003eDisplay.openGallery()\u003c/code\u003e but it hasn’t provided an API to open arbitrary file types because this type of functionality was not available on most mobile platforms. Times have changed and most platforms now offer support for more than just images and photos, so we decided to provide access to this functionality as a cn1lib. Here is a short introduction to the cn1-filechooser library.\u003c/p\u003e","title":"Native File Open Dialogs"},{"content":"\nHistorical note: Codename One\u0026rsquo;s UWP target was discontinued in release 7.0.229. This post is preserved for historical context only, and its build/setup instructions no longer apply to current Codename One projects.\nThe next plugin update will add support for native interfaces in UWP. This opens the door for you to really dig into the native features of Windows if you wish to do so. Crucially, this will also allow us to push forward with windows support on some of the cn1libs that require native functionality. As a proof of concept, I have updated the CN1WebSockets library to support windows. It now works on all major platforms: iOS, Android, Javascript, UWP (Windows 10), Simulator, and Desktop builds. If you require sockets in your app, I highly recommend web sockets, as it is the most portable option currently available.\nFor more information about the CN1 Websockets lib, check out my previous blog post on the subject.\nInside the Source of a UWP Native Interface __ This section describes how the C# implementations will look, but you don’t need to memorize this because you can just use the \u0026ldquo;Generate Native Access\u0026rdquo; option in your IDE to generate the basic structure, so you just need to fill in the methods with your implementations. Parameter Types Native interface implementations in UWP are written as C# classes, and the similarities between C# and Java make it very intuitive. C# parameter and return types are all the same as their Java counterparts, except that boolean is named bool in C#. E.g. If your Java Native interface includes a method like:\npublic float multiply(String message, double a, double b, boolean round); Your implementation would look like:\npublic float multiply(string message, double a double b, bool round) { // do the multiplication here.... return result; } Peer Components Peer components should be a subclass of FrameworkElement, but the parameter types and return types will just be object. You would need to cast them to the appropriate object type inside your method.\nE.g. Consider a native interface designed to create a native Label widget. The Java native interface method signature is:\npublic PeerComponent createNativeLabel(String text); And the UWP implementation of this method is:\npublic object createNativeLabel(string text) { Windows.UI.Xaml.Controls.TextBlock textBlock = null; impl.SilverlightImplementation.dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =\u0026gt; { textBlock = new Windows.UI.Xaml.Controls.TextBlock(); textBlock.Text = text; textBlock.Width = 240; textBlock.IsTextSelectionEnabled = true; textBlock.TextWrapping = Windows.UI.Xaml.TextWrapping.Wrap; }).AsTask().ConfigureAwait(false).GetAwaiter().GetResult(); return textBlock; } A couple of things to note on this snippet:\nWe use the TextBlock class for our visual component, which is a subclass of FrameworkElement.\nAll interaction with UI elements in UWP must occur on the main UI thread, which is why it is wrapped in a dispatcher.RunAsync() callback. See the following section on the UI thread for more information.\nThe return type of this method is object.\nSome portions of this snippet require using System; at the beginning of the file.\nThe usage for this method would look something like:\n// ntv = instance of the native interface // hi = a form PeerComponent nativeLabel = ntv.createNativeLabel(\u0026quot;This is a native label\u0026quot;); nativeLabel.setPreferredH(200); hi.add(nativeLabel); The UI Thread Most things in UWP are expected to occur on its main UI thread. This is especially the case when you are working with UI elements. The easiest way to run code on the UI thread is via the com.codename1.impl.SilverlightImplementation.dispatcher.RunAsync() method, as shown in the snippet above. This will run the code asynchronously. If you need to wait for the result of some code that occurs in this callback, as we did in the example above, then you can chain RunAsync().AsTask().GetAwaiter().GetResult();. This will effectively run your code synchronously.\n__ .AsTask() is only available if you add the using System; to the beginning of the file. 3rd Party Native Dependencies If your native interface depends on a 3rd party native library, your best option right now is to use the windows.depedencies build hint to add versioned dependencies from the nuget repository.\nSyntax for this build hint is as follows:\nwindows.dependencies=Lib1Name:Lib1Version,Lib2Name:Lib2Version,etc... E.g. Suppose we wanted to add LevelDB version 1.18.3 as a dependency. We would have:\nwindows.dependencies=LevelDB.UWP:1.18.3 Working in Visual Studio When developing native interfaces, the process I usually follow is:\nCreate the native interface in java (in my CN1 environment – Netbeans, Eclipse, IntelliJ, etc..).\nGenerate native access to generate my stub inside the \u0026ldquo;native/win\u0026rdquo; directory.\nEnable the \u0026ldquo;Include Sources\u0026rdquo; option for my project so that the build server will generate a Visual Studio project for my app.\nBuild the project for Windows UWP. Download the sources zip file. Open the \u0026ldquo;UWPApp\u0026rdquo; project in Visual Studio. The project is a Visual Studio 2015 project. Open and edit the native implementation (you’ll find it in the appropriate structure inside the \u0026ldquo;src\u0026rdquo; directory. Test the app in Visual Studio.\nWhen it’s all working, copy your native implementation’s source back into your CN1 project.\nReferences For a full example of a UWP native implementation, check out the UWP websockets implementation. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nHristo Vrigazov — November 16, 2016 at 6:28 pm (permalink) Great!\nChibuike Mba — November 17, 2016 at 10:48 am (permalink) WOW! Steve this is good.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/uwp-native-interfaces-mix-c-java/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/uwp-native-interfaces-mix-c-java/uwp-on-codenameone.jpg\"\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003eHistorical note:\u003c/strong\u003e Codename One\u0026rsquo;s UWP target was discontinued in release \u003cstrong\u003e7.0.229\u003c/strong\u003e. This post is preserved for historical context only, and its build/setup instructions no longer apply to current Codename One projects.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eThe next plugin update will add support for native interfaces in UWP. This opens the door for you to really dig into the native features of Windows if you wish to do so. Crucially, this will also allow us to push forward with windows support on some of the cn1libs that require native functionality. As a proof of concept, I have updated the CN1WebSockets library to support windows. It now works on all major platforms: iOS, Android, Javascript, UWP (Windows 10), Simulator, and Desktop builds. If you require sockets in your app, I highly recommend web sockets, as it is the most portable option currently available.\u003c/p\u003e","title":"UWP Native Interfaces – Mix C# and Java"},{"content":"\nThe Codename One CSS plugin is a handy tool to style your app with CSS. This includes setting borders, padding, margin, fonts, colors, and pretty much everything else that you might otherwise do in the resource editor. However, there are some other cool things that this plugin can do for you, such as importing multi-images into your resource file. Let me demonstrate with a small snippet.\n__ In order to use CSS with your Codename One project, you will need to install CSS support in your project first. I’ll use the MemeMaker demo as an example of how to do this. It has a CSS file located at \u0026ldquo;css/theme.css\u0026rdquo; within the project directory, and I’ve loaded this CSS file in my app’s init() method using this code:\ntry { css = Resources.openLayered(\u0026quot;/theme.css\u0026quot;); UIManager.getInstance().addThemeProps(css.getTheme(css.getThemeResourceNames()[0])); } catch (Exception ex) { Log.e(ex); } I created a little icon, to display in the title area. It is located at \u0026ldquo;css/MemeIcon-white-100×100.png\u0026rdquo;.\nI’d like it to be imported as a multi-image so that it will be rendered at an appropriate size on all devices, regardless of their pixel density.\nI can import the image in my CSS file by adding a dummy selector with a background-image. I call this selector \u0026ldquo;Images\u0026rdquo;, but you can call it anything you like:\nImages { background-image: url(MemeIcon-white-100x100.png); cn1-source-dpi: 320; } __ This url path is relative to the css file itself. If I had placed the Image in a subdirectory (e.g. css/images/), then the url would be url(images/MemeIcon-white-100x100.png). I could also use an http or https URL if I wanted to load the image over the network. In such a case, this image would be downloaded at compile-time and embedded directly into the theme.css.res file. The above CSS snippet should be mostly self-explanatory. It is creating a selector with my image as a background image. This triggers the CSS processor to import the image into the generated resource file at compile time.\nThe cn1-source-dpi directive is a hint to the CSS plugin as to what the \u0026ldquo;source dpi\u0026rdquo; of the image is. It uses this as a reference point for generating the different sizes in the resulting multi-image. Generally I only use one of 2 values here: 160 or 320. As a reference, a value of 160 means that the image is currently sized correctly for an iPhone 3G (i.e. Non-retina display). A value of 320 means that the image is currently sized correctly for an iPhone 4, 5, or 6 (i.e. a Retina) device. It will then generate appropriately sized versions for all other densities based on this reference point.\nIn my experience, most PSD theme designs I find on the internet are sized for a retina display, so you’ll usually be using a value of \u0026ldquo;320\u0026rdquo; here. If you get it wrong, it will be obvious, and you can experiment with different values easily by just changing it and recompiling.\n__ When changing the cn1-source-dpi, you may need to delete the old generated \u0026ldquo;theme.css.res\u0026rdquo; file (which is saved in your app’s \u0026ldquo;src\u0026rdquo; directory) to clear out the old resolutions. Accessing the Images from Code Using the imported image from code is very easy. If you have a reference to the Resources object from loading the \u0026ldquo;theme.css.res\u0026rdquo; file, you can simply call css.getImage(\u0026quot;MemeIcon-white-100x100.png\u0026quot;) (i.e. you can load it by its file name).\nLoading Multiple Images in a Single Selector In the example above, I only imported a single image, but you can import multiple images in the same selector by separating them by a comma within the same background-image property. E.g.\nImages { background-image: url(MemeIcon-white-100x100.png), url(http://example.com/otherimage.jpg), url(images/myotherimage.png); cn1-source-dpi: 320; } Adding Images to UI Constants Sometimes I find it tedious to keep a reference to my css Resources object for the purpose of loading an image. One nice alternative is to add the image to Codename One’s theme constants. The CSS plugin reserves a special selector #Constants for defining theme constants (these correspond with the values you see in the \u0026ldquo;Constants\u0026rdquo; tab of a theme in the resource editor). Here is an example from the MemeMaker app:\n*theme.css :\nImages { background-image: url(MemeIcon-white-100x100.png); cn1-source-dpi: 320; } #Constants { MemeIconImage: \u0026quot;MemeIcon-white-100x100.png\u0026quot;; } This creates a theme constant named \u0026ldquo;MemeIconImage\u0026rdquo; with my image. I can then access the image from code as follows:\nUIManager.getInstance().getThemeImageConstant(\u0026quot;MemeIconImage\u0026quot;) __ Theme constants must follow naming conventions to identify their \u0026ldquo;type\u0026rdquo;. Any theme constant that stores an image, must end with \u0026ldquo;Image\u0026rdquo;. E.g. \u0026ldquo;MemeIconImage\u0026rdquo; is fine. \u0026ldquo;MemeIconPhoto\u0026rdquo; is not. If you take a look at the constants tab of any theme, you should be able to catch on to the naming convention very quickly. And the result:\nGet the Meme Maker App On the Play Store\nIn the Windows Store\nIn the iTunes Store\nOn GitHub\nArchived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — August 9, 2017 at 3:44 pm (permalink) Is it possible to import several images with different cn1-source-dpi?\nIn the following example you assume that both images have same dpi, is it right? How to do if the dpi is different?\nImages {\nbackground-image: url(MemeIcon-white-100×100.png),\nurl(http://example.com/otherima…),\nurl(images/myotherimage.png);\ncn1-source-dpi: 320;\n}\nThank you.\nshannah78 — August 10, 2017 at 5:00 am (permalink) You would do separate styles.\nE.g.\nImages {\n….\ncn1-source-dpi: 320\n}\nImages160 {\n…\ncn1-source-dpi: 160\n}\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/using-css-to-import-images/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/using-css-to-import-images/css-header.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe Codename One CSS plugin is a handy tool to style your app with CSS. This includes setting borders, padding, margin, fonts, colors, and pretty much everything else that you might otherwise do in the resource editor. However, there are some other cool things that this plugin can do for you, such as importing multi-images into your resource file. Let me demonstrate with a small snippet.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eIn order to use CSS with your Codename One project, you will need to install \u003ca href=\"https://github.com/shannah/cn1-css\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCSS support\u003c/a\u003e in your project first.\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eI’ll use the \u003ca href=\"https://github.com/shannah/mememaker\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eMemeMaker demo\u003c/a\u003e as an example of how to do this. It has a CSS file located at \u0026ldquo;css/theme.css\u0026rdquo; within the project directory, and I’ve loaded this CSS file in my app’s init() method using this code:\u003c/p\u003e","title":"CSS Tip: Using CSS to Import Images"},{"content":"Cross Platform Mobile App Development for iOS (iPhone/iPad), Android, Windows \u0026amp; more! Building a mobile app is challenging. We can help\u0026hellip;\nHome Services Full App Development We can provide an app that runs on 2 or more mobile OS\u0026rsquo;s with no additional cost!\nTypical app development shops price low then charge for refinements. We make our profit by keeping you as a customer in the long run. Our maintenence fees are included in the enterprise support package.\nCustom Theme/Design Integration We will adapt a PSD or designer sketches to an application that will work properly across all devices/densities\u0026rsquo;s. This allows your developers to focus on coding the application and have a pixel perfect design to plug into.\nClient Side Development You have your backend and your server side developers, but don\u0026rsquo;t have enough resources to build the client. Our developers can work together with your team and build you the client side of your App.\nProof of Concept We can build a prototype to prove that Codename One can answer your project requirements. This is the fastest way to jumpstart Codename One development and can be used to transition into an in-house development.\nSounds Good? Contact Us\n","permalink":"https://www.codenameone.com/mobile-app-design-development-services/","summary":"\u003ch1 id=\"cross-platform-mobile-app-development-for-ios-iphoneipad-android-windows--more\"\u003eCross Platform Mobile App Development for iOS (iPhone/iPad), Android, Windows \u0026amp; more!\u003c/h1\u003e\n\u003cp\u003eBuilding a mobile app is challenging. We can help\u0026hellip;\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eServices\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"full-app-development\"\u003eFull App Development\u003c/h3\u003e\n\u003cp\u003eWe can provide an app that runs on 2 or more mobile OS\u0026rsquo;s with no additional cost!\u003cbr\u003e\nTypical app development shops price low then charge for refinements. We make our profit by keeping you as a customer in the long run. Our maintenence fees are included in the enterprise support package.\u003c/p\u003e","title":"Mobile App Design \u0026 Development Services"},{"content":"\nOne of the most frustrating things that can happen to developers is when you manage to reproduce a rare bug but\nyou are not in the debugger when you did that. My kingdom for a stack trace…​\nBut this is also pretty frustrating when you work on a tool like Codename One’s designer or GUIBuilder and they\nsuddenly freeze with no visible error. How do you provide a viable bug report for that?\nThis was pretty obvious for me but I’ve programmed in Java from the age that predated IDE’s and surprisingly\nthis isn’t common knowledge. On Windows you can just do a ctrl → Break on a Java process and get the\nfull JVM dump which includes everything you need to debug the issue. With Mac/Linux you can send a\nkill -QUIT message for the same effect which is slightly more of an effort but in some ways more rewarding.\nTo do this open your console/terminal and type in:\nps auxw | grep java This should provide you with the list of Java processes ID’s, identify the one that is relevant and use:\nkill -QUIT process-id Where process-id is the number representing the process e.g. running this on a fresh instance of the Codename One\ndesigner shows how powerful this tool is. You can see the current state of every thread and memory state rather\neasily and without any special tools.\nFull thread dump Java HotSpot(TM) 64-Bit Server VM (25.45-b02 mixed mode): \u0026quot;TimerQueue\u0026quot; #36 daemon prio=5 os_prio=31 tid=0x00007fbd49408000 nid=0x1141f waiting on condition [0x000070000260b000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for \u0026lt;0x000000076da064e0\u0026gt; (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.DelayQueue.take(DelayQueue.java:211) at javax.swing.TimerQueue.run(TimerQueue.java:171) at java.lang.Thread.run(Thread.java:745) \u0026quot;qtp984828826-34\u0026quot; #34 prio=5 os_prio=31 tid=0x00007fbd49af7000 nid=0x10b03 waiting on condition [0x0000700002508000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for \u0026lt;0x000000076d19ac80\u0026gt; (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:337)\tat org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:337) at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:337) at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:516) at org.eclipse.jetty.util.thread.QueuedThreadPool.access$600(QueuedThreadPool.java:39) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:562) at java.lang.Thread.run(Thread.java:745) \u0026quot;qtp984828826-33\u0026quot; #33 prio=5 os_prio=31 tid=0x00007fbd4ac7b800 nid=0x10903 waiting on condition [0x0000700002405000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for \u0026lt;0x000000076d19ac80\u0026gt; (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:337) at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:516) at org.eclipse.jetty.util.thread.QueuedThreadPool.access$600(QueuedThreadPool.java:39) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:562) at java.lang.Thread.run(Thread.java:745) \u0026quot;qtp984828826-32\u0026quot; #32 prio=5 os_prio=31 tid=0x00007fbd4ac9a800 nid=0x10703 waiting on condition [0x0000700002302000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for \u0026lt;0x000000076d19ac80\u0026gt; (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:337) at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:516) at org.eclipse.jetty.util.thread.QueuedThreadPool.access$600(QueuedThreadPool.java:39) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:562) at java.lang.Thread.run(Thread.java:745) \u0026quot;qtp984828826-31\u0026quot; #31 prio=5 os_prio=31 tid=0x00007fbd4ac94000 nid=0x10503 waiting on condition [0x00007000021ff000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for \u0026lt;0x000000076d19ac80\u0026gt; (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:337) at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:516) at org.eclipse.jetty.util.thread.QueuedThreadPool.access$600(QueuedThreadPool.java:39) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:562) at java.lang.Thread.run(Thread.java:745) \u0026quot;qtp984828826-30\u0026quot; #30 prio=5 os_prio=31 tid=0x00007fbd4aa89000 nid=0x10303 waiting on condition [0x00007000020fc000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for \u0026lt;0x000000076d19ac80\u0026gt; (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:337) at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:516) at org.eclipse.jetty.util.thread.QueuedThreadPool.access$600(QueuedThreadPool.java:39) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:562) at java.lang.Thread.run(Thread.java:745) \u0026quot;qtp984828826-29\u0026quot; #29 prio=5 os_prio=31 tid=0x00007fbd4a333800 nid=0x10103 waiting on condition [0x0000700001ff9000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for \u0026lt;0x000000076d19ac80\u0026gt; (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:337) at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:516) at org.eclipse.jetty.util.thread.QueuedThreadPool.access$600(QueuedThreadPool.java:39) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:562) at java.lang.Thread.run(Thread.java:745) \u0026quot;qtp984828826-28 Selector0\u0026quot; #28 prio=5 os_prio=31 tid=0x00007fbd4a34c000 nid=0xff03 runnable [0x0000700001ef6000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.KQueueArrayWrapper.kevent0(Native Method) at sun.nio.ch.KQueueArrayWrapper.poll(KQueueArrayWrapper.java:198) at sun.nio.ch.KQueueSelectorImpl.doSelect(KQueueSelectorImpl.java:103) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86) - locked \u0026lt;0x000000076d21dc00\u0026gt; (a sun.nio.ch.Util$2) - locked \u0026lt;0x000000076d21db78\u0026gt; (a java.util.Collections$UnmodifiableSet) - locked \u0026lt;0x000000076d21d9f0\u0026gt; (a sun.nio.ch.KQueueSelectorImpl) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97) at org.eclipse.jetty.io.nio.SelectorManager$SelectSet.doSelect(SelectorManager.java:560) at org.eclipse.jetty.io.nio.SelectorManager$1.run(SelectorManager.java:277) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:598) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:533) at java.lang.Thread.run(Thread.java:745) \u0026quot;qtp984828826-27 Acceptor0 [[email protected]](/cdn-cgi/l/email-protection):9000 STARTING\u0026quot; #27 prio=5 os_prio=31 tid=0x00007fbd4a230000 nid=0xfb13 runnable [0x0000700001df3000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method) at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422) at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250) - locked \u0026lt;0x000000076d1a3bf8\u0026gt; (a java.lang.Object) at org.eclipse.jetty.server.nio.SelectChannelConnector.accept(SelectChannelConnector.java:97) at org.eclipse.jetty.server.AbstractConnector$Acceptor.run(AbstractConnector.java:833) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:598) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:533) at java.lang.Thread.run(Thread.java:745) \u0026quot;HashSessionScavenger-0\u0026quot; #26 daemon prio=6 os_prio=31 tid=0x00007fbd493cf000 nid=0xfd0b in Object.wait() [0x0000700001cf0000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.util.TimerThread.mainLoop(Timer.java:552) - locked \u0026lt;0x000000076d18f048\u0026gt; (a java.util.TaskQueue) at java.util.TimerThread.run(Timer.java:505) \u0026quot;Thread-5\u0026quot; #24 prio=6 os_prio=31 tid=0x00007fbd4a2de000 nid=0x671f in Object.wait() [0x0000700001aea000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on \u0026lt;0x000000076d092240\u0026gt; (a java.lang.Object) at java.lang.Object.wait(Object.java:502) at org.eclipse.jetty.util.thread.QueuedThreadPool.join(QueuedThreadPool.java:385) - locked \u0026lt;0x000000076d092240\u0026gt; (a java.lang.Object) at org.eclipse.jetty.server.Server.join(Server.java:403) at com.codename1.designer.LocalServer$1.run(LocalServer.java:73) \u0026quot;Network Thread\u0026quot; #21 prio=5 os_prio=31 tid=0x00007fbd49372800 nid=0xed03 in Object.wait() [0x00007000019e7000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on \u0026lt;0x00000006c0945408\u0026gt; (a java.lang.Object) at java.lang.Object.wait(Object.java:502) at com.codename1.io.NetworkManager$NetworkThread.run(NetworkManager.java:337) - locked \u0026lt;0x00000006c0945408\u0026gt; (a java.lang.Object) at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176) \u0026quot;DestroyJavaVM\u0026quot; #18 prio=5 os_prio=31 tid=0x00007fbd4911d800 nid=0x1703 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE \u0026quot;EDT\u0026quot; #17 prio=6 os_prio=31 tid=0x00007fbd49956000 nid=0xe613 in Object.wait() [0x00007000017e1000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on \u0026lt;0x00000006c01b28c8\u0026gt; (a java.lang.Object) at java.lang.Object.wait(Object.java:502) at com.codename1.ui.Display.mainEDTLoop(Display.java:959) - locked \u0026lt;0x00000006c01b28c8\u0026gt; (a java.lang.Object) at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120) at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176) \u0026quot;Timer-0\u0026quot; #15 daemon prio=5 os_prio=31 tid=0x00007fbd4a18a800 nid=0xe403 in Object.wait() [0x00007000016de000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:502) at java.util.TimerThread.mainLoop(Timer.java:526) - locked \u0026lt;0x00000006c019aef8\u0026gt; (a java.util.TaskQueue) at java.util.TimerThread.run(Timer.java:505) \u0026quot;Java2D Disposer\u0026quot; #14 daemon prio=10 os_prio=31 tid=0x00007fbd4a988000 nid=0xe203 in Object.wait() [0x00007000015db000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on \u0026lt;0x00000006c01b2d68\u0026gt; (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) - locked \u0026lt;0x00000006c01b2d68\u0026gt; (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) at sun.java2d.Disposer.run(Disposer.java:148) at java.lang.Thread.run(Thread.java:745) \u0026quot;Java2D Queue Flusher\u0026quot; #13 daemon prio=10 os_prio=31 tid=0x00007fbd4a1dc000 nid=0xce07 in Object.wait() [0x00007000014d8000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) at sun.java2d.opengl.OGLRenderQueue$QueueFlusher.run(OGLRenderQueue.java:203) - locked \u0026lt;0x00000006c019af48\u0026gt; (a sun.java2d.opengl.OGLRenderQueue$QueueFlusher) \u0026quot;AWT-EventQueue-0\u0026quot; #12 prio=6 os_prio=31 tid=0x00007fbd491dd000 nid=0xc007 waiting on condition [0x00007000013d5000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for \u0026lt;0x00000006c01b4860\u0026gt; (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.awt.EventQueue.getNextEvent(EventQueue.java:554) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:170) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) at java.awt.EventDispatchThread.run(EventDispatchThread.java:82) \u0026quot;AWT-Shutdown\u0026quot; #11 prio=5 os_prio=31 tid=0x00007fbd4914d800 nid=0x6b23 in Object.wait() [0x00007000011cc000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:502) at sun.awt.AWTAutoShutdown.run(AWTAutoShutdown.java:295) - locked \u0026lt;0x00000006c019b248\u0026gt; (a java.lang.Object) at java.lang.Thread.run(Thread.java:745) \u0026quot;AppKit Thread\u0026quot; #10 daemon prio=5 os_prio=31 tid=0x00007fbd498d8000 nid=0xa0b runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE \u0026quot;Service Thread\u0026quot; #8 daemon prio=9 os_prio=31 tid=0x00007fbd4a01a800 nid=0x4903 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE \u0026quot;C1 CompilerThread2\u0026quot; #7 daemon prio=9 os_prio=31 tid=0x00007fbd4a019800 nid=0x4703 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE \u0026quot;C2 CompilerThread1\u0026quot; #6 daemon prio=9 os_prio=31 tid=0x00007fbd4a014800 nid=0x4503 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE \u0026quot;C2 CompilerThread0\u0026quot; #5 daemon prio=9 os_prio=31 tid=0x00007fbd4902e000 nid=0x4303 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE \u0026quot;Signal Dispatcher\u0026quot; #4 daemon prio=9 os_prio=31 tid=0x00007fbd4a013800 nid=0x360f waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE \u0026quot;Finalizer\u0026quot; #3 daemon prio=8 os_prio=31 tid=0x00007fbd4a83b000 nid=0x3003 in Object.wait() [0x000070000092e000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on \u0026lt;0x00000006c02124a0\u0026gt; (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) - locked \u0026lt;0x00000006c02124a0\u0026gt; (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) \u0026quot;Reference Handler\u0026quot; #2 daemon prio=10 os_prio=31 tid=0x00007fbd4a83a800 nid=0x2e03 in Object.wait() [0x000070000082b000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on \u0026lt;0x00000006c019b608\u0026gt; (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157) - locked \u0026lt;0x00000006c019b608\u0026gt; (a java.lang.ref.Reference$Lock) \u0026quot;VM Thread\u0026quot; os_prio=31 tid=0x00007fbd49018800 nid=0x2c03 runnable \u0026quot;GC task thread#0 (ParallelGC)\u0026quot; os_prio=31 tid=0x00007fbd4980a000 nid=0x2403 runnable \u0026quot;GC task thread#1 (ParallelGC)\u0026quot; os_prio=31 tid=0x00007fbd4980a800 nid=0x2603 runnable \u0026quot;GC task thread#2 (ParallelGC)\u0026quot; os_prio=31 tid=0x00007fbd4980b000 nid=0x2803 runnable \u0026quot;GC task thread#3 (ParallelGC)\u0026quot; os_prio=31 tid=0x00007fbd49008800 nid=0x2a03 runnable \u0026quot;VM Periodic Task Thread\u0026quot; os_prio=31 tid=0x00007fbd4a06b000 nid=0x4b03 waiting on condition JNI global references: 807 Heap PSYoungGen total 76288K, used 50593K [0x000000076ab00000, 0x0000000770000000, 0x00000007c0000000) eden space 65536K, 77% used [0x000000076ab00000,0x000000076dc685b8,0x000000076eb00000) from space 10752K, 0% used [0x000000076eb00000,0x000000076eb00000,0x000000076f580000) to space 10752K, 0% used [0x000000076f580000,0x000000076f580000,0x0000000770000000) ParOldGen total 126976K, used 11704K [0x00000006c0000000, 0x00000006c7c00000, 0x000000076ab00000) object space 126976K, 9% used [0x00000006c0000000,0x00000006c0b6e050,0x00000006c7c00000) Metaspace used 25623K, capacity 25970K, committed 26240K, reserved 1073152K class space used 3249K, capacity 3341K, committed 3456K, reserved 1048576K Visual VM You can take this a step further with jvisualvm which is like a console for your running JVM processes. You can\nget exactly the result outlined above and far more by just selecting the process matching the JVM, selecting the\nthreads view and their dump:\nFigure 1. Visual VM showing the stack trace for the designer tool\nThis tool is pretty powerful and can provide a lot of insight into the on-goings of Java processes.\nSubmitting Stacks When you run into an issue that might benefit from the stacks in the simulator it’s the time to pull out these\ntools and point them at the process. An issue that includes the full JVM stack states would often be easier to\nsolve especially if it’s a deadlock issues.\nIf you have an issue on an Android device check out this stackoverflow thread\nwhere you can see some information on listing the thread states on a physical device.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-get-stack-state-trace-from-java-processes/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-get-stack-state-trace-from-java-processes/just-the-tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the most frustrating things that can happen to developers is when you manage to reproduce a rare bug but\u003cbr\u003e\nyou are not in the debugger when you did that. My kingdom for a stack trace…​\u003cbr\u003e\nBut this is also pretty frustrating when you work on a tool like Codename One’s designer or GUIBuilder and they\u003cbr\u003e\nsuddenly freeze with no visible error. How do you provide a viable bug report for that?\u003c/p\u003e","title":"TIP: Get Stack State (trace) from Java Processes"},{"content":"\nWe try to space out plugin updates as much as reasonably possible but unfortunately we need to push out\nan update this week to fix a critical regression in the new GUI builder. Hopefully it is more stable now and we can\ngo back to working on new features.\nSteve made a couple of very interesting posts this week and we have a few more from him in the coming weeks.\nOn stack overflow things were as usual:\ntoastbar in postResponse of connectionRequest ToastBar is tied to a specific form so if a Dialog is shown when you show a ToastBar it might bind to that instead\nRead on stackoverflow…​\nCodename One wasPurchased() method : Is it supported on Android devices? There is a bit of a \u0026ldquo;weird\u0026rdquo; item naming convention required for Android IAP\nRead on stackoverflow…​\nHow to open html input type file dialog box inside codenameone app File picker is a unique component in the Android browser that’s very problematic\nRead on stackoverflow…​\nBack button in statusbar I used the floating toolbar quite a lot, it’s pretty cool…​\nRead on stackoverflow…​\nTest In-App-Purchase in Codename One simulator results in Null Pointer Exception IAP and push both need the main class to implement their respective callback interfaces\nRead on stackoverflow…​\nHand coded GUI build failed in Codename One When you create a GUI builder form and decide to stop using the GUI buidler you need to delete the .gui file\nRead on stackoverflow…​\nOverridable method call in constructor in Codename One Demo example [duplicate] This was closed by moderators as a duplicate but it’s a pretty good question still…​\nRead on stackoverflow…​\nHow to localize styled components The font for the component is quite important for localization\nRead on stackoverflow…​\nHow to setup fragment projects cn1lib’s allow some modularity in Codename One but unfortunately Eclipse doesn’t yet include the template for cn1libs\nRead on stackoverflow…​\nPerformance related issue with network connection It is crucial to keep an eye on all networking operationson all times\nRead on stackoverflow…​\nHow to test an Android native code snippet with Codename One? The best way is to use include source and open the native project in the native IDE\nRead on stackoverflow…​\nIs it possible with Codename One to record microphone input and play it back simultaneously? Apparently it isn’t with the current implementation but possible with native interfaces\nRead on stackoverflow…​\nSpanButton client property throws NullPointerException The source component of the event is sometimes murky when using lead component\nRead on stackoverflow…​\nNetbeans Plugin Version Netbeans doesn’t keep historical versions of the plugin to my knowledge\nRead on stackoverflow…​\nCustom toolbar issues Getting alignment/spacing \u0026ldquo;just right\u0026rdquo; is sometimes a delicate balance\nRead on stackoverflow…​\nSet next Texfield to be focused We’ve used the old focus order functionality that’s used in desktops and old phones for the text field order feature\nin iOS/Android/Windows\nRead on stackoverflow…​\nExemplary code for payment We need a better In-App-Purchase sample for developers as a \u0026ldquo;real\u0026rdquo; app\nRead on stackoverflow…​\nQuery returning no results This was eventually caused by missing information in the database\nRead on stackoverflow…​\nAutoCompleteTextField list does not always scroll to top? We’re still trying to reproduce the original issue reliably\nRead on stackoverflow…​\nApp doesn’t work on iPhone 4S There are several reasons why an app will work on one device and won’t install/run in another\nRead on stackoverflow…​\nhttp proxy when using ConnectionRequest This should \u0026ldquo;just work\u0026rdquo; for the most part and use the system proxy when possible\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-31/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-31/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe try to space out plugin updates as much as reasonably possible but unfortunately we need to push out\u003cbr\u003e\nan update this week to fix a critical regression in the new GUI builder. Hopefully it is more stable now and we can\u003cbr\u003e\ngo back to working on new features.\u003c/p\u003e\n\u003cp\u003eSteve made a couple of very interesting posts this week and we have a few more from him in the coming weeks.\u003c/p\u003e","title":"Questions of the Week 31"},{"content":"\nFontBox is a mature java library for loading, manipulating, and rendering fonts in Java. It gives you direct access to the font glyphs so that you can perform effects or transformations on them. A couple of years ago, I ported FontBox to Codename One, but since CN1 didn’t yet include support for drawing shapes, I made it dependent upon the CN1Pisces library, which did support drawing shapes. This was cool but it had some major limitations; the main one being that FontBox fonts could only be used to draw strings on Pisces graphics contexts, which can only be rendered to an image – not directly to the screen. This meant that you couldn’t just use a FontBox font in your app (e.g. in a label or a button). You could only use it to write on an image.\nFast forward to the present day, when Codename One supports drawing shapes \u0026ldquo;natively\u0026rdquo; on all major platforms, I felt is was time to revamp this library so that it integrates better with Codename One. My goal was to be able to use a FontBox font interchangeably with \u0026ldquo;normal\u0026rdquo; fonts. E.g. for a label, button, text field, graphics context, etc…​ The motivation for this update came as I was developing the \u0026ldquo;Meme Maker\u0026rdquo; demo. I needed to draw some text that was filled white but had a black outline. Built-in fonts don’t have this ability, but since FontBox provides direct access to the font glyphs as paths (i.e. lines and curves) I could fairly easily create a font that had both fill and stroke. That’s just what I did, with the new TTFFont class.\nWhat can TTFFont do that Font cannot? TTFFont is a subclass of CustomFont which is itself a subclass of com.codename1.ui.Font. Therefore it can be used in any place that a standard font is used. Why would you do this?\nTTFFont supports stroking, filling, or both, with different colors. E.g. You can create a font that is stroked with white, but filled with black. And you can specify the width of the stroke just as you would a normal shape.\nFigure 1. Stroked and filled text\nTTFFont supports both horizontal and vertical scaling, so you can make your text really skinny, or really wide, depending on what your requirements are. This also enables you to size text to fit a space exactly.\nFigure 2. Stretched text\nFigure 3. Compressed text\nTTFFont can load a TTF file from storage, file system, resources, or just from a plain old InputStream. This means that you can load fonts dynamically over a network if you want.\nDrawbacks Since TTFFonts are actually rendered in CN1 as shapes, they will be slower than built-in fonts, which are rendered natively by the platform. Therefore, you should only use TTFFont in cases where you require its extra capabilities. That said, there was no noticeable \u0026ldquo;lag\u0026rdquo; introduced in the Meme Maker app by my use of TTFFont.\nUsage Examples Loading TTF File From InputStream:\nTTFFont font = TTFFont.createFont(\u0026quot;MyFont\u0026quot;, inputStream); From Resources:\nTTFFont font = TTFFont.createFont(\u0026quot;MyFont\u0026quot;, \u0026quot;/MyFont.ttf\u0026quot;); From Storage/URL:\nTTFFont font = TTFFont.createFontToStorage(\u0026quot;MyFont\u0026quot;, \u0026quot;font_MyFont.ttf\u0026quot;, \u0026quot;http://example.com/MyFont.ttf\u0026quot; ); From File System/URL:\nTTFFont font = TTFFont.createFontToFileSystem(\u0026quot;MyFont\u0026quot;, FileSystemStorage.getInstance().getAppHomePath()+\u0026quot;/fonts/MyFont.ttf\u0026quot;, \u0026quot;http://example.com/MyFont.ttf\u0026quot; ); From Cache:\nTTFFont font = TTFFont.getFont(\u0026quot;MyFont\u0026quot;, 12); Setting Font for Style myLabel.getAllStyles().setFont(font); Getting Particular Size Font font = font.deriveFont(24); // get size 24 font. Horizontal and Vertical Scaling font = font.deriveScaled(0.5f, 1.5f); // scaled 50% horizontal, and 150% vertical font = font.deriveHorizontalScaled(0.5f); // scaled 50% horizontally font = font.deriveVerticalScaled(0.5f); // scaled 50% vertically Stroking and Filling font = font.deriveStroked(Stroke(1f, Stroke.CAP_BUTT, Stroke.JOIN_MITER, 1f), #ff0000); // Stroke with red 1px outline font = font.deriveStroked(Stroke(1f, Stroke.CAP_BUTT, Stroke.JOIN_MITER, 1f), null); // Stroked - stroke color determined by graphics context's current color.. e.g. defers to Style's foreground color font = font.deriveStroked(null, 0x0); // Not stroked font = font.deriveFilled(true, null); // Filled - fill color determined by graphics context's current color.. e.g. defers to Style's foreground color font = font.deriveFilled(true, 0x00ff00); // Filled with green font = font.deriveFilled(false, null); // Not filled Antialias font = font.deriveAntialias(true); // Should be rendered antialiased font = font.deriveAntialias(false); // should be rendered without antialias. Drawing Directly on Graphics Context font.drawString(g, \u0026quot;Hello world\u0026quot;, x, y); // Or ... g.setFont(font); g.drawString(\u0026quot;Hello world\u0026quot;, x, y); Appending to existing GeneralPath font.draw(path, \u0026quot;Hello world\u0026quot;, x, y, 1f /*opacity*/); More About CN1FontBox For more information about CN1FontBox, check out the CN1FontBox github repository. The best way to install it is through the \u0026ldquo;Extensions\u0026rdquo; section of the Codename One Settings for your project.\nGet the Meme Maker App On the Play Store\nIn the Windows Store\nIn the iTunes Store\nOn GitHub\nArchived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — November 10, 2016 at 7:41 pm (permalink) That’s very cool. Thanks once again for all your great work on CN1.\nChibuike Mba — November 11, 2016 at 9:09 am (permalink) Nice one Steve. Thanks.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/cool-text-effects-mobile-app-phone-ios-android/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/cool-text-effects-mobile-app-phone-ios-android/cool-text-transformations.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eFontBox is a mature java library for loading, manipulating, and rendering fonts in Java. It gives you direct access to the font glyphs so that you can perform effects or transformations on them. A couple of years ago, I ported FontBox to Codename One, but since CN1 didn’t yet include support for drawing shapes, I made it dependent upon the \u003ca href=\"https://github.com/shannah/CN1Pisces\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCN1Pisces library\u003c/a\u003e, which did support drawing shapes. This was cool but it had some major limitations; the main one being that FontBox fonts could only be used to draw strings on Pisces graphics contexts, which can only be rendered to an image – not directly to the screen. This meant that you couldn’t \u003cstrong\u003ejust\u003c/strong\u003e use a FontBox font in your app (e.g. in a label or a button). You could only use it to write on an image.\u003c/p\u003e","title":"Cool Text Effects for Your Mobile App on iPhone (iOS), Android etc."},{"content":"\nWe are launching a partners page in the website that will refer to consultants that we recommend/approve.\nIf you are a software development company that works with Codename One we’d like to feature you in our website\nand provide the following benefits:\nDo-follow link from us (we have good page rank for valuable industry keywords)\nOfficial reference – we will only feature companies that we recommend\nWork from Codename One – when we outsource work we will only use official partners\nPotential for guest posts, success stories, case studies, press releases etc.\nFor a featured position we currently have the following requirements:\nAt least one high quality app in the featured apps gallery available at least on iOS \u0026amp; Android\nA do follow link to Codename One from your website\nWe reserve the right to deny anyone based on our considerations e.g. if a developer has bad reputation we can’t\nendorse such a developer.\nTo signup for this please use the chat contact button in the bottom right of the page and provide us with some\ndetails about your company, the app links, logo etc.\nDemos in the new Plugin With the new plugin update we added a lot of the new demos to the plugin to make it easier for\nyou to see them. This is true for both the NetBeans and IntelliJ plugins although not yet a part of the Eclipse plugin\nwhich is harder to maintain.\nEvery recent update of the new GUI builder is a bit of a mixed bag as we fix and improve we also introduce\npainful regressions. This time around we have a regression with MultiButton and probably all lead components\n(e.g. SpanButton) where events are no longer delivered. This probably means we’ll have to release a plugin\nupdate this Friday as well.\nHowever, we did add a lot of other fixes and improvements including the ability to define a lead component properly\nand the long time RFE for the old GUI builder:\nUsing Custom Components The new GUI Builder allows us to custom components into the GUI. Just pick the custom component from the\npalette and drag it into place.\nOnce you do that you will need to create a method with the signature:\nprivate Component create_ComponentName() { return new MyComponent(); } __ the upcoming version of the plugin will generate that method implicitly Here you can return any arbitrary component instance, bind listeners and do any initialization code you want. The\nGUI builder will only be used as a layout tool in the case of that specific component and you would have the\nfull power to place anything there.\n64bit Debug Builds One annoyance of iOS 10 is that it now pops up a warning that the application is built for an older OS and might\nbe slow. This is one of those \u0026ldquo;Appleisms\u0026rdquo; that tries to force developers to move to 64bit, we already support\n64bit but no longer build it in the debug version to avoid the performance cost.\nIf you build a release build and install it via testflight this should behave fine, however if you find this warning\nannoying you can just build a 64bit version instead of a 32bit version with the upcoming build hint:\nios.debug.archs=arm64\nNotice that once you enable that flag the app will fail installation on older devices that don’t have 64bit support.\nThat is why this is off by default. Normally we compile both 64 and 32 bit and package everything in a \u0026ldquo;fat binary\u0026rdquo;\nhowever for debug builds that effectively doubles the build time and increases the download size significantly.\nEnd of Life for iphone_old If you rely on the iphone_old build target please migrate your code/certificates until January. We intend to migrate\nthe last remaining servers to xcode 7.x by the time we release 3.6.\nBy now xcode 8 and a new version of Mac OS are already out so we need to keep up and the old build target\nis no longer practical. If you are still experiencing issues and are waiting for the fix now is the time to start working\non getting these issues fixed!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/partners-demos-custom-gui-components-iphone-old-deprecation/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/partners-demos-custom-gui-components-iphone-old-deprecation/new-gui-builder.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are launching a partners page in the website that will refer to consultants that we recommend/approve.\u003cbr\u003e\nIf you are a software development company that works with Codename One we’d like to feature you in our website\u003cbr\u003e\nand provide the following benefits:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eDo-follow link from us (we have good page rank for valuable industry keywords)\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eOfficial reference – we will only feature companies that we recommend\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eWork from Codename One – when we outsource work we will only use official partners\u003c/p\u003e","title":"Partners, Demos, Custom GUI Component \u0026 iPhone-Old Deprecation"},{"content":"\nOne of the compelling reasons to go native (vs say a web app) is to better integrate with the platform. One form of integration that is frequently handy is the ability register your app to handle certain file types so that it is listed as one of the options when a user tries to view a file of that type. Codename One supports this use case via the \u0026ldquo;AppArg\u0026rdquo; display property – the same, simple mechanism used for handling custom link types in your app.\nWith the \u0026ldquo;Meme Maker\u0026rdquo; demo that I just created, I wanted users to be able to select a photo from another app (like Photos on Android), and send it directly to the Meme Maker app as the basis for creating a Meme.\nIn case you’re not familiar with \u0026ldquo;Memes\u0026rdquo;, they are those sometimes annoying photos that litter your facebook feed with witty captions laid over them. E.g:\nFigure 1. Example cat meme\nMeme Maker is a very simple app. It allows the user to select a photo, and it provides some text laid over the photo which the user can edit. When the meme is finished, it can be exported as an image, and/or shared to Facebook or other social media.\nAll this is simple to do in Codename One. Selecting an image, can be achieved using Display.openGallery(), which allows the user to choose from one of the images in their device’s photos. Sharing an image can be achieved via Display.execute() or with the ShareButton component.\nI wanted to go a step further, though, so that users could launch MemeMaker directly from their Photos app. For a simple app like this, allowing the user to \u0026ldquo;Share\u0026rdquo; an image to the app can significantly improve the user experience.\nHow to Register an App to open a File Type Registering your app to open a a file type involves two parts:\nAdd some build hints to inject the appropriate metadata into each native platform config files (e.g. The info.plist on iOS, the manifest file on Android, etc..) to inform the native platform that the app can open the specified file types.\nCheck for Display.getInstance().getProperty(\u0026quot;AppArg\u0026quot;, null) at the beginning of your app’s start() method to see if the app was opened as a result of file being opened or shared. If present, it will be the path to a file that you can access using FileSystemStorage.\nAn example from the \u0026ldquo;Meme Maker\u0026rdquo; demo Lets’ start by looking at the code that handles the \u0026ldquo;AppArg\u0026rdquo;. At the beginning of the start() method we have:\nDisplay disp = Display.getInstance(); String arg = disp.getProperty(\u0026quot;AppArg\u0026quot;, null); if (arg != null) { disp.setProperty(\u0026quot;AppArg\u0026quot;, null); disp.callSerially(()-\u0026gt;{ fireImageSelected(arg); }); } So, what we’ve done here is\nCheck the \u0026ldquo;AppArg\u0026rdquo; property.\nIf it is not null, we set it null (just so we don’t mistake it being set in future starts).\nI use callSerially() to defer the actual selection of the image until after the rest of the start() method has run. That is app-specific, and not necessary in general for processing app arguments.\nThat’s all there is to it.\nNow the app is equipped to \u0026ldquo;handle\u0026rdquo; files that are passed to it on startup. However we still need to register the app with each platform so that the operating system knows to make our app available as a share target (or an \u0026ldquo;open with\u0026rdquo; target).\nAndroid-Specific Configuration There are two build-hints related to Android that we will need to employ:\nandroid.activity.launchMode=singleTask. The default launch mode for Codename One apps is \u0026ldquo;singleTop\u0026rdquo;. Unfortunately this doesn’t really work very well if the app can be launched from other apps to open files. I won’t go into specifics here about the differences between \u0026ldquo;singleTop\u0026rdquo; and \u0026ldquo;singleTask\u0026rdquo; launch mode. Just know that if you want your app to work properly as a share target, you need to set this build hint to \u0026ldquo;singleTask\u0026rdquo;.\nYou can read more about Android’s activity:launchMode directive here.\nandroid.xintent_filter This is where we add the \u0026lt;intent-filter\u0026gt; tags to be injected into the app’s manifest file. These filters will register our app to open specific file types. The value I used for Meme Maker is:\n\u0026lt;intent-filter\u0026gt; \u0026lt;action android_name=\u0026quot;android.intent.action.SEND\u0026quot; /\u0026gt; \u0026lt;category android_name=\u0026quot;android.intent.category.DEFAULT\u0026quot; /\u0026gt; \u0026lt;data android_mimeType=\u0026quot;image/*\u0026quot; /\u0026gt; \u0026lt;/intent-filter\u0026gt; \u0026lt;intent-filter \u0026gt; \u0026lt;action android_name=\u0026quot;android.intent.action.VIEW\u0026quot; /\u0026gt; \u0026lt;category android_name=\u0026quot;android.intent.category.DEFAULT\u0026quot; /\u0026gt; \u0026lt;data android_mimeType=\u0026quot;image/*\u0026quot; /\u0026gt; \u0026lt;/intent-filter\u0026gt; The first filter says that the app is an eligible \u0026ldquo;share\u0026rdquo; target for files with mimetype \u0026ldquo;image/\u0026rdquo;. The second says that the app is eligible to \u0026ldquo;Open\u0026rdquo; files with mimetype \u0026ldquo;image/ \u0026ldquo;. Each is used in different instances. A simple way to think of this is, from a Codename One’s app perspective:\n1. `Display.execute(filepath)` – will allow the user to \u0026quot;open\u0026quot; the file using apps that have registered an appropriate intent filter with action `android.intent.action.VIEW`. 2. `Display.share(null, filepath, \u0026quot;image/png\u0026quot;)` – will allow the user to \u0026quot;send\u0026quot; the file to an app that has registered an appropriate intent filter with action `android.intent.action.SEND`. Here are some sceen-shots of how the integration looks on my Nexus 5.\nI did a search on Google for \u0026ldquo;blank meme photos\u0026rdquo;. Once I found a photo, I did a long-press on the image (in Chrome), to open the context menu:\nFigure 2. Android chrome context menu\nThen when I tap on \u0026ldquo;Share\u0026rdquo;, it gives me a list of the apps that I can share this image to. MemeMaker is listed there:\nFigure 3. Share image to meme maker\nThen it opens Meme Maker with the image already loaded into the background:\nFigure 4. Meme maker with preloaded image\niOS-Specific Configuration On iOS, we only need concern ourselves with one build hint:\nios.plistInject\nThe content I used for the Meme Maker app is:\n\u0026lt;key\u0026gt;CFBundleDocumentTypes\u0026lt;/key\u0026gt; \u0026lt;array\u0026gt; \u0026lt;dict\u0026gt; \u0026lt;key\u0026gt;CFBundleTypeName\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;image\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;CFBundleTypeRole\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;Viewer\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;LSHandlerRank\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;Alternate\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;LSItemContentTypes\u0026lt;/key\u0026gt; \u0026lt;array\u0026gt; \u0026lt;string\u0026gt;public.image\u0026lt;/string\u0026gt; \u0026lt;/array\u0026gt; \u0026lt;/dict\u0026gt; \u0026lt;/array\u0026gt; Don’t be intimidated by this snippet. There’s a lot there, but for the most part it is just boiler-plate copy and paste. Here is a break-down of the values and their meaning:\nCFBundleTypeName – A name for this bundle type. You can provide pretty much any value you want here. I used \u0026ldquo;image\u0026rdquo;, but it could have been \u0026ldquo;foo\u0026rdquo; or \u0026ldquo;bar\u0026rdquo;.\nCFBundleTypeRole – The role of this app. In our case I’m just registering it as an image viewer. The value can be Editor, Viewer, Shell, or None. This key is required.\nLSHandlerRank – How iOS ranks the relevance against other apps that open this file type. Possible values: \u0026ldquo;Owner\u0026rdquo;, \u0026ldquo;Alternate\u0026rdquo;, \u0026ldquo;Default\u0026rdquo;, \u0026ldquo;None\u0026rdquo;\nLSItemContentTypes – A list of the content types that are being registered to be opened by the app. iOS uses UTIs instead of mimetypes here. The public.image UTI is basically the same as the image/* mimetype. You can see a list of all public UTIs here.\n__ iOS has (at least) two different mechanisms for handling file types in your app. The above ios.plistInject value will register the app to be able to \u0026ldquo;Open\u0026rdquo; an image file, but it won’t allow it to receive it as a share target. The distinction is subtle and it depends on what mechanism is used to launch the \u0026ldquo;Open with\u0026rdquo; or \u0026ldquo;Share\u0026rdquo; dialog in the source app. E.g. If you view a PDF inside Safari, it will provide an \u0026ldquo;Open with…​\u0026rdquo; (label changed to \u0026ldquo;More…​\u0026rdquo; in iOS 10) link in the top left, which, if tapped, will provide the user with a list of registered apps that can open a PDF. If our app was registered to open a PDF in the same way that it is registered to open images, then our app would appear in this list of elligible apps. However, there is also a \u0026ldquo;Share\u0026rdquo; button at the bottom of the screen in Safari. This won’t include our app as it uses a different mechanism for registering apps. Registration to appear in this menu is more complicated and beyond the scope of this post.\nUnfortunately I couldn’t find an example in the latest OS where an app provides \u0026ldquo;Open with\u0026rdquo; an image. It seems that things are shifting towards \u0026ldquo;sharing\u0026rdquo; when images are involved, and as I mentioned above, this is a little more complex. However, for other files types, like PDF, the \u0026ldquo;open with\u0026rdquo; workflow is still common. For example, here is a sample of a PDF as viewed in iOS’ Safari. If I tap on the PDF, it provides a little menu along the top with a \u0026ldquo;More…​\u0026rdquo; option, as shown here:\nAnd when I tap on \u0026ldquo;More…​\u0026rdquo; I see:\nFigure 5. iOS Open with dialog\nThe first application listed here is \u0026ldquo;OCR.net\u0026rdquo;, which is an app that I developed using Codename One. It includes the following ios.plistInject directive to be shown here:\n\u0026lt;key\u0026gt;CFBundleDocumentTypes\u0026lt;/key\u0026gt; \u0026lt;array\u0026gt; \u0026lt;dict\u0026gt; \u0026lt;key\u0026gt;CFBundleTypeName\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;pdf\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;CFBundleTypeRole\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;Viewer\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;LSHandlerRank\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;Alternate\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;LSItemContentTypes\u0026lt;/key\u0026gt; \u0026lt;array\u0026gt; \u0026lt;string\u0026gt;com.adobe.pdf\u0026lt;/string\u0026gt; \u0026lt;/array\u0026gt; \u0026lt;/dict\u0026gt; \u0026lt;dict\u0026gt; \u0026lt;key\u0026gt;CFBundleTypeName\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;image\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;CFBundleTypeRole\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;Viewer\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;LSHandlerRank\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;Alternate\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;LSItemContentTypes\u0026lt;/key\u0026gt; \u0026lt;array\u0026gt; \u0026lt;string\u0026gt;public.image\u0026lt;/string\u0026gt; \u0026lt;/array\u0026gt; \u0026lt;/dict\u0026gt; \u0026lt;/array\u0026gt; Windows-Specific Configuration The process for UWP is similar to both iOS and Android. In this case we use the windows.extensions directive to inject content into the windows manifest file. In this case, we use:\n\u0026lt;uap:Extension Category=\u0026quot;windows.fileTypeAssociation\u0026quot;\u0026gt; \u0026lt;uap:FileTypeAssociation Name=\u0026quot;image\u0026quot;\u0026gt; \u0026lt;uap:Logo\u0026gt;imagesicon.png\u0026lt;/uap:Logo\u0026gt; \u0026lt;uap:SupportedFileTypes\u0026gt; \u0026lt;uap:FileType ContentType=\u0026quot;image/jpeg\u0026quot;\u0026gt;.jpg\u0026lt;/uap:FileType\u0026gt; \u0026lt;uap:FileType ContentType=\u0026quot;image/jpeg\u0026quot;\u0026gt;.jpeg\u0026lt;/uap:FileType\u0026gt; \u0026lt;uap:FileType ContentType=\u0026quot;image/gif\u0026quot;\u0026gt;.gif\u0026lt;/uap:FileType\u0026gt; \u0026lt;uap:FileType ContentType=\u0026quot;image/png\u0026quot;\u0026gt;.png\u0026lt;/uap:FileType\u0026gt; \u0026lt;/uap:SupportedFileTypes\u0026gt; \u0026lt;/uap:FileTypeAssociation\u0026gt; \u0026lt;/uap:Extension\u0026gt; With this build hint, our app is registered to open files with .jpg, jpeg, .gif, and .png files. On the desktop, this means you can right click on files of these types, select \u0026ldquo;Open with\u0026rdquo; in the contextual menu, and then select \u0026ldquo;Meme maker\u0026rdquo; as shown here:\nFor more information about the available options in UWP, see handling file activation on MSDN.\nWindows 10 Share Targets As with iOS and Android, Windows 10 treats \u0026ldquo;share targets\u0026rdquo; slightly differently than file associations. The FileTypeAssociation tag registers the app to be able to \u0026ldquo;open\u0026rdquo; files of the specified types, but it doesn’t register to be a share target. Share targets are those apps that appear in the sharing dialog when a users chooses \u0026ldquo;Share\u0026rdquo; from a context menu. E.g. When I right click on this image in Edge, it gives me an option to \u0026ldquo;Share\u0026rdquo; the image:\nOn the desktop, this will open a sidebar with a list of applications to which this image can be shared:\nIn the above screenshot, notice that Meme Maker is listed as one of the apps. This version of MemeMaker was built using an some additional options in the windows.extensions build hint:\n\u0026lt;uap:Extension Category=\u0026quot;windows.shareTarget\u0026quot;\u0026gt; \u0026lt;uap:ShareTarget Description=\u0026quot;Images\u0026quot;\u0026gt; \u0026lt;uap:SupportedFileTypes\u0026gt; \u0026lt;uap:FileType\u0026gt;.jpg\u0026lt;/uap:FileType\u0026gt; \u0026lt;uap:FileType\u0026gt;.gif\u0026lt;/uap:FileType\u0026gt; \u0026lt;uap:FileType\u0026gt;.png\u0026lt;/uap:FileType\u0026gt; \u0026lt;uap:FileType\u0026gt;.jpeg\u0026lt;/uap:FileType\u0026gt; \u0026lt;/uap:SupportedFileTypes\u0026gt; \u0026lt;uap:DataFormat\u0026gt;StorageItems\u0026lt;/uap:DataFormat\u0026gt; \u0026lt;/uap:ShareTarget\u0026gt; \u0026lt;/uap:Extension\u0026gt; __ For more information about the \u0026ldquo;windows.shareTarget\u0026rdquo; category, see Microsoft’s docs on the subject. With this share target information, the app was listed in the Sharing sidebar when an image file was shared by another app. Selecting \u0026ldquo;Meme maker\u0026rdquo; in this sidebar would open Mememaker inside the sharing sidebar as shown here:\nFigure 6. Meme maker loaded inside Windows 10 sidebar\n__ Ultimately I opted not to include the \u0026ldquo;shareTarget\u0026rdquo; functionality in the finished app because it resulted in some peculiar behaviour when the app was opened in both the sharing sidebar and as a stand-alone app. Get the Meme Maker App On the Play Store\nIn the Windows Store\nIn the iTunes Store\nOn GitHub\nArchived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nCarlos — November 8, 2016 at 4:03 pm (permalink) Excelent.\nOne big step forward would be to read Exif rotation and correct the image accordingly, as this is something that happens very often. Most devices don’t actually rotate pictures, but mark them as such in the exif data.\nbryan — November 8, 2016 at 7:37 pm (permalink) Great tutorial Steve – thanks.\nShai Almog — November 9, 2016 at 7:31 am (permalink) Thanks.\nAFAIK we already do that implicitly in our capture implementation.\nCarlos — November 9, 2016 at 9:09 am (permalink) This is what I get in what should be a vertical pic…\nhttps://uploads.disquscdn.c…\nShai Almog — November 10, 2016 at 4:57 am (permalink) Looking at the code it seems to no longer be there, not sure why. I’ll have to ask on that.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/associating-your-app-with-file-extension-mime-types-iphone-android-windows/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/associating-your-app-with-file-extension-mime-types-iphone-android-windows/file-type-associations.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the compelling reasons to go native (vs say a web app) is to better integrate with the platform. One form of integration that is frequently handy is the ability register your app to handle certain file types so that it is listed as one of the options when a user tries to view a file of that type. Codename One supports this use case via the \u0026ldquo;AppArg\u0026rdquo; display property – the same, simple mechanism used for handling custom link types in your app.\u003c/p\u003e","title":"Associating Your App with File Extension/Mime Type on iPhone (iOS), Android \u0026 Windows"},{"content":"\nThis is inspired by this post that covers the process of creating different icons for different\nOS builds. But here I’d like to discuss the lowest common denominator and how we got it wrong!\nOn Android an icon can have any shape and often does, on iOS we usually expect a rounded corner look and on\nWindows we expect square icons. The thing is that iOS automatically crops the icon with round corners, so if you\nprovide a completely square icon it should work just fine.\nAs part of that we are tuning slightly the default icon that ships with Codename One to look like this:\nFigure 1. Square default icon\nThe main value is that this looks good on Windows, iOS and reasonable on Android. The alternative of Android\nstyle icons looks horrible on iOS and Windows.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-create-square-icons/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-create-square-icons/just-the-tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is inspired by \u003ca href=\"/blog/different-icons.html\"\u003ethis post\u003c/a\u003e that covers the process of creating different icons for different\u003cbr\u003e\nOS builds. But here I’d like to discuss the lowest common denominator and how we got it wrong!\u003c/p\u003e\n\u003cp\u003eOn Android an icon can have any shape and often does, on iOS we usually expect a rounded corner look and on\u003cbr\u003e\nWindows we expect square icons. The thing is that iOS automatically crops the icon with round corners, so if you\u003cbr\u003e\nprovide a completely square icon it should work just fine.\u003c/p\u003e","title":"TIP: Create Square Icons"},{"content":"\n30 is probably the perfect time to stop with Roman numerals…​ We don’t want to give search engines the wrong\nidea.\nThis has been a really busy week with the new Phoenix demo and quite\na few other developments. October is finally over and we are all back home from vacations \u0026amp; travels. We are still\nin \u0026ldquo;recovery mode\u0026rdquo; but looking at the pipeline we have pretty exciting things coming up!\nChen has made huge strides with the new GUI builder, to such an extent that we decided to release a plugin update\nand not just a regular update. We’ll write more next week about some of the changes that are included in this update.\nOn stack overflow things were as usual:\nHow to simulate click/tap in Codename One? Generally this sort of code should work fine unless something odd happens or a special case…​\nRead on stackoverflow…​\nDNS problems in Codename One This is quite misleading, it turns out that this is just another case of confusion over Apples strict HTTPS policy\nRead on stackoverflow…​\nMake Codename One text area full width When changing style values it is crucial to do this in both the selected and unselected modes\nRead on stackoverflow…​\nButton from an iframe in WebBrowser does not work Setting properties for browser options in a device dependent and we allow doing that to configure quite a few features on Android/iOS\nRead on stackoverflow…​\nNew Gui does not accept placement \u0026ldquo;Right\u0026rdquo; on a command This was a bug that Chen solved really quick, please report GUI builder bugs otherwise we can’t possibly refine the tool\nRead on stackoverflow…​\nDragging connected Lines together This was pretty unclear to me, it turns out the question was about multi-touch…​\nRead on stackoverflow…​\nPicker \u0026amp; GUI Builder, how to set the type Since the type property for picker objects are not exposed in the GUI Builder, what’s the proper way to set the type via code for a picker object placed using the GUI Builder? I’ve tried doing so …​\nRead on stackoverflow…​\nReceived exception: SSL handshake failed Server certificates and JavaSE are pretty confusing\nRead on stackoverflow…​\nNo animation with snapToGrid scrolling and tensileDragEnabled set to false I’m not so sure why this would happen but if my suggested workaround \u0026ldquo;works\u0026rdquo; then we might be able to fix this\nRead on stackoverflow…​\nThe codenameon demos under netbean 8.2 do not work This was a regression in the NetBeans plugin. We fixed it in recent updates and also mention a workaround in the post\nRead on stackoverflow…​\nCodename One Issue publishing ios 64 bit app on store I’m still not sure why he was getting this, we generate a 64+32 bit fat binary for appstore builds\nRead on stackoverflow…​\nImageViewer produce blank image on ipad but work fine on android and simulator These things usually happen due to corrupt images often due to assumptions about the behavior of InputStream that\nare misplaced\nRead on stackoverflow…​\nHow do I change the style of a floatingactionbutton? As luck would have it we just released an extensive demo where we styled it a lot. We also enhanced its style-ability\nquite a bit this week…​\nRead on stackoverflow…​\nSpeech Recognition simple example on Android in Codename One Most such issues (this one include) are due to permission problems\nRead on stackoverflow…​\nJar size 50MB limit I explained here why we set the limit at 50mb. Turns out that in this case it helped pinpoint a developer error\nRead on stackoverflow…​\nSelect an Audio File from File System This is much easier now with the new file picker cn1lib from Steve\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-30/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-30/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e30 is probably the perfect time to stop with Roman numerals…​ We don’t want to give search engines the wrong\u003cbr\u003e\nidea.\u003cbr\u003e\nThis has been a really busy week with the new \u003ca href=\"/blog/template-phoenix-ui.html\"\u003ePhoenix demo\u003c/a\u003e and quite\u003cbr\u003e\na few other developments. October is finally over and we are all back home from vacations \u0026amp; travels. We are still\u003cbr\u003e\nin \u0026ldquo;recovery mode\u0026rdquo; but looking at the pipeline we have pretty exciting things coming up!\u003c/p\u003e","title":"Questions of the Week 30"},{"content":"\nLast week a question came up in stackoverflow\nthat came out quite a few times before but this time I had a better answer thanks to the round border. After giving\nthat answer I recalled that I already wrote some code to implement badging in the FloatingActionButton\nbut never exposed it because of some bugs…​\nSo I took the time and looked at the bugs in that code, turns out it was pretty trivial to fix so the same sample\nI gave for stackoverflow can now look like this:\nForm hi = new Form(\u0026quot;Badge\u0026quot;); Button chat = new Button(\u0026quot;\u0026quot;); FontImage.setMaterialIcon(chat, FontImage.MATERIAL_CHAT, 7); FloatingActionButton badge = FloatingActionButton.createBadge(\u0026quot;33\u0026quot;); hi.add(badge.bindFabToContainer(chat, Component.RIGHT, Component.TOP)); TextField changeBadgeValue = new TextField(\u0026quot;33\u0026quot;); changeBadgeValue.addDataChangedListener((i, ii) -\u0026gt; { badge.setText(changeBadgeValue.getText()); badge.getParent().revalidate(); }); hi.add(changeBadgeValue); hi.show(); That’s shorter (mostly because of default styles) and pretty neat in general. It results in this:\nFigure 1. Badge floating button in action\nIdeally I’d like to continue this trend into validators and other builtin tools to use more of the builtin borders and\nmaterial icons. This is something we need to work on more as we move forward. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJoão Bastos — November 3, 2016 at 8:47 am (permalink) createBadge error. Is it missing \u0026ldquo;public\u0026rdquo; statement in the method? or i´m missing something here?\nShai Almog — November 4, 2016 at 5:47 am (permalink) Shai Almog says:\nSorry, I neglected to mention that this is landing in the Friday release today so when you get a new update the code should compile fine. You can use Update Client Libraries later today to get the update.\nJoão Bastos — November 4, 2016 at 8:43 am (permalink) João Bastos says:\nOk. Thanks Shai\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/badging-arbitrary-components/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/badging-arbitrary-components/badge-floating-button.png\"\u003e\u003c/p\u003e\n\u003cp\u003eLast week a question came up in \u003ca href=\"http://stackoverflow.com/questions/40256864/how-to-create-facebook-like-notification-badges-in-codenameone\" target=\"_blank\" rel=\"noopener noreferrer\"\u003estackoverflow\u003c/a\u003e\u003cbr\u003e\nthat came out quite a few times before but this time I had a better answer thanks to the round border. After giving\u003cbr\u003e\nthat answer I recalled that I already wrote some code to implement badging in the \u003ca href=\"/blog/floating-button.html\"\u003eFloatingActionButton\u003c/a\u003e\u003cbr\u003e\nbut never exposed it because of some bugs…​\u003c/p\u003e\n\u003cp\u003eSo I took the time and looked at the bugs in that code, turns out it was pretty trivial to fix so the same sample\u003cbr\u003e\nI gave for stackoverflow can now look like this:\u003c/p\u003e","title":"Badging Arbitrary Components"},{"content":"\nThe Phoenix theme had a FloatingActionButton with a gradient on top. This goes against the mostly flat material\ndesign spec but after looking at the design with a solid color I came to the conclusion that the designer was totally\nright to use a gradient in this case. Unfortunately we didn’t build that support into the FloatingActionButton.\nSo as part of that work I added a special mode to the RoundBorder that uses the parent UIID to draw the background.\nThis sounds like a \u0026ldquo;no brainer\u0026rdquo; but there is a catch: the round border needs to be \u0026ldquo;round\u0026rdquo;.\nGradient and image primitives don’t draw within a round shape, so the only solution was\nshape clipping which has a performance penalty as well\nthe associated problem of not working everywhere…​\nSo right now this is off by default as the behavior doesn’t work exactly the same on the JavaScript or Windows ports\nwhere shape clipping is still missing.\nTo enable this we need to change the border of the component by making it use the UIID. We need to do that\nfrom code using the RoundBorder.uiid(boolean) method. We can do this using:\nRoundBorder rb = (RoundBorder)fab.getUnselectedStyle().getBorder(); rb.uiid(true); If the background style of the round border includes a gradient or an image you will see the effects at once.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/gradient-image-background-floatingactionbutton/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/gradient-image-background-floatingactionbutton/gradients-image-background-floatingactionbutton.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe Phoenix theme had a \u003ca href=\"/blog/floating-button.html\"\u003eFloatingActionButton\u003c/a\u003e with a gradient on top. This goes against the mostly flat material\u003cbr\u003e\ndesign spec but after looking at the design with a solid color I came to the conclusion that the designer was totally\u003cbr\u003e\nright to use a gradient in this case. Unfortunately we didn’t build that support into the \u003ccode\u003eFloatingActionButton\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eSo as part of that work I added a special mode to the \u003ccode\u003eRoundBorder\u003c/code\u003e that uses the parent UIID to draw the background.\u003cbr\u003e\nThis sounds like a \u0026ldquo;no brainer\u0026rdquo; but there is a catch: the round border needs to be \u0026ldquo;round\u0026rdquo;.\u003c/p\u003e","title":"Gradient and Image Background on FloatingActionButton"},{"content":"\nThe Phoenix UI kit by\nAdrian Chiran is one of the best looking and most challenging\ntemplate UI’s I had to adapt in recent history. The breadth\nof the design is pretty challenging but it also has some elements that are really hard to adapt across platforms in\na portable way.\nIn fact, some elements only work on devices and don’t even work properly for the JavaScript port e.g. the floating\naction button gradient color and the round look of the walkthru UI.\nI’m pretty happy with the result though, notice that the JavaScript version you see on the right isn’t quite perfect\nso scroll down to the device screenshots below to see how it looks on my Android OPO device.\nDue to time constraints I didn’t port all th forms, I also converted one of the \u0026ldquo;forms\u0026rdquo; to a side menu which wasn’t\nvery clear from the design but worked well in production.\nUnlike previous demos I chose to use the GUI builder for most of this demo, as an experienced developer using\nGUI builders slows me down considerably and this made this demo harder to build. I also ran into quite a few\nissues in the current GUI builder which we will fix to improve the results for everyone. I’m not sure if the next\ntemplate will be GUI builder based but I’m confident we will make further use of the GUI builder for demos \u0026amp;\ntemplates moving forward.\nThe nice thing about this GUI builder is that it generates code so even if you prefer handcoded development\nyou can still look at the code without launching the GUI builder.\nYou can check out the demo page here which includes all the information including\nthe github page.\nRounded Walkthru Section This was probably the most challenging part of the demo, at first glance the UI for the walkthru form doesn’t look\nlike it will be too challenging but this becomes a problem when we start looking at different DPI’s/orientations.\nAt first I tried solutions such as masking the image but this created some issues –\nThe first mask I tried included only the top diagonal line and the round border. But this kept misaligning with the\nbottom text portion especially when running in problematic orientations/aspect ratios.\nI then tried creating a single image that would include the bottom and top part and draw the text above but this\ncreated a situation where the text would grow too much.\nThe problem here is that the design image on the top might run out of space entirely, in fact one of the biggest\ndesign changes we had to do was reduce whitespace so some UI’s would fit. Still in landscape on a low DPI phone\nthe top image won’t appear at all.\nThe solution I ended up using was a shape clipping for the round rectangle, this isn’t ideal and doesn’t work\nin the JavaScript port but it works almost universally. We install this with a background painter on the style\nagain not ideal, but it shows just how powerful Codename One can be in such situations.\nOnce this was in place we can just fill up the space we need for the text with the white background.\nIf I had the time to work on this I might have enlarged the text to fit for some cases, but this would require more\ndevice testing rinse/repeat and I spent way too much time on this form.\nFigure 1. The original design from the PSD\nFigure 2. Running on the iPhone 6 simulator skin (scroll down for device screenshots)\nFigure 3. iPhone 3gs simulator in landscape mode, the image disappears the content remains\nFloating Action Button The inbox form has a unique floating action behavior that is inconsistent with the default Android behavior:\nFigure 4. Floating Action Button popup\nAt first I thought about implementing it as a special layout but since this is a very special case I eventually decided\nto use padding to position the components in the the various locations. Since the UI can’t contain more than 3 elements\nthis sort of hack is pretty easy.\nStatus Form One of the last forms I worked on was the status form with the round progress indication, I chose to use the\nCN1CircleProgress cn1lib since it was there already and\nincluded the main UI element features.\nI thought about doing this manually and using the gradient design but after seeing the UI without the gradient\nI decided this wasn’t essential.\nThe bottom bar is a horizontal List that allows you to scroll thru the elements.\nI didn’t add some of the other elements of the design as similar elements already appear on the trending form\nand this seemed redundant.\nEnd Result Below are screenshots from my One Plus One Android device:\nFigure 5. Splash screen image (the logo rotates)\nFigure 6. Walkthru page 1\nFigure 7. Walkthru page 1 rotated to landscape\nFigure 8. Walkthru page 2\nFigure 9. Walkthru page 3\nFigure 10. Login UI\nFigure 11. Inbox\nFigure 12. Inbox with floating button clicked\nFigure 13. Sidemenu\nFigure 14. Calendar\nFigure 15. Trending\nFigure 16. Stats\nFinal Word There were a few pages and features I skipped due to lack of time and the approach to the 1mb limit in the jar\nsize. I was still able to stay below that despite the fact that this theme required quite a few images…​ We ended up with a\n706kb jar which is pretty small .\nMost of the stuff I skipped was more of the same, I also skipped the Map UI which is a subject for a post all\nby itself.\nI hope you find these posts useful and instructive specifically about the types of designs that can be achieved\nwith Codename One. As usual, if you have a specific question about a UI element or anything related to the design\nplease don’t hesitate to ask in the comments! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — November 2, 2016 at 1:26 am (permalink) That all looks good, but a more fundamental question is why do people want to use a PSD file ? I Googled using a PSD in a native Android app, and it’s not all that simple either.\nShai Almog — November 2, 2016 at 1:34 am (permalink) PSD is the output of Photoshop and other design tools that followed. It is a design format and as a result really bad for engineering tools that have very different concepts.\nIn 90% of the cases when you employ a designer you will get a PSD as a result. As you can see from the results this is very effective in improving the final look of the app…\nPSD is hard to adapt to any platform just like it’s hard to take any design and make it into a real product.\nTomas Fecko — November 2, 2016 at 9:14 am (permalink) this looks great, codenameone should also use modern looking templates like this in sample projects for eclipse, intelliJ idea… My first contact with codenameone was actually through those samples in intelliJ (for some reason as an engineer, I wanted to see the code samples first). When I saw that funny looking samples, I just left, didn’t wanted to look into this any more. The stuff I’m seeing here makes me want to look at it again…\nShai Almog — November 3, 2016 at 1:22 am (permalink) Thanks.\nI agree we need to add these to the plugins, it’s always a pain to package demos into the plugins but it’s worth it. The nice thing is that this entire demo fits in under 1mb so it won’t significantly impact the plugin size.\ntomm0 — November 11, 2016 at 12:24 am (permalink) This looks awesome! Is the code available anywhere?\nShai Almog — November 11, 2016 at 4:46 am (permalink) The link is in the demo page.\nIt’s also in the latest plugin version under the demos section for NetBeans/IDEA.\nsalah Alhaddabi — December 5, 2016 at 6:52 pm (permalink) Dear Shai,\nAllow me to say that I really dont understand what GUI builder you have used to build the forms.\nThe generated code seems a bit strange. It looks like it was built using the new GUI builder.\nI can not even edit any of the forms using the new GUI builder .\nFor example, the repaint method used within the splash form looks extremely complicated.\nI am not sure if we have to do the same thing just to show the infinite progress of the splash screen.\nThere is a lot of generated code that I would like to know how it was achieved.\nThanks in advance for any help.\nShai Almog — December 6, 2016 at 6:13 am (permalink) Hi,\nmost of the forms are GUI builder forms and should work \u0026ldquo;as is\u0026rdquo; however I needed to do quite a bit of handcoding on top of that to allow some of the more unique features. Everything that’s outside of the GUI builder code block was handwritten.\nThe GUI builder can do a lot but it can’t do everything on any platform/OS combination.\nsalah Alhaddabi — December 7, 2016 at 7:01 pm (permalink) Dear Shai,\nThanks for your helpful answer. One question remains though, do you mean you have used the new gui builder cuz I can not see any of the gui elements included in the theme.\nAnd if you have used the new gui builder, how can we edit the forms? When I try to edit them using the context menu and clicking on gui builder it says \u0026ldquo;Gui builder only works with GUI builder files created using the wizard\u0026rdquo;\nThanks again.\nShai Almog — December 8, 2016 at 6:21 am (permalink) Hi,\nthe new GUI builder doesn’t use the theme for UI elements see:\nhttps://www.codenameone.com…\nYou need to select a form java source file and then selecting the GUI builder.\nsalah Alhaddabi — December 8, 2016 at 6:43 am (permalink) Dear Shai,\nThat’s what I did with this application after downloading it from github into my netbeans IDE.\nI right click on any of the java file form files and chose gui builder but then I get a pop up with the following error message:\n\u0026ldquo;Gui builder only works with GUI builder files created using the wizard\u0026rdquo;\nShai Almog — December 9, 2016 at 7:53 am (permalink) Hi,\nI just tried this with a new project from the wizard and it worked with forms such as the inbox form.\nThe error message you are getting means that this is not a GUI builder form or that the .gui file matching this form is missing from the res directory.\nShai Almog — May 2, 2017 at 5:03 am (permalink) Hi,\nWhat’s the exception stack and what’s in the loop? Which line in your code does the stack point to?\nTakwa — May 17, 2020 at 4:07 pm (permalink) i tried to work with this project but thers no main classes found ..can anyone help me :/\nShai Almog — May 18, 2020 at 2:41 am (permalink) This is a Codename One project not a standard command line Java project. As such the main class includes the start(), stop() etc. methods.\nYou need to run it within an IDE with the Codename One plugin installed e.g. NetBeans where pressing play/debug \u0026ldquo;just works\u0026rdquo; and invokes init(Object), start() on launch.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/template-phoenix-ui/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/template-phoenix-ui/phoenixui-template.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe \u003ca href=\"https://www.dropbox.com/s/fmkzvoy1n2gqjtb/PheonixUI-vol1-PSD.psd\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ePhoenix UI kit\u003c/a\u003e by\u003cbr\u003e\n\u003ca href=\"https://twitter.com/adrianchiran\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eAdrian Chiran\u003c/a\u003e is one of the best looking and most challenging\u003cbr\u003e\n\u003ca href=\"/blog/template-mobile-material-screens-ui-kit.html\"\u003etemplate UI’s\u003c/a\u003e I had to adapt in recent history. The breadth\u003cbr\u003e\nof the design is pretty challenging but it also has some elements that are really hard to adapt across platforms in\u003cbr\u003e\na portable way.\u003cbr\u003e\nIn fact, some elements only work on devices and don’t even work properly for the JavaScript port e.g. the floating\u003cbr\u003e\naction button gradient color and the round look of the walkthru UI.\u003c/p\u003e","title":"Template – Phoenix UI"},{"content":"\nSome designs don’t work well in landscape/portrait mode and we need to adapt them to fit the orientation of\nthe device e.g. when we have a large graphic element (icon etc.) on top/below and we no longer have room\nfor that element.\nAs an example check out the code below:\nForm hi = new Form(\u0026quot;Swap\u0026quot;, new BorderLayout()); hi.add(BorderLayout.NORTH, FlowLayout.encloseCenter( new Label(duke.scaledWidth(Display.getInstance().convertToPixels(40))))); hi.add(BorderLayout.CENTER, ComponentGroup.enclose( new TextField(\u0026quot;\u0026quot;, \u0026quot;Username\u0026quot;), new TextField(\u0026quot;\u0026quot;, \u0026quot;Password\u0026quot;, 20, TextField.PASSWORD) )); hi.show(); It produces this image in portrait which matches our expectations:\nFigure 1. Portrait mode border layout image\nWhen we rotate the device though, things go south…​ Literally:\nFigure 2. In landscape mode the image hides the actual content of the UI\nThe thing is that there is plenty of space in landscape it is just distributed differently, so if the image was on the east\ninstead of the north position it would \u0026ldquo;just work\u0026rdquo;. That’s exactly what swap border position does. By using this\ncode the component in the north will automatically shift positions when the device is in landscape mode:\nBorderLayout bl = new BorderLayout(); Form hi = new Form(\u0026quot;Swap\u0026quot;, bl); bl.defineLandscapeSwap(BorderLayout.NORTH, BorderLayout.EAST); Figure 3. Automatic position swapping with the defineLandscapeSwap method\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-border-layout-can-adapt-orientations/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-border-layout-can-adapt-orientations/just-the-tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSome designs don’t work well in landscape/portrait mode and we need to adapt them to fit the orientation of\u003cbr\u003e\nthe device e.g. when we have a large graphic element (icon etc.) on top/below and we no longer have room\u003cbr\u003e\nfor that element.\u003c/p\u003e\n\u003cp\u003eAs an example check out the code below:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eForm hi = new Form(\u0026quot;Swap\u0026quot;, new BorderLayout());\n\nhi.add(BorderLayout.NORTH,\n        FlowLayout.encloseCenter(\n                new Label(duke.scaledWidth(Display.getInstance().convertToPixels(40)))));\n\nhi.add(BorderLayout.CENTER,\n        ComponentGroup.enclose(\n                new TextField(\u0026quot;\u0026quot;, \u0026quot;Username\u0026quot;),\n                new TextField(\u0026quot;\u0026quot;, \u0026quot;Password\u0026quot;, 20, TextField.PASSWORD)\n        ));\n\nhi.show();\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIt produces this image in portrait which matches our expectations:\u003c/p\u003e","title":"TIP: Border Layout can Adapt to Orientation"},{"content":"\nThis was a busy week with a lot of work going on under the hood especially on the new GUI builder.\nWe are also working on a pretty cool new demo that we’ll ideally launch next week. Our release today\nonly includes the libraries making it smaller, we would probably release a plugin update next Friday as there\nare many changes that warrant an update.\nOn stack overflow things were as usual:\nPush notifications not registering on ios 10 We have users with iOS 10 devices so this is probably not the case\nRead on stackoverflow…​\nModal Dialog does not appear EDT violations are typically the reason for this\nRead on stackoverflow…​\nHow to create Facebook-like notification badges in CodenameOne This is a frequent enough question it warrants a sample\nRead on stackoverflow…​\nLaunching touch events programatically These sort of things are really easy in Codename One thanks to the lightweight nature of the framework\nRead on stackoverflow…​\nCenter a label in the south container of a border layout in Codename One The need for revalidate() on changes is often confusing to developers but it is pivotal to Codename One\nRead on stackoverflow…​\nUnable to use jar When using a native jar code completion won’t work but it should be there…​\nRead on stackoverflow…​\nHow to integrate Other Ads network on codename one app The best place to start is to look at sample cn1libs that we already integrated\nRead on stackoverflow…​\nWhich app store? We don’t provide an API to return the source appstore URL at this time, it’s not quite portable as far as I can tell\nRead on stackoverflow…​\nURLImage fetch method not working We clarified the JavaDocs for the fetch method to make it clear that this isn’t the way it would behave\nRead on stackoverflow…​\nTrouble reading from Storage There are posts where you are given a lot of information and are missing just the one tiny bit that would help you\nanswer…​\nRead on stackoverflow…​\nHow to insert data in codename one db using prepared statement? That’s an interesting behavior of the sqlite implementation\nRead on stackoverflow…​\nAfter latest update the java file from the gui do strange things We had a regression in the GUI builder that shipped with the 3.5.5 plugin which is why we had to push an update\nshortly after\nRead on stackoverflow…​\nGoogleAds Does’t show up This frustrating issue is caused by the https restrictions of iOS\nRead on stackoverflow…​\nStorage throwing EOF \u0026amp; NullPointer Exception There are specific API’s that are substituted by the externalization code\nRead on stackoverflow…​\nCodename one expect feature on DateTime Component The picker is problematic as it is a native widget, we can’t offer anything that isn’t offered by the native OS\nRead on stackoverflow…​\nHow to add text to the textfield inside dataChangedListener in codename one? I am using TextField and on addDataChangedListener I am trying to add some character to the text field if length of the text field is 2 but it is not working for me.can you please help me how to …​\nRead on stackoverflow…​\nWorkaround for applying a mask to an image in Codename One There are some complex image modes in Codename One but most of them are convertable to standard raster images\nRead on stackoverflow…​\nHow do I restore a deleted multi-image We generally recommend keeping the res directory in source control so this dosen’t become an issue\nRead on stackoverflow…​\nFloatingActionButton Sub can’t call another form in Codename One This should have been serialized with the dialog disposal code, it should be fixed now\nRead on stackoverflow…​\nHow to get app version (Play / iTunes) stores using Codename one We don’t know the itunes version but we can give you the Codename One version of the app.\nRead on stackoverflow…​\nHow to resolve null when using webservices in codename one This is a bit of a long thread, kudos to Diamond for taking the time on this\nRead on stackoverflow…​\nBack navigation does not stop youtube video in WebBrowser This is turning into a FAQ, the destroy() method closes the browser completely\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xxix/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xxix/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis was a busy week with a lot of work going on under the hood especially on the new GUI builder.\u003cbr\u003e\nWe are also working on a pretty cool new demo that we’ll ideally launch next week. Our release today\u003cbr\u003e\nonly includes the libraries making it smaller, we would probably release a plugin update next Friday as there\u003cbr\u003e\nare many changes that warrant an update.\u003c/p\u003e\n\u003cp\u003eOn stack overflow things were as usual:\u003c/p\u003e","title":"Questions of the Week XXIX"},{"content":"\nCodename One’s resource files contain a lot of details but it’s sometimes hard to add elements into the resource\nfile automatically. Recently I wanted to add a better way to add images directly in the new GUI builder. I considered\nseveral options and eventually decided to operate the designer tool automatically to do the \u0026ldquo;heavy lifting\u0026rdquo;.\nI’m not the first person to try this though, some Codename One users automate tasks by generating the theme\nand UI XML’s to automatically scaffold an app.\nSidebar: Resource File XML\nThe resource file is a binary format which is very efficient for device consumption but not very convenient for\ncode generators or source control. To solve that we created the XML Team Mode (you can toggle it under\nthe File menu in the designer tool), when it is active and you open a resource file the tool starts\nby looking under the res directory for an XML file matching the resource file name and loads that instead of\nthe binary resource file.\nSaving is done both into the XML and the binary res file thus preserving device compatibility. This allows you to\ncommit the XML and free form files into version control and handle conflicts more elegantly.\nThe Command Line The Codename One plugin automatically installs the designer in the users home directory. You can invoke\nthe designer from the command line on Linux/Unix using:\njava -jar ~/.codenameone/designer_1.jar For Windows you would do something similar as:\njava -jar c:Usersmyuser.codenameonedesigner_1.jar From this point on I’ll use the unix/linux notation which is slightly shorter and should be easily understandable.\nGenerating a Resource file From XML You can scaffold a project resource file relatively easily by building all of the element XML’s within the res\ndirectory of the project and then force the creation of an up to date resource file by invoking the designers\n-regen command line.\nThis is useful for wizards or tools that customize a theme.xml file and then want to save the changes directly\nso it is visible in the UI without the user having to re-open the res file and save it.\njava -jar ~/.codenameone/designer_1.jar -regen path-to-my-file.res This will take the XML files and regenerate the res file with their modifications.\nVersion The -buildVersion returns the designer tool version, this might be important if you depend on features/behaviors\nof a specific version. Notice that this is an integer sequential version that doesn’t match the general version\nnumber!\nThe version is based on the date as YYYYMMDD which makes it completely sequential e.g.:\njava -jar ~/.codenameone/designer_1.jar -buildVersion Produces:\n20161021 Image Import You can just import an image directly into a resource, notice that this is done one by one so if you want to add\nmultiple images you need to do so one at a time. Also notice that this command doesn’t check if the designer\nis already running or if the file is already open which means an open copy of the designer might erase the changes\nmade by the command…​\nYou can add a regular image thru a command such as:\njava -jar ~/.codenameone/designer_1.jar -img path-to/theme.res path-to/image.png image.png The last argument is the name of the image in the resource file, it’s optional and if you leave it out the name will\nuse the file name.\nThis will add a regular image, you can add a multi-image in a similar way to the \u0026ldquo;quick add\u0026rdquo; method in the designer\nby using the following command:\njava -jar ~/.codenameone/designer_1.jar -mimg path-to/theme.res hd path-to/image.png The hd argument represents the source size of the image we are adding which allows the system to decide on\nthe way to adapt it. The following DPI arguments are supported: high, veryhigh, hd, 560, 2hd \u0026amp; 4k.\nFuture Progress We will add more features to the designer command line as we move forward to address more capabilities and\nextract automation to simpler cleaner tools.\nRight now the designer includes in it a great deal of legacy within one monolithic tool so the right thing to do\nis to break it down piece by piece. The first piece is naturally the GUI builder.\nLocalization, theming, image management etc. should slowly separate into smaller tools. This is easier to do\nif we can just modularize the pieces thru a simple command line interface \u0026amp; as a side advantage it also makes\nit easier for you guys to automate some of your recurring tasks.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/using-designer-command-line-options/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/using-designer-command-line-options/designer-tool-command-line.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One’s resource files contain a lot of details but it’s sometimes hard to add elements into the resource\u003cbr\u003e\nfile automatically. Recently I wanted to add a better way to add images directly in the new GUI builder. I considered\u003cbr\u003e\nseveral options and eventually decided to operate the designer tool automatically to do the \u0026ldquo;heavy lifting\u0026rdquo;.\u003c/p\u003e\n\u003cp\u003eI’m not the first person to try this though, some Codename One users automate tasks by generating the theme\u003cbr\u003e\nand UI XML’s to automatically scaffold an app.\u003c/p\u003e","title":"Using the Designers Command Line Options"},{"content":"\nI’ve recently noticed that distribution build sizes were identical for appstore and debug builds which wasn’t the case\nbefore the xcode 7.x migration we did a while back. This shouldn’t be the case as it indicates that the standard\ndebug builds include both the 64bit and 32bit code which is redundant during debugging.\nWe made some changes that should apply for the next update this Friday that might double build speed for some of\nyou as it will do less work during compiling but also produce a smaller binary.\n__ | I would also recommend unchecking \u0026ldquo;include source\u0026rdquo; which slows down the build as the zip and upload of\na huge file slows down the whole process GUI Builder Update I wanted to put out a new demo today and I have something really nice on the way…​ But then we decided to do it\nwith the GUI builder which resulted in about 15 issues so far.\nSo the good news is that we are improving the GUI builder and tracking down bugs/inconveniences etc. The bad\nnews is that we’ll need to wait for a nice new demo for next week as this is pretty difficult.\nWe also added quite a few cool new features to the GUI builder such as:\nAbility to refresh to see the list of images added to the designer\nAbility to add a new image directly from the GUI builder without launching the designer\nUIID editing that allows us to pick from a list of UIID’s in the theme\nAnd quite a few other features.\nSQL Updates Steve made some changes to the SQL Javadocs to clarify some SQL limitations in the JavaScript port.\nBesides the lack of portability for the SQL support there (due to the fact that SQL is not an official W3C standard),\nthere are two big issues:\nTransactions can’t be mapped properly – the browser support for SQL wraps transactions in a very different way\nand this can’t map to the Java side.\nThere is no database file so the trick of shipping a database file with your app and installing it won’t work!\nIdeally I’d love for us to have a better object persistence solution that will remove the need for SQL in the long\nterm. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nNick Koirala — October 27, 2016 at 3:40 am (permalink) Nick Koirala says:\nWhat sort of solution are you thinking for an SQL replacement? The advantage of SQL in my mind compared to key/value storage is complex querying of the data. Its possible in NoSQL solutions of course, but they seem complicated to embed in platforms that (almost) all support SQLite. But a better solution is of course welcome, there are quirks and issues with SQLite – though I use it extensively as I don’t know of any good alternatives.\nShai Almog — October 28, 2016 at 3:43 am (permalink) Shai Almog says:\nWe considered a lot of options but haven’t made a choice yet. While all platforms support a form of sqlite this is misleading as the functionality varies a lot resulting in device issues which is what we try to avoid.\n1. Offering hsql or a similar javadb as a cn1lib or even builtin – this will probably increase the dist size a bit so I’m a bit weary of it. I’m not too crazy about SQL either.\n2. Supporting one of the leading mobile object DB’s e.g. realm – While this has value this might be a problem as none of them is nearly as portable as we are e.g. the JavaScript port is always problematic.\n3. Build a simple Object storage maybe on top of something else – I’m hesitant to go into something like that. It’s not hard but those are famous last words…\nNick Koirala — October 28, 2016 at 3:43 am (permalink) Nick Koirala says:\niOS 10.1 shows a message ‘This app may slow down your iPhone’ if its a 32bit build. sigh I guess it only affects debug / ad-hoc builds but it is a bit dumb.\nAkinniranye James — November 1, 2016 at 3:51 pm (permalink) Akinniranye James says:\nWill vote for 1\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/faster-ios-builds-gui-builder-improvements-sql-updates/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/faster-ios-builds-gui-builder-improvements-sql-updates/generic-java-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve recently noticed that distribution build sizes were identical for appstore and debug builds which wasn’t the case\u003cbr\u003e\nbefore the xcode 7.x migration we did a while back. This shouldn’t be the case as it indicates that the standard\u003cbr\u003e\ndebug builds include both the 64bit and 32bit code which is redundant during debugging.\u003c/p\u003e\n\u003cp\u003eWe made some changes that should apply for the next update this Friday that might double build speed for some of\u003cbr\u003e\nyou as it will do less work during compiling but also produce a smaller binary.\u003c/p\u003e","title":"Faster iOS Builds, GUI Builder Improvements \u0026 SQL Updates"},{"content":"\nBoth TechCrunch \u0026amp;\nEngaget report that\nsurface sold well during the last quarter when contrasting it’s sales of 926M to 4.9B iPad sales.\nBut the number is a bit misleading as the surface is really comparable to the iPad pro line in terms of pricing/target market\nand I would guess the sales are very close and might have exceeded those of the Apple device.\nThis is important since both devices target the very lucrative enterprise/professional user market and both require\ntouch friendly apps. Both are hard to reach for Java developers and as such Codename One is the only solution\nthat can properly natively address both…​\nThis is fact is further highlighted by the recent news that\nOracle is now bundling adware into the JRE distribution\nmaking Java even less viable on the desktop.\nWhile Windows Mobile might never catch up to iOS or Android surface might bring a fresh set of users who\nwere stuck in the past up until now.\nAn influx of users looking for apps to install is a very profitable place to be in…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/surface-sales-java-adware/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/surface-sales-java-adware/universal-windows-platform.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eBoth \u003ca href=\"https://techcrunch.com/2016/10/20/microsofts-surface-business-skyrockets-as-the-ipads-slow/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eTechCrunch\u003c/a\u003e \u0026amp;\u003cbr\u003e\n\u003ca href=\"https://www.engadget.com/2016/10/20/microsofts-surface-business-is-still-booming/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eEngaget\u003c/a\u003e report that\u003cbr\u003e\nsurface sold well during the last quarter when contrasting it’s sales of 926M to 4.9B iPad sales.\u003c/p\u003e\n\u003cp\u003eBut the number is a bit misleading as the surface is really comparable to the iPad pro line in terms of pricing/target market\u003cbr\u003e\nand I would guess the sales are very close and might have exceeded those of the Apple device.\u003c/p\u003e\n\u003cp\u003eThis is important since both devices target the very lucrative enterprise/professional user market and both require\u003cbr\u003e\ntouch friendly apps. Both are hard to reach for Java developers and as such Codename One is the only solution\u003cbr\u003e\nthat can properly \u003cstrong\u003enatively\u003c/strong\u003e address both…​\u003c/p\u003e","title":"Surface Sales and Java Adware"},{"content":"\nThis isn’t a programming tip, but since we discussed photoshop quite a few times before\nit’s probably an important subject. Especially because we made this exact mistake in those tutorials and\nI’ve spent the better part of the day tracking this with no result…​\nI’ve worked on extracting UI’s from PSD files for a while now and I was on my way to build a new UI when suddenly\nI noticed my theme file was HUGE. Not just \u0026ldquo;big\u0026rdquo;, HUGE.\nLooking at the images I’ve noticed they were ridiculously big so I started doing the typical things (bluring, scaling,\nreducing quality) all of which didn’t work until I was able to come up with an odd workaround by saving as\nJPEG2000 and then resaving as a regular file.\nThen I noticed that this didn’t just impact JPEG files…​ PNG files that contained nothing other than black and white\npixels were over 800kb in size!\nThat’s when the hex editor came up and showed that something was really broken, the file was filled with gibberish\nmeta-data that I was able to find in the photoshop UI but there is no place to edit this data.\nI was eventually able to find this and several other sources that confirmed\nthat this behavior is \u0026ldquo;by design\u0026rdquo; which is insane…​ I found no way to remove the meta-data or edit it after the fact.\nEven OptiPNG wouldn’t remove it!\nSo the solution is simple if a bit obtuse, when you are ready to export an image always use File → Export \u0026amp;\nnever use File → Save As. Notice that this only impacts regular images. Multi-Images are automatically\nconverted and are not impacted as a result.\nEdit in Photoshop If we are already on the subject of photoshop here is another tip that has been there since before Codename One\nbut most developers are probably unfamiliar with…​\nYou can edit every image File directly in photoshop without re-importing or any complex task. To do so just\nuse the Edit button above the image. This also works for multi-images although obviously it only impacts\none of the resolutions.\nFor this to work the default action for PNG/JPG in your system must be photoshop (or GIMP if you are so inclined)\nwe implicitly do the rest. Just edit the file and save to see the changes reflected in the designer tool.\n__ This might not work in Linux due to the horrible support of the JavaSE Desktop API in Linux Figure 1. You can edit images from the designer tool directly in Photoshop\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-dont-use-file-save-as-in-photoshop/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-dont-use-file-save-as-in-photoshop/just-the-tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis isn’t a programming tip, but since we \u003ca href=\"/blog/psd-to-app-revisited.html\"\u003ediscussed photoshop quite a few times before\u003c/a\u003e\u003cbr\u003e\nit’s probably an important subject. Especially because we made this exact mistake in those tutorials and\u003cbr\u003e\nI’ve spent the better part of the day tracking this with no result…​\u003c/p\u003e\n\u003cp\u003eI’ve worked on extracting UI’s from PSD files for a while now and I was on my way to build a new UI when suddenly\u003cbr\u003e\nI noticed my theme file was \u003cstrong\u003eHUGE\u003c/strong\u003e. Not just \u0026ldquo;big\u0026rdquo;, \u003cstrong\u003eHUGE\u003c/strong\u003e.\u003c/p\u003e","title":"TIP: Don't use File – Save As in Photoshop, only use Export"},{"content":"\nUnlike last week this has mostly been a calm week with the exception of some downtime we had on the\ncertificate wizard (Apple tightened TLS access) there was hardly anything major going on. We are focusing\na lot of our efforts on refining our offering on all fronts e.g.\nbetter demos,\nthemes,\ndocs, compatibility and\ntools.\nThings will probably stay relatively easy until November although I think a big focus will shift into handling\nsome of the bugs we have lined up for 3.6.\nDue to some painful regressions in the GUI builder we decided to release another plugin update which isn’t ideal as\nwe try to release as few of those as possible and focus on library updates which are more lightweight. Hopefully\nthis will be the last update before mid November.\nOn stack overflow things were as usual:\nApp broken after iOS build This might have happened because sending a build updates the libraries if there is a new version. This is a\nproblem that occasionally happens on NetBeans where the AST cache gets corrupted. It’s solvable in\nNetBeans by removing the caches, not sure how that’s done in intellij\nRead on stackoverflow…​\nBack navigation does not stop youtube video in WebBrowser The browserComponent.destroy() isn’t very intuitive\nRead on stackoverflow…​\nPreference class picks wrong method When we built this API initially it looked like a good idea to name all the methods with the same name\nand differentiate them by argument type, in retrospect that was a mistake…​\nRead on stackoverflow…​\nApp version number programmatically I’m not sure how we can make this simpler, I’ve thought about adding a dedicated API but people don’t find\ngetUDID() either…​\nRead on stackoverflow…​\nNSAllowsArbitraryLoadsInWebContent in CN1 That’s exactly the use case for ios.plistInject\nRead on stackoverflow…​\nUsing CN1 bluetooth is not scanning devices on Android Bluetooth is a bit painful as an API\nRead on stackoverflow…​\nSSL error- Connention reset by peer on using Generate Certificates for ios builds We had an issue with Apple servers just in the week Steve took off on vacation. Luckily he stepped in because\nI was totally on the wrong track here…​\nRead on stackoverflow…​\nAutoCompleteTextField does not respect minimum length on load This should be fixed by now with the new update\nRead on stackoverflow…​\nAutocomplete text field firing selection event on load This is related to text field events that are \u0026ldquo;over eager\u0026rdquo; and would fire twice rather than miss a change\nRead on stackoverflow…​\nHow can I access sqlite database on a webserver in codename one We get a lot of questions on accessing remote DBMS’s on servers. I’d love to have a short decent explanation\non why this is a bad idea without going into NAT’s, security and the other problems.\nRead on stackoverflow…​\nPass Data to other Forms and update Form We might want to create a post with a discussion of the best practices for state within an application but this\nis a bit of a big subject\nRead on stackoverflow…​\nHow to mock server / http requests in Codename One for testing? Our mock testing tools are non-existant which is a shame. We should have a mock implementation of Codename One\nand it should be pretty trivial to build…​\nRead on stackoverflow…​\nHow I can access to the webcam in cn1 windows desktop build? JavaSE/FX is pretty problematic about basic things like that…​\nRead on stackoverflow…​\nSlider control: border is invisible until I press and drag it There is an open issue on this in github which we really need to fix by now…​\nRead on stackoverflow…​\nCodename One AnalyticsService suddenly completely blocks the application flow Sometimes these things are really hard to track…​\nRead on stackoverflow…​\nHow to access sqlite database from webserver and insert record using web services in codenameone This question seems to confuse the use of sqlite and webservices\nRead on stackoverflow…​\nHow to modify the height of the statusbar in codenameone? We made this even easier in the recent update where we provided fine grained control over the status bar\nRead on stackoverflow…​\nCodenameOne Background color This is a huge deficiency in the designer tool, it should prevent users from changing the color when a border\nis in effect\nRead on stackoverflow…​\nCodenameOne playing video / size and position We made some improvements to video playback that were required due to regression we got after the new-peer switch\nRead on stackoverflow…​\nCodename one list scrolled down when returning to form If this is with the old GUI builder then I have a good answer but you need to ask the right question…​\nRead on stackoverflow…​\nHow to bundle sounds with Codename One? You can play arbitrary media files easily\nRead on stackoverflow…​\nApp launch on startup in codename one This seems to be a common request but not really doable across platforms\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xxviii/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xxviii/qanda-friday2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eUnlike last week this has mostly been a calm week with the exception of some downtime we had on the\u003cbr\u003e\ncertificate wizard (Apple tightened TLS access) there was hardly anything major going on. We are focusing\u003cbr\u003e\na lot of our efforts on refining our offering on all fronts e.g.\u003cbr\u003e\n\u003ca href=\"/sql-playground-sql-tutorial-in-the-browser-iphone-ios-android-windows/\"\u003ebetter demos\u003c/a\u003e,\u003cbr\u003e\n\u003ca href=\"/blog/template-clean-modern-ui-kit.html\"\u003ethemes\u003c/a\u003e,\u003cbr\u003e\n\u003ca href=\"/manual/\"\u003edocs\u003c/a\u003e, \u003ca href=\"/blog/file-url-java-mobile-compatibility.html\"\u003ecompatibility\u003c/a\u003e and\u003cbr\u003e\n\u003ca href=\"/blog/further-refined-cross-platform-mobile-gui-builder.html\"\u003etools\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eThings will probably stay relatively easy until November although I think a big focus will shift into handling\u003cbr\u003e\nsome of the bugs we have lined up for 3.6.\u003c/p\u003e","title":"Questions of the Week XXVIII"},{"content":"\nI explained why we don’t support the full Java API\n(and the difficulties involved) not so long ago. The logic behind this is solid. However, the utility of porting\nexisting Java code to Codename One is also with a lot of merit.\nWe try to strike a balance between portability, compatibility to the Java API etc. and that is a very delicate\nbalance. To improve the situation we created two new classes: com.codename1.io.File \u0026amp; com.codename1.io.URL.\nThey are meant to be drop-in replacements for java.io.File \u0026amp; java.net.URL to help you port existing code.\nThis doesn’t mean that every API will work or behave as you expect as the mapping is sometimes counter intuitive\ne.g. File works with relative paths which we don’t support. We had some thoughts about the \u0026ldquo;right way\u0026rdquo; to\nimplement the URL API and eventually decided to use our internal synchronous API and not the high level\nConnectionRequest API.\nThat means that the URL API can block the EDT (illegally) and should be used with caution. This makes it\nmore compatible with the JavaSE API of the same name. This also means that using URL should be completely\nseparate from ConnectionRequest and will not block the network thread when you do so.\nWe’d like to start looking at big ticket Java libraries that people use that we can port to Codename One. So we\ncan learn from the process and provide both \u0026ldquo;best practices\u0026rdquo; and better support from within.\nIf you have a wishlist of a jars you want to use in Codename One let us know and we’ll add them to the consideration.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/file-url-java-mobile-compatibility/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/file-url-java-mobile-compatibility/port-java-code.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI explained \u003ca href=\"/blog/why-we-dont-support-the-full-java-api.html\"\u003ewhy we don’t support the full Java API\u003c/a\u003e\u003cbr\u003e\n(and the difficulties involved) not so long ago. The logic behind this is solid. However, the utility of porting\u003cbr\u003e\nexisting Java code to Codename One is also with a lot of merit.\u003c/p\u003e\n\u003cp\u003eWe try to strike a balance between portability, compatibility to the Java API etc. and that is a very delicate\u003cbr\u003e\nbalance. To improve the situation we created two new classes: \u003ccode\u003ecom.codename1.io.File\u003c/code\u003e \u0026amp; \u003ccode\u003ecom.codename1.io.URL\u003c/code\u003e.\u003cbr\u003e\nThey are meant to be drop-in replacements for \u003ccode\u003ejava.io.File\u003c/code\u003e \u0026amp; \u003ccode\u003ejava.net.URL\u003c/code\u003e to help you port existing code.\u003c/p\u003e","title":"File and URL for Better Java Mobile Compatibility"},{"content":"\nThe SQL demo has been on my \u0026ldquo;todo\u0026rdquo; list for months. It’s really hard to create a compelling demo for something\nas boring (by design) as SQL so this was a big procrastination target. After we built the SQL explorer tool for the developer\nguide it became apparent to me that this could be the basis for the new SQL demo, just provide the ability to\ntype in arbitrary SQL and see it work…​\nHowever, this doesn’t provide enough as beginners might not grasp the full scope of the capabilities, so to make\nthis interesting we added a special tutorial mode that just shows you the queries you can execute. I initially wanted\nto do something more elaborate like a walkthru tutorial but time constraints blocked that option.\nYou’ll notice that I’m not embedding the JavaScript version of the demo into this post although you can see it from\nthe demo page. The reason for that is unique.\nBrowsers don’t support SQL, there was an attempt at getting a standard out but it didn’t last and all vendors\ndeprecated their respective SQL support although some still kept it (notably Chrome \u0026amp; Safari). So the demo\nworks well on Chrome \u0026amp; Safari but not on Firefox (no idea about IE/Edge). There are also a couple of bugs in the\nSQL support in the JavaScript port making the situation slightly worse.\nOne of the things we were able to achieve is to make the demo submittable to app stores and as a result it’s\nalready on\nGoogle Play,\nMicrosoft Store and on\nitunes.\nCheck out the full source code in the github repository for the project.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/sql-demo-revisited/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/sql-demo-revisited/sql-playground.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe SQL demo has been on my \u0026ldquo;todo\u0026rdquo; list for months. It’s really hard to create a compelling demo for something\u003cbr\u003e\nas boring (by design) as SQL so this was a big procrastination target. After we built the SQL explorer tool for the developer\u003cbr\u003e\nguide it became apparent to me that this could be the basis for the new SQL demo, just provide the ability to\u003cbr\u003e\ntype in arbitrary SQL and see it work…​\u003c/p\u003e","title":"SQL Demo Revisited"},{"content":"\nIn the previous template post I introduced a material\ndesign inspired theme. This time the theme I chose is simpler \u0026ldquo;cleaner\u0026rdquo; but not necessarily easier to integrate.\nI’ve had quite a few difficulties wrestling with Photoshop oddities (bugs?) that made this template painful,\nhopefully I’ve narrowed down the process enough so this should become easier.\nThe PSD I chose this time is the Clean Modern\nUI Kit which is heavy on background images and a minimalist on all other aspects. You can check out the\nfull git repository of the work here.\nAs usual you can check out the full app running on the right thanks to the JavaScript port and device screenshots\nat the bottom of this post…​\nPorting the theme was relatively simple and I had very few issues, I made several choices that were interesting\nin the design so I’ll go over them below.\nDisabled Global Toolbar I used the Toolbar in the demo but disabled it’s global default. I did this so I can create my own Toolbar instances\nusing the layered mode which we create using new Toolbar(true).\nThis allows the Toolbar to hover on top of the UI and is very useful for a transparent Toolbar effect where the UI\nis drawn under the Toolbar.\nE.g. we use this in the news \u0026amp; profile page. In those pages we could have styled the Toolbar to have the image within\nit instead of taking this approach. However, that would have made some effects harder to customize.\nFigure 1. The Toolbar in the news page\nArrow Down Effect One of the more challenging effects was the arrow bar pointing downwards at the selection.\nFigure 2. The arrow bar\nI started off by looking at this as a Tabs Container but eventually chose to use a set of RadioButton components\nin toggle button mode. The main challenge is positioning the arrow in the \u0026ldquo;exact\u0026rdquo; center. We have an\narrow border feature but it’s a bit clunky and I didn’t want to make use of that (rewriting this is on my personal\n\u0026ldquo;todo list\u0026rdquo;).\nThe arrow is really just a label aligned to the bottom whose padding I change based on radio button selection and\ndevice orientation.\nOnOffSwitch One painful point was the on-off switch design which I was too lazy to replicate with our OnOffSwitch.\nI ended up using a toggle button with two image states which isn’t a good solution.\nI’m thinking about rewriting the OnOffSwitch code to use the new capabilities of the API such as RoundBorder\nand possibly shape clipping. I’m not sure when we’ll get around to it as there is so much work and this is a non-trivial\ntask.\nEnd Result Below are screenshots from my One Plus One Android device, notice the way the UI adapts to landscape mode\nas well.\nFigure 3. Walkthru Page 1\nFigure 4. Walkthru Page 2\nFigure 5. Walkthru Page 3\nFigure 6. Login page\nFigure 7. Signup page\nFigure 8. Authentication Page\nFigure 9. Newsfeed\nFigure 10. Sidemenu\nFigure 11. Profile\nFigure 12. Landscape profile\nFigure 13. Landscape newsfeed\nFinal Word This took longer to build than I’d hoped mostly because of photoshop oddities and the sheer number of forms.\nIn the future I might limit the number of forms just to get stuff out of the way.\nMany of these forms are repetitive and I skipped at least two forms from the design which I just couldn’t\ncomplete in time. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — October 19, 2016 at 12:50 am (permalink) bryan says:\nJust downloaded onto a device, and it looks nice. Good job.\nRoss Taylor — October 19, 2016 at 9:27 am (permalink) Ross Taylor says:\nI was playing with the javascript port of the app from the browser. It looks good, but the app froze in the browser when accessing profile info and clicking on the search button. Not sure if this is the exact cause.\nShai Almog — October 20, 2016 at 2:10 am (permalink) Shai Almog says:\nThanks, I just added a search button for the look and didn’t test it.\nTurns out that the search bar feature doesn’t work with the layered toolbar mode\nleroadrunner — November 1, 2016 at 2:43 pm (permalink) leroadrunner says:\nGetting a \u0026ldquo;cannot find symbol\u0026rdquo; in NewsfeedForm\nComponent.setSameSize(radioContainer, spacer1, spacer2);\nI updated to latest plugin…what I am missing?\nShai Almog — November 2, 2016 at 1:36 am (permalink) Shai Almog says:\nGo to settings and click the update client libs button to update the packaged libraries.\nleroadrunner — November 2, 2016 at 1:01 pm (permalink) leroadrunner says:\nThanks! I’ll remember that…\u0026ldquo;refresh cn1libs files\u0026rdquo; was not enough\nLove this new design!\nsalah Alhaddabi — January 16, 2017 at 6:52 pm (permalink) salah Alhaddabi says:\nDear Shai, I have tested this app from the plugin in the simulator but found that in all forms the title area in the middle between the search button and the side menu symbol is always a black rectangle. I tried setting the TitleArea UIID transparency to zero but still didn’t work. The right and the left side of the toolbar are showing the background image but only the rectangle between the search button and the side menu symbol is black!!!\nShai Almog — January 17, 2017 at 5:25 am (permalink) Shai Almog says:\nCan you provide a screenshot?\nHow did you test the app? Did you use the wizard?\nsalah Alhaddabi — January 17, 2017 at 5:47 pm (permalink) salah Alhaddabi says:\nhttps://uploads.disquscdn.c…\nThis is a screen shot of the Profile form, for example, as you can see with a black rectangle on the middle of the tool bar. I have used the wizard as part of the demo that is bundled with the plugin. I have codename one plugin version 3.6 in netbeans. I have used the simulator in this screen shot.\nShai Almog — January 18, 2017 at 7:24 am (permalink) Shai Almog says:\nWhich skin is that?\nJust tried that on a couple of iOS skins and nothing…\nWhich IDE are you using?\nhttps://uploads.disquscdn.c…\nsalah Alhaddabi — January 18, 2017 at 3:02 pm (permalink) salah Alhaddabi says:\nDear Shai, you are right. This is only happening with the iphone6plus skin. I am using netbeans 8.2. Does this mean if I deploy the app to a 6plus iPhone it will have the same issue??\nShai Almog — January 19, 2017 at 6:27 am (permalink) Shai Almog says:\nNo that’s a bug in the skin. We just fixed that. Can you please go to the more skins menu and update the skin from there. It should fix the problem after restarting the simulator.\nsalah Alhaddabi — January 19, 2017 at 8:08 pm (permalink) salah Alhaddabi says:\nThanks a lot Shai. It’s working even better now with a very nice animation!!!\nFaten Sahli — April 27, 2017 at 9:58 pm (permalink) Faten Sahli says:\nhow can i downoald a template ?\nShai Almog — April 28, 2017 at 5:41 am (permalink) Shai Almog says:\nIt’s in the plugin\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/template-clean-modern-ui-kit/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/template-clean-modern-ui-kit/clean-modern-ui-kit.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIn the previous \u003ca href=\"/blog/template-mobile-material-screens-ui-kit.html\"\u003etemplate post\u003c/a\u003e I introduced a material\u003cbr\u003e\ndesign inspired theme. This time the theme I chose is simpler \u0026ldquo;cleaner\u0026rdquo; but not necessarily easier to integrate.\u003cbr\u003e\nI’ve had quite a few difficulties wrestling with Photoshop oddities (bugs?) that made this template painful,\u003cbr\u003e\nhopefully I’ve narrowed down the process enough so this should become easier.\u003c/p\u003e\n\u003cp\u003eThe PSD I chose this time is the \u003ca href=\"https://www.dropbox.com/s/4bqg4y8cru95ek6/Screens.psd.zip?dl=0\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eClean Modern\u003cbr\u003e\nUI Kit\u003c/a\u003e which is heavy on background images and a minimalist on all other aspects. You can check out the\u003cbr\u003e\nfull git repository of the work \u003ca href=\"https://github.com/codenameone/CleanModernUIKit\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere\u003c/a\u003e.\u003c/p\u003e","title":"Template – Clean Modern Cross Platform Mobile UI Kit"},{"content":"\nWe previously discussed the problems with List and somewhat neglected\nComboBox which is a subclass of List. ComboBox has the dubious \u0026ldquo;honor\u0026rdquo; of deriving most of the problems\nList has and adding a slew of its own problems such as two separate renderers, different behaviors between OS’s\netc.\nIn addition mobile OS’s don’t really have a ComboBox in their native UI arsenal. E.g. iOS has no native\nComboBox support. When web code has a select entry that needs to show a ComboBox Safari shows a UI\nspecific to it and launches a spinner for interaction.\nComboBox was pretty common before iOS and it’s a component we had since 2006 but it’s time to move forward\nand here are better alternatives that should support every single use case…​\nPicker Picker doesn’t look good in the simulator and has its issues but on the device it is mapped to a native device\nvalue picker. If you need to pick a Time, Date or String then picker is by far the best alternative out there.\n__ Picker has a time \u0026amp; date option that only works natively on iOS…​ The cool thing about picker is that it uses native UI for time/date which allow things like a clock face on Android\nwhen picking the time…​\nHowever, I’m guessing that with the case of replacing the ComboBox you would want a String Picker which\nworks like this:\nString[] characters = { \u0026quot;Tyrion Lannister\u0026quot;, \u0026quot;Jaime Lannister\u0026quot;, \u0026quot;Cersei Lannister\u0026quot;, \u0026quot;Daenerys Targaryen\u0026quot;, \u0026quot;Jon Snow\u0026quot; /* cropped */ }; Form hi = new Form(\u0026quot;Picker\u0026quot;); Picker p = new Picker(); p.setStrings(characters); p.setSelectedString(characters[0]); p.addActionListener(e -\u0026gt; ToastBar.showMessage(\u0026quot;You picked \u0026quot; + p.getSelectedString(), FontImage.MATERIAL_INFO)); hi.add(p); hi.show(); AutoCompleteTextField The AutoCompleteTextField is probably the best alternative if you are picking a String we discussed this in some\ndetails in the blog post here. But this is only a partial replacement to the\ncombo box.\nWe can combine an auto complete with a button to produce an editable ComboBox that is just amazing e.g.\ncheck out this code:\nString[] characters = { \u0026quot;Tyrion Lannister\u0026quot;, \u0026quot;Jaime Lannister\u0026quot;, \u0026quot;Cersei Lannister\u0026quot;, \u0026quot;Daenerys Targaryen\u0026quot;, \u0026quot;Jon Snow\u0026quot; /* cropped */ }; Form hi = new Form(\u0026quot;Picker\u0026quot;); AutoCompleteTextField act = new AutoCompleteTextField(characters); act.addActionListener(e -\u0026gt; ToastBar.showMessage(\u0026quot;You picked \u0026quot; + act.getText(), FontImage.MATERIAL_INFO)); Button down = new Button(); FontImage.setMaterialIcon(down, FontImage.MATERIAL_KEYBOARD_ARROW_DOWN); hi.add( BorderLayout.center(act). add(BorderLayout.EAST, down)); down.addActionListener(e -\u0026gt; act.showPopup()); hi.show(); Figure 1. AutoCompleteTextField as editable combo box\nThis component is one of my favorites as it allows for complex searches and the typical combo box use cases.\nButton (or MultiButton etc.) \u0026amp; Popup The last one seems like \u0026ldquo;hard work\u0026rdquo; but when you look at the alternative of building a cell renderer for a\nComboBox this is actually really easy and more powerful…​\nInstead of using a ComboBox just use a button, you can style it to look like a ComboBox and then show a\nDialog as a popup so it will appear next to the Button.\nE.g. the code in the demo below has some complexities but they are far simpler than the complexities of building\na renderer:\nForm hi = new Form(\u0026quot;Button\u0026quot;, BoxLayout.y()); String[] characters = { \u0026quot;Tyrion Lannister\u0026quot;, \u0026quot;Jaime Lannister\u0026quot;, \u0026quot;Cersei Lannister\u0026quot;}; String[] actors = { \u0026quot;Peter Dinklage\u0026quot;, \u0026quot;Nikolaj Coster-Waldau\u0026quot;, \u0026quot;Lena Headey\u0026quot;}; int size = Display.getInstance().convertToPixels(7); EncodedImage placeholder = EncodedImage.createFromImage(Image.createImage(size, size, 0xffcccccc), true); Image[] pictures = { URLImage.createToStorage(placeholder, \u0026quot;tyrion\u0026quot;,\u0026quot;http://i.lv3.hbo.com/assets/images/series/game-of-thrones/character/s5/tyrion-lannister-512x512.jpg\u0026quot;), URLImage.createToStorage(placeholder, \u0026quot;jaime\u0026quot;,\u0026quot;http://i.lv3.hbo.com/assets/images/series/game-of-thrones/character/s5/jamie-lannister-512x512.jpg\u0026quot;), URLImage.createToStorage(placeholder, \u0026quot;cersei\u0026quot;,\u0026quot;http://i.lv3.hbo.com/assets/images/series/game-of-thrones/character/s5/cersei-lannister-512x512.jpg\u0026quot;) }; MultiButton b = new MultiButton(\u0026quot;Pick A Lanister...\u0026quot;); b.addActionListener(e -\u0026gt; { Dialog d = new Dialog(); d.setLayout(BoxLayout.y()); d.getContentPane().setScrollableY(true); for(int iter = 0 ; iter \u0026lt; characters.length ; iter++) { MultiButton mb = new MultiButton(characters[iter]); mb.setTextLine2(actors[iter]); mb.setIcon(pictures[iter]); d.add(mb); mb.addActionListener(ee -\u0026gt; { b.setTextLine1(mb.getTextLine1()); b.setTextLine2(mb.getTextLine2()); b.setIcon(mb.getIcon()); d.dispose(); b.revalidate(); }); } d.showPopupDialog(b); }); hi.add(b); hi.show(); Figure 2. Pick a Lanister with the popup open\nFigure 3. I like Tyrion but this was Lena’s season…​\n__ | I forgot to set the emblem character in the MultiButton to the down arrow which would have made it\nlook like a combo box Finally I think every single one of the options above is superior to ComboBox my intuition is telling me that we should\ndeprecate it so people stop using it but we probably won’t remove it as it is still used a lot…​\nWhat are your thoughts on the options listed above? Did I miss a use case for which ComboBox is essential? Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nUlises Escobar Aranda — October 17, 2016 at 2:48 pm (permalink) The reason why I have not stopped using the combobox is because I use a list caption-value, with repeated titles. Is there any way that you can add this functionality to the Picker and also a getSelectedIndex() and setSelectedIndex() functions?\nShai Almog — October 18, 2016 at 2:49 am (permalink) The picker is implemented natively so no, something like this will not be realistic in the picker. I think this falls squarely into the Button+Dialog territory\nTommy Mogaka — October 18, 2016 at 1:39 pm (permalink) I agree… combo lists can be a nightmare and styling them is just the begining! Even so, I think it is still the best component for displaying a selection of large data in a way that the user can quickly choose what they want e.g. in the case of countries as shown below. The combo here is better be replaceable by an autocomplete textfield because the user already knows what s/he wants. Still, in the case that they don’t know what they want to select in advance, isn’t a combo way better?\ncombo_countries = new ComboBox();\ntry\n{\nObject rawStringCountries = Storage.getInstance().readObject(\u0026ldquo;countries.json\u0026rdquo;);\nJSONObject j = new JSONObject(rawStringCountries.toString());\nJSONArray Arr = (JSONArray) j.get(\u0026ldquo;data\u0026rdquo;);\nstr_countries = new String[Arr.length()];\nList listOfString = new ArrayList\u0026lt;\u0026gt;();\nfor (int i = 0; i \u0026lt; Arr.length(); i++)\n{\nString p = Arr.getString(i);\nJSONObject obj_country = new JSONObject(p);\nfinal String str_id = (String)obj_country .get(\u0026ldquo;id\u0026rdquo;);\nfinal String str_title = (String)obj_country .get(\u0026ldquo;title\u0026rdquo;);\ncombo_countries.addItem(str_title);\n}\ncombo_inchi.setIncludeSelectCancel(true);\n}\ncatch (JSONException e)\n{\ne.printStackTrace();\n}\nShai Almog — October 19, 2016 at 8:20 am (permalink) Shai Almog says:\nYou can use a hybrid approach of auto-complete coupled with the button dialog which would be superior although slightly more verbose.\nMo — March 8, 2017 at 8:18 pm (permalink) Mo says:\nHi, having just experimented with the above Button \u0026amp; Popup, but when I use the Validator, I am unable to get the same behavior as the ComboBox on an Invalid value, can you advice on how to use the Validator with the above approach??\nShai Almog — March 9, 2017 at 7:29 am (permalink) Shai Almog says:\nHi,\nyou will need to derive the validator and override getComponentValue() to return the right value for that component and super.getComponentValue() for the other components.\nMo — March 9, 2017 at 2:31 pm (permalink) Mo says:\nHi Shai, thank you for the reply and would appreciated if you could elaborate your hint above with an example?\nThe code below, is an example of how I am experimenting with Button and Popup technique, where MultiButtonBox is overriding the Button/MultiButton component!\nlangField = new MultiButtonBox(language, langMap); validator.addConstraint(langField, new com.codename1.ui.validation.LengthConstraint(2, \u0026quot;errors.invalid\u0026quot;));//validate Shai Almog — March 10, 2017 at 8:47 am (permalink) Shai Almog says:\nInstead of doing new Validator(). Subclass it and override that method. That method retrieves the value of the component for validation, since your component is arbitrary (a button) the validator doesn’t know the actual value of the component and can’t figure out what to do in this case.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-dont-use-combobox/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-dont-use-combobox/just-the-tip.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe previously \u003ca href=\"/blog/avoiding-lists.html\"\u003ediscussed the problems with List\u003c/a\u003e and somewhat neglected\u003cbr\u003e\n\u003ccode\u003eComboBox\u003c/code\u003e which is a subclass of \u003ccode\u003eList\u003c/code\u003e. \u003ccode\u003eComboBox\u003c/code\u003e has the dubious \u0026ldquo;honor\u0026rdquo; of deriving most of the problems\u003cbr\u003e\n\u003ccode\u003eList\u003c/code\u003e has and adding a slew of its own problems such as two separate renderers, different behaviors between OS’s\u003cbr\u003e\netc.\u003c/p\u003e\n\u003cp\u003eIn addition mobile OS’s don’t really have a \u003ccode\u003eComboBox\u003c/code\u003e in their native UI arsenal. E.g. iOS has no native\u003cbr\u003e\n\u003ccode\u003eComboBox\u003c/code\u003e support. When web code has a select entry that needs to show a \u003ccode\u003eComboBox\u003c/code\u003e Safari shows a UI\u003cbr\u003e\nspecific to it and launches a spinner for interaction.\u003c/p\u003e","title":"TIP: Don't Use ComboBox"},{"content":"\nThis has been a REALLY busy week. We had to release an emergency plugin update during the week to\nworkaround a critical issue in the previous plugin update. This was pretty hard!\nTo make things extra difficult we had two huge blog posts that I’ve worked on launching, the code itself wasn’t\nsuch a big deal as is all the hassle around them e.g. appstore submissions are never fun especially when traveling…​\nAfter all these releases we still chose to release an update today\nIt doesn’t have any ground breaking changes but does include the refinements I\ndiscussed yesterday in the blog.\nOn stack overflow things were as usual:\nSoft back button not working This should work regardless of where you call setBackCommand\nRead on stackoverflow…​\nDropbox plugin? We have a pretty old dropbox plugin which\nshould work but uses the old OAuth solution. Ideally this should be updated to the OAuth2 approach to allow\nupload etc. I know some developers did that but sadly they didn’t contribute their work back…​\nRead on stackoverflow…​\nBuilding from xcode source, missing \u0026ldquo;pods\u0026rdquo; library This is a bit confusing, you need to open the xworkspace file in the new pods build\nRead on stackoverflow…​\nCodenameone theming sidemenu We just showed how deeply you can customize the sidemenu in the\nlatest template demo\nRead on stackoverflow…​\nCodenameone app version issue When you use a build hint like android.versionCode you need to pay close\nattention. It’s best to avoid that specific hint…​\nRead on stackoverflow…​\nPubnub-CodeNameOne library – missing methods (Access Manager) Craig from pubnub gave a great reference for that\nRead on stackoverflow…​\nSend log file The device acts differently when using send email\nRead on stackoverflow…​\nUnable to build codename one app after adding admobfullscreen lib We need to update the old extensions to include the build hints inside them\nRead on stackoverflow…​\nListen to side menu / hamburger menu clicked event We need to implement this functionality in the sidemenu itself but until we do you can just add your own button\nas a side menu button and hide the default side menu button\nRead on stackoverflow…​\nNavigation between forms fires infiniteContainer refresh It’s hard to give an answer when I have so little information to work with, I can’t stress this enough: use images\nto illustrate your point…​\nRead on stackoverflow…​\nHow to enable Facebook authentication for Codename One on Android SHA1 works fine on all devices guaranteed\nRead on stackoverflow…​\nComboBox in codename one I don’t like ComboBox as it derives from List which is problematic and adds problems of it’s own…​\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xxvii/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xxvii/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis has been a \u003cstrong\u003eREALLY\u003c/strong\u003e busy week. We had to release an emergency plugin update during the week to\u003cbr\u003e\nworkaround a critical issue in the previous plugin update. This was pretty hard!\u003cbr\u003e\nTo make things extra difficult we had two huge blog posts that I’ve worked on launching, the code itself wasn’t\u003cbr\u003e\nsuch a big deal as is all the hassle around them e.g. appstore submissions are never fun especially when traveling…​\u003c/p\u003e","title":"Questions of the Week XXVII"},{"content":"Android Developer Introduction To Codename One Take your first steps in Codename One from an Android developer perspective\nHome Developers Android Developers The content of this page is out of date! please check a more thorough discussion and sample porting in this post.\nCodename One allows Android developers familiar with Java and Eclipse (or NetBeans/IntelliJ) to instantly build native applications for Android, iOS, Windows and other platforms!\nCodename One has the following additional advantages:\nA fast simulator Standard Java debugging and profiling tools Drag and drop development (optional) Resources are automatically scaled to the different DPI\u0026rsquo;s in the tools No need to deal with manifests and permissions (Codename One automatically detects and applies the necessary permissions) Codename One hides the differences between versions on Android such as Gingerbread, Jellybean and Lollipop Resources can be downloaded dynamically and aren\u0026rsquo;t compiled into the APK Component hierarchy (views) is much simpler in Codename One To learn more about Codename One in general you can go to our developer section. Read below for information of Codename One equivalents to common Android features.\nLayouts In Android developers build their user interfaces in XML by nesting layout views and view elements one within another (you can write Android apps in code but that isn\u0026rsquo;t as common). These elements are translated by the compiler and in order to bind code to them you need to \u0026ldquo;find\u0026rdquo; them by their ID to use them. Codename One differs in several ways:\nYou can build Codename One applications either via the GUI builder (in which case you use a findXXX() method to locate the component) or write Java source code manually. Component is Codename One\u0026rsquo;s equivalent of a view, Container derives from Component. All layouts are applied to the Container class essentially decoupling layout from Container hierarchy E.g. Android\u0026rsquo;s linear layout is essentially very similar to the box layout in Codename One. So to arrange components in a row in Codename One we can do something like:\nYou can do the same with the GUI builder as well using simple drag and drop. To read more about the different types of layouts and how they can be nested/used you can follow the section on layout managers in the developer guide.\nFragments Fragments essentially solve an issue with Android which mixed Activities and Views in a hierarchy creating a somewhat complex scenario to support a very dynamic architecture. This concept is powerful, yet isn\u0026rsquo;t portable, convenient or robust. Fragments become unnecessary because of the much simpler Codename One hierarchy.\nMultiple DPI\u0026rsquo;s \u0026amp; 9-Patch Borders Codename One supports a multi-image format which is roughly identical to the multiple DPI directories commonly used in Android. Unlike Android the Codename One designer tool automatically scales the images to all the resolutions (using high quality scaling algorithm) saving you the need to maintain multiple resolution support.\nThe same is true with Codename One\u0026rsquo;s 9-part image borders. However, unlike Androids very elaborate 9-patch borders Codename One borders are far simpler. Codename One uses tiling for border images (instead of scaling) and breaks the images down, it also includes an image cutting wizard and internally cuts the images to 9-pieces.\nAndroid\u0026rsquo;s 9-patch images are VERY powerful but also very hard to implement on all platforms in a performant way. They are also a very difficult concept to grasp for most developers.\nActivities Codename One has its own lifecycle object which acts a bit more like an application than the activity does, its somewhat simpler to program to. Codename One supports firing intents although that is mostly Android specific and won\u0026rsquo;t work on other platforms.\nAndroid Specific Features You can invoke \u0026ldquo;native\u0026rdquo; Android code from Codename One without breaking the portability of Codename One. Follow the native code section in the developer guide to understand how this can be accomplished, you can also see the how do I video tutorial on the subject. You can also add things to the manifest etc. if required by your native code.\n","permalink":"https://www.codenameone.com/introduction-for-android-developers/","summary":"\u003ch1 id=\"android-developer-introduction-to-codename-one\"\u003eAndroid Developer Introduction To Codename One\u003c/h1\u003e\n\u003cp\u003eTake your first steps in Codename One from an Android developer perspective\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://beta.codenameone.com/developing-in-codename-one.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDevelopers\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eAndroid Developers\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eThe content of this page is out of date!\u003c/strong\u003e please check a more thorough discussion and sample porting in \u003ca href=\"/blog/port-native-android-app-ios-iphone-guide.html\"\u003ethis post\u003c/a\u003e.\u003c/p\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003cp\u003eCodename One allows Android developers familiar with Java and Eclipse (or NetBeans/IntelliJ) to instantly build native applications for Android, iOS, Windows and other platforms!\u003c/p\u003e","title":"Introduction For Android Developers"},{"content":"\nThere was much left unsaid about the\ntemplate UI that I did earlier in the week.\nIt was doable \u0026amp; reasonably easy but I still had some pitfalls. I was able to circumvent them easily but I’m not so\nsure these would have been easy for other developers out there. As a result we decided to simplify some use\ncases in Codename One as a result.\nI chose to separate these to a different post as most of the subjects here will be resolved in the next update, but\nthe template post would probably still be useful when this post becomes history…​\nSide Menu Opening The designs to the template UI placed the menu button at the top, we have a special case to allow that but that\nspecial case doesn’t deal with the settings placement at the top too. The solution I took was to define the\ntheme constant hideLeftSideMenuBool=true which hides the sidemenu button. I then added my own button with\nthe menu button icon as such:\nButton menuButton = new Button(\u0026quot;\u0026quot;); menuButton.setUIID(\u0026quot;Title\u0026quot;); FontImage.setMaterialIcon(menuButton, FontImage.MATERIAL_MENU); menuButton.addActionListener(e -\u0026gt; ((SideMenuBar)getToolbar().getMenuBar()).openMenu(null)); Most of that is pretty standard and easy except of the downcast to the SideMenuBar class. So we’ve added\na method to Toolbar named openSideMenu which would make this far more reasonable:\nmenuButton.addActionListener(e -\u0026gt; getToolbar().openSideMenu()); Status Bar Control Another difficulty is in the level of control over the status bar in iOS. iOS apps space their top portion to leave room\nfor the status bar. You can customize that UIID but that means customizing it for all the forms which might not\nbe what I want…​\nSo we’ve decided to add two methods to Form:\nprotected boolean shouldPaintStatusBar(); protected Component createStatusBar(); These should allow you to override whether the status bar is even shown on a per form basis and also manipulate\nit as needed during the creation phase.\n__ | The StatusBarSideMenu UIID lets you disable the status bar in the side menu only. You can just define\nits padding to 0 to remove the status bar from the sidemenu UI Same Size It’s very common to want two components to occupy the same size. We often want that to align components\nso we have the methods:\nComponent.setSameHeight(Component... cmps); Component.setSameWidth(Component... cmps); These create a special case where the components in cmps return the same preferred width/height as the largest\ncomponent in the group. Thus they all appear to have the same width or height.\nThe use case of layout is great but I found myself using these methods like this:\nComponent.setSameHeight(notesLabel, notesPlaceholder); Component.setSameWidth(notesLabel, notesPlaceholder); To allow a component and its placeholder to have the same size before I use Container.replace to fade in\nthe component. So I added:\nComponent.setSameSize(Component... cmps); Which saves writing the same line twice…​\nNow you might be thinking, why not use notesPlaceholder.setPreferredSize(notesLabel.getPreferredSize()).\nThis is how we used to do things and it does work well for simple cases like this. But what if I want to replace\nan entry not with a placeholder but rather with an entry that might be bigger on an axis?\nIn that case I’ll need to check which component is bigger in each axis and apply the right dimension which isn’t\na problem with the original code.\n__ I ignored the fact that setPreferredSize is deprecated because I don’t think that should be the reason Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/msuikit-template-inspired-changes/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/msuikit-template-inspired-changes/Mobile-Material-UI-Screens.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThere was much left unsaid about the\u003cbr\u003e\n\u003ca href=\"/blog/template-mobile-material-screens-ui-kit.html\"\u003etemplate UI\u003c/a\u003e that I did earlier in the week.\u003cbr\u003e\nIt was doable \u0026amp; reasonably easy but I still had some pitfalls. I was able to circumvent them easily but I’m not so\u003cbr\u003e\nsure these would have been easy for other developers out there. As a result we decided to simplify some use\u003cbr\u003e\ncases in Codename One as a result.\u003c/p\u003e\n\u003cp\u003eI chose to separate these to a different post as most of the subjects here will be resolved in the next update, but\u003cbr\u003e\nthe template post would probably still be useful when this post becomes history…​\u003c/p\u003e","title":"MSUIKit Template Inspired Changes"},{"content":"\nWe get contacted quite a bit about the prospect of porting applications that were already written using the Android\nAPI. In this quick tutorial we will walk you thru the paces of converting a simple Android application to\na Codename One application. We will also start with some basic tips covering the differences between Android \u0026amp;\nCodename One development.\nHow does Codename One Differ from Android Development? Codename One allows Android developers familiar with Java to instantly build native applications for Android,\niOS, Windows and other platforms.\nCodename One has the following additional advantages besides portability:\nA fast simulator – Despite recent advances in the emulator. The build process and app connection are still frustratingly slow on Android\nStandard Java debugging and profiling tools\nResources are automatically scaled to the different DPI’s in the tools\nNo need to deal with manifests and permissions (Codename One automatically detects and applies the necessary permissions).\nNotice this is implicitly Marshmallow compatible as well, so permission prompts are implicitly shown.\nCodename One hides the differences between versions on Android\nSince Codename One doesn’t package GUI XML’s into the final product it is harder to reverse engineer a Codename One application\nComponent hierarchy (views) is much simpler in Codename One\nWorks with all major IDE’s (NetBeans, Eclipse \u0026amp; IntelliJ/IDEA)\nAll inclusive by default – no need for mixing and matching multiple disparate tools\nLayouts In Android developers build user interfaces in XML by nesting layout views and view elements one within\nanother (you can write Android apps in code but that isn’t as common). These elements are translated by the\ncompiler and in order to bind code to them you need to \u0026ldquo;find\u0026rdquo; them by their ID to use them. Codename One\ndiffers in several ways:\nYou can build Codename One applications either via the GUI builder which uses a more traditional code generator\napproach or write Java source code manually.\nComponent is Codename One’s equivalent of a view, Container derives from Component (think of it as a\nViewGroup.\nAll layouts are applied to the Container class essentially decoupling layout from Container hierarchy\nE.g. Android’s linear layout is essentially very similar to the box layout in Codename One. So to arrange\ncomponents in a row in Codename One we can do something like:\nContainer cnt = new Container(new BoxLayout(BoxLayout.X_AXIS)); cnt.add(button1); cnt.add(button2); cnt.add(button3); This can also be written as shorthand like this:\nContainer cnt = BoxLayout.encloseX(button1, button2, button3); You can do the same with the GUI builder as well using simple drag and drop.\nTo read more about the different types of layouts and how they can be nested/used you can follow the\nsection on layout managers in the developer guide or check out the\nlayouts section in the javadocs.\nFragments Fragments essentially solve an issue with Android which mixed Activity and View in a hierarchy creating a\nsomewhat complex scenario to for dynamic architectures.\nThe concept is powerful, yet it isn’t portable, convenient or robust. Fragments become unnecessary because\nof the much simpler Codename One hierarchy. Since Codename One doesn’t have a real equivalent of\nActivity the UI elements don’t need it either e.g. Tabs work with Container not Activity.\nMultiple DPI’s \u0026amp; 9-Patch Borders Codename One supports a multi-image format which is roughly identical to the multiple DPI directories\ncommonly used in Android. Unlike Android the Codename One designer tool automatically scales the\nimages to all the resolutions (using high quality scaling algorithm) saving you the need to maintain multiple\nresolution support.\nThe same is true with Codename One’s 9-part image borders. However, unlike Androids very elaborate\n9-patch borders Codename One borders are far simpler.\nCodename One uses tiling for border images (instead of scaling) and breaks the images down, it also\nincludes an image cutting wizard and internally cuts the images to 9-pieces.\nAndroid’s 9-patch images are VERY powerful but also very hard to implement on all platforms in a\nperformant way. They are also a very difficult concept to grasp for most developers.\nActivities Codename One has its own lifecycle object which acts a bit more like an application than the activity does,\nit’s somewhat simpler to program to.\nCodename One supports firing intents although that is mostly Android specific and won’t work on other platforms.\nYou can execute arbitrary URL’s to launch external applications when necessary. Notice that iOS, Windows etc.\ndon’t have anything remotely close to activities.\nCodename One has two different classes that match the activity. Form is the top level component that you\ncan \u0026ldquo;show\u0026rdquo; \u0026amp; transition. The main class for Codename One itself gets lifecycle events similar to the Activity\nlifecycle events.\nAndroid Specific Features You can invoke \u0026ldquo;native\u0026rdquo; Android code from Codename One without breaking the portability of Codename One.\nFollow the native code section in the developer guide to understand how this can be accomplished, you can\nalso see the\nhow do I video tutorial on the subject.\nYou can also add things to the manifest etc. if required by your native code.\nPorting Tool A while back we announced an open source project to ease the porting process\ncn1 android importer. This is a very basic tool that just\nscaffolds the new Codename One project from an Android project without really duplicating the UI or\nconverting the code.\nWe can obviously improve this tool significantly but to do so we need to gauge community interest which so\nfar has been \u0026ldquo;underwhelming\u0026rdquo;. I will start by using this tool as it is now to get started quickly and then port the\ncode.\nThe Application I chose to port a really trivial application so it will be easy to follow. Specifically I chose\nSwiftnotes whose source code is\navailable here.\nI chose this application because it is simple. Making the application \u0026ldquo;pretty\u0026rdquo; isn’t a goal of this tutorial although\nI tried to make the application look reasonably good while trying to stay loyal to the original design.\nTo give you a sense of where we are heading I’ve published the end result to\nApple itunes,\ngoogle play \u0026amp;\nthe Microsoft store as well as created a JavaScript build\nwhich you can see to the right here (running live!) and you can launch on a\ndevice here.\nI’ve changed a few things in the final app e.g. removed the overflow, changed the icon etc. so it will look decent\nin the various appstores.\nThe full source code of the app is here: https://github.com/codenameone/SwiftnotesCN1\nThe Porting Process First we need to get the pre-requisites:\nDownload the Android importer from https://github.com/shannah/cn1-android-importer/blob/master/dist/ –\nnote that at this time the files from the lib directory should also be downloaded but this should hopefully be resolved\nDownload and unzip the Swiftnotes sources from https://github.com/adrianchifor/Swiftnotes/archive/master.zip\nDownload NetBeans and install Codename One if you haven’t already\nStep 1: Create a new Codename One Project The instructions are for NetBeans but should work for IntelliJ as is. I’m not sure about Eclipse.\nWe create a standard Codename One project:\nFigure 1. In the new project wizard we select Codename One\nThe project name doesn’t matter much I just used SwiftnotesCN1\nFigure 2. The project name and location\nWe then pick the class/package name, the package name should match the existing Android package name if\nyou want to replace the original project. I also picked a native theme for simplicity and the barebone application\nto start from scratch:\nFigure 3. We should use the same package name as the android project\n__ After doing this I chose to refactor the app to the com.codename1 package space so we can run it side by side with the native app Step 2: Run the Conversion Tool The conversion tool is very simplistic and preliminary. It had issues with some of the UI elements even with\nit’s limited support for these features.\n__ If you show enough interest, file issues we’ll fix them and move this tool forward I used the following command to convert the project:\njava -jar AndroidImporter.jar import-project -i Swiftnotes-master/app/src/main/res -o ~/dev/SwiftnotesCN1 -p com.moonpi.swiftnotes The first argument is the resource directory for the original Android project. Followed by the output directory\n(the new Codename One project) and the package name where GUI files should be created.\nThis placed the localization bundles and imported the images, it also generated the GUI XML files.\nTo generate the GUI sources right click the project and select \u0026ldquo;build\u0026rdquo; this will generate GUI source files for\nall the XML files.\nStep 3: Bind Localization Code This is really trivial and will allow us to see something running almost at once, open the main class in our case\nSwiftnotesCN1. Edit the init(Object) method to load the localization Strings:\npublic void init(Object context) { theme = UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;); Map\u0026lt;String, String\u0026gt; v = theme.getL10N(\u0026quot;strings\u0026quot;, L10NManager.getInstance().getLanguage()); if(v == null) { v = theme.getL10N(\u0026quot;strings\u0026quot;, \u0026quot;en\u0026quot;); } UIManager.getInstance().setBundle(v); // Enable Toolbar on all Forms by default Toolbar.setGlobalToolbar(true); // Pro only feature, uncomment if you have a pro subscription Log.bindCrashProtection(true); } To see/edit the Strings in the app double click the theme.res file in the root of the project\nand select the localization section.\nInterlude: The GUI Builder The wizard generates GUI builder XML files that are \u0026ldquo;hidden\u0026rdquo; under the res/guibuilder directory and must\ncorrespond to Java source files. They carry the .gui extension and use a relatively simple format of hierarchy/layout.\nYou can edit the XML files but if you remove the java files they will be regenerated. You need to remove/move\nthe XML \u0026amp; Java files together if you want to work with both.\nCurrently the generator doesn’t generate much as it can’t replicate the layout and Android is too different from\nCodename One, but it’s a starting point.\nStep 4: Fix the Main Activity Form The generated code derives from Container instead of Form since Android doesn’t have an equivalent of\nCodename One’s concept of a top level component. We can just edit the ActivityMain class to derive from\nForm instead of Container (you can also do that in the .gui XML file but it’s not essential).\nWe can now right click the MainActivity.java file and select the GUI builder option which should open\nthis UI:\nFigure 4. Main Activity UI as it is generated\nThis looks a bit weird but if we look at the Android XML this starts to make sense:\n\u0026lt;?xml version=\u0026quot;1.0\u0026quot; encoding=\u0026quot;utf-8\u0026quot;?\u0026gt; \u0026lt;RelativeLayout xmlns_android=\u0026quot;http://schemas.android.com/apk/res/android\u0026quot; xmlns_tools=\u0026quot;http://schemas.android.com/tools\u0026quot; android_layout_width=\u0026quot;match_parent\u0026quot; android_layout_height=\u0026quot;match_parent\u0026quot; android_animateLayoutChanges=\u0026quot;true\u0026quot; tools_context=\u0026quot;.MainActivity\u0026quot; android_background=\u0026quot;@color/background_white\u0026quot; \u0026gt; \u0026lt;include android_id=\u0026quot;@+id/toolbarMain\u0026quot; layout=\u0026quot;@layout/toolbar\u0026quot;/\u0026gt; \u0026lt;ListView android_layout_width=\u0026quot;match_parent\u0026quot; android_layout_height=\u0026quot;match_parent\u0026quot; android_id=\u0026quot;@+id/listView\u0026quot; android_divider=\u0026quot;@null\u0026quot; android_dividerHeight=\u0026quot;8dp\u0026quot; android_drawSelectorOnTop=\u0026quot;true\u0026quot; android_fastScrollEnabled=\u0026quot;true\u0026quot; android_scrollbarStyle=\u0026quot;outsideOverlay\u0026quot; android_paddingRight=\u0026quot;16dp\u0026quot; android_paddingLeft=\u0026quot;16dp\u0026quot; android_clipToPadding=\u0026quot;false\u0026quot; android_layout_alignParentLeft=\u0026quot;true\u0026quot; android_layout_alignParentRight=\u0026quot;true\u0026quot; android_layout_alignParentBottom=\u0026quot;true\u0026quot; android_layout_below=\u0026quot;@+id/toolbarMain\u0026quot; android_paddingTop=\u0026quot;8dp\u0026quot; android_paddingBottom=\u0026quot;8dp\u0026quot; /\u0026gt; \u0026lt;ImageButton android_layout_width=\u0026quot;65dp\u0026quot; android_layout_height=\u0026quot;65dp\u0026quot; android_id=\u0026quot;@+id/newNote\u0026quot; android_scaleType=\u0026quot;fitXY\u0026quot; android_background=\u0026quot;@drawable/ic_new_selector\u0026quot; android_layout_marginBottom=\u0026quot;30dp\u0026quot; android_layout_marginRight=\u0026quot;30dp\u0026quot; android_layout_alignParentBottom=\u0026quot;true\u0026quot; android_layout_alignParentRight=\u0026quot;true\u0026quot; android_contentDescription=\u0026quot;@string/new_note_content_description\u0026quot; /\u0026gt; \u0026lt;TextView android_layout_width=\u0026quot;wrap_content\u0026quot; android_layout_height=\u0026quot;wrap_content\u0026quot; android_id=\u0026quot;@+id/noNotes\u0026quot; android_textAppearance=\u0026quot;?android:attr/textAppearanceLarge\u0026quot; android_text=\u0026quot;@string/no_notes_text\u0026quot; android_textColor=\u0026quot;@color/theme_primary\u0026quot; android_textStyle=\u0026quot;bold\u0026quot; android_layout_alignParentLeft=\u0026quot;true\u0026quot; android_layout_alignParentRight=\u0026quot;true\u0026quot; android_layout_alignParentStart=\u0026quot;true\u0026quot; android_layout_alignParentEnd=\u0026quot;true\u0026quot; android_gravity=\u0026quot;center\u0026quot; android_layout_marginLeft=\u0026quot;8dp\u0026quot; android_layout_marginRight=\u0026quot;8dp\u0026quot; android_layout_centerInParent=\u0026quot;true\u0026quot; android_visibility=\u0026quot;invisible\u0026quot; /\u0026gt; \u0026lt;View android_layout_width=\u0026quot;match_parent\u0026quot; android_layout_height=\u0026quot;@dimen/shadow_elevation\u0026quot; android_layout_below=\u0026quot;@+id/toolbarMain\u0026quot; android_layout_alignParentRight=\u0026quot;true\u0026quot; android_layout_alignParentLeft=\u0026quot;true\u0026quot; android_background=\u0026quot;@drawable/drop_shadow\u0026quot; /\u0026gt; \u0026lt;/RelativeLayout\u0026gt; Above we have these elements:\nToolbar – this is builtin to Codename One with the Toolbar class\nListView – Codename One doesn’t recommend lists and instead uses box layout so we will use a Container\nImageButton \u0026amp; Shadow – this is used to provide the floating action button, this is builtin to Codename One\nTextView – used to show content when the view is empty. We will have a special case for it in the Container\nNotice that there is a toolbar.xml file included but it doesn’t include anything important just theme stuff and\nnothing of value to us.\nAll of these elements except for the text view are useless to us:\nThe Toolbar is builtin to Codename One\nWe should avoid lists and instead use BoxLayout Container\nWe have a builtin FloatingActionButton so we don’t need that.\nSo we will delete everything except for the text. We will also verify that the layout is BoxLayout.Y_AXIS (it should\nalready be with that layout).\nOne important thing we need to do is select the root form and make sure its UIID property is Form otherwise\nthe converter will try to assign the default UIID’s from Android which won’t work well.\nFigure 5. After removing all the redundant stuff…​\nWe save and open the Java source file, then edit the constructor to include the FloatingActionButton as well\nas the proper title. So we change this:\npublic ActivityMain(com.codename1.ui.util.Resources resourceObjectInstance) { initGuiBuilderComponents(resourceObjectInstance); } To this:\npublic ActivityMain(com.codename1.ui.util.Resources resourceObjectInstance) { super(\u0026quot;app_name\u0026quot;); initGuiBuilderComponents(resourceObjectInstance); FloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_ADD); fab.bindFabToContainer(getContentPane()); getToolbar().addSearchCommand(e -\u0026gt; Log.p(\u0026quot;Todo\u0026quot;)); getToolbar().addCommandToOverflowMenu(\u0026quot;Backup Notes\u0026quot;, null, e -\u0026gt; Log.p(\u0026quot;Todo\u0026quot;)); getToolbar().addCommandToOverflowMenu(\u0026quot;Restore Notes\u0026quot;, null, e -\u0026gt; Log.p(\u0026quot;Todo\u0026quot;)); getToolbar().addCommandToOverflowMenu(\u0026quot;Rate App\u0026quot;, null, e -\u0026gt; Log.p(\u0026quot;Todo\u0026quot;)); } It should be mostly self explanatory and should construct the main UI.\nStep 5: Run To see what we have we can just edit the main class ( SwiftnotesCN1 ) and replace this code:\nForm hi = new Form(\u0026quot;Hi World\u0026quot;); hi.addComponent(new Label(\u0026quot;Hi World\u0026quot;)); hi.show(); With this:\nnew ActivityMain(theme).show(); The end result still needs styling which we will do in the next step.\nFigure 6. Before styling the result\nStep 6: Styling the UI We style the UI using the designer tool, there are other options such as\nCSS but I find the designer tool to be simpler\nand more consistent.\nTo launch the designer double click the theme.res file in the src root. Select the Theme entry and press the\nAdd button in the bottom of the theme. In the Combo Box at the top of the Add dialog type \u0026ldquo;Toolbar\u0026rdquo;.\nSelect the Color tab.\nNext uncheck Derive Background and paste the color (which I got from the colors.xml file of the original\nAndroid project) CE0A31. Then uncheck Derive Transparency and set the value to 255.\nNext select the Border tab, uncheck Derive click the …​ button and select Empty in the combo box.\nNext select the Padding tab, uncheck Derive and leave everything as 0.\nYou should end up with something like this and a red background title:\nFigure 7. Setup of the Toolbar UIID\nNext we setup the foreground colors and fonts for the title elements, for brevity I will summerize the elements\nthat need changing.\nAdd a \u0026ldquo;Title\u0026rdquo; entry with the following properties:\nForeground Color ffffff\nBackground Transparency 0\nFont True Type = native:MainLight (this will map to Roboto/Helvetic Neue respectively)\nTrue Type Size = 4 millimeters\nAfter saving this copy and paste this entry as TitleCommand \u0026amp; MenuButton.\nLast but not least we will add a StatusBar UIID with:\nBackground color of B00A31\nBackground Transparency 255\nWe now have this which is already starting to look like an app:\nFigure 8. After styling the title\nStep 7: Convert the Functionality The other UI elements are too simple and often inconsistent so we’ll just delete the corresponding .gui \u0026amp; .java\nfiles representing those other widgets and implement them dynamically. This is especially crucial since the original\napp has some \u0026ldquo;androidisms\u0026rdquo; embedded into it making the code conversion challenging.\nE.g. the original app didn’t include a Note business object abstraction which is pretty basic so we added that\nto get started:\npublic class Note implements Externalizable { private static ArrayList\u0026lt;Note\u0026gt; notes; private String title = \u0026quot;\u0026quot;; private String body = \u0026quot;\u0026quot;; private boolean bodyHidden; private boolean starred; private int color = 0xffffff; private float fontSize = 2; private boolean deleted; /** * @return the title */ public String getTitle() { return title; } /** * @param title the title to set */ public void setTitle(String title) { this.title = title; } /** * @return the body */ public String getBody() { return body; } /** * @param body the body to set */ public void setBody(String body) { this.body = body; } /** * @return the bodyHidden */ public boolean isBodyHidden() { return bodyHidden; } /** * @param bodyHidden the bodyHidden to set */ public void setBodyHidden(boolean bodyHidden) { this.bodyHidden = bodyHidden; } /** * @return the starred */ public boolean isStarred() { return starred; } /** * @param starred the starred to set */ public void setStarred(boolean starred) { this.starred = starred; } /** * @return the color */ public int getColor() { return color; } /** * @param color the color to set */ public void setColor(int color) { this.color = color; } /** * @return the fontSize */ public float getFontSize() { return fontSize; } /** * @param fontSize the fontSize to set */ public void setFontSize(float fontSize) { this.fontSize = fontSize; } @Override public int getVersion() { return 1; } @Override public void externalize(DataOutputStream out) throws IOException { Util.writeUTF(title, out); Util.writeUTF(body, out); out.writeBoolean(bodyHidden); out.writeBoolean(starred); out.writeInt(color); out.writeFloat(fontSize); } @Override public void internalize(int version, DataInputStream in) throws IOException { title = Util.readUTF(in); body = Util.readUTF(in); bodyHidden = in.readBoolean(); starred = in.readBoolean(); color = in.readInt(); fontSize = in.readFloat(); } @Override public String getObjectId() { return \u0026quot;Note\u0026quot;; } public static ArrayList\u0026lt;Note\u0026gt; getNotes() { if(notes == null) { notes = (ArrayList\u0026lt;Note\u0026gt;)Storage.getInstance().readObject(\u0026quot;notes\u0026quot;); if(notes == null) { notes = new ArrayList\u0026lt;\u0026gt;(); } } return notes; } public void saveNote() { if(!notes.contains(this)) { notes.add(this); } Storage.getInstance().writeObject(\u0026quot;notes\u0026quot;, notes); } public void delete() { notes.remove(this); deleted = true; Storage.getInstance().writeObject(\u0026quot;notes\u0026quot;, notes); } public boolean isDeleted() { return deleted; } } Notice that this class encapsulates all the handling/storage of notes, I kept it as simple as possible to avoid\nany complexities and just implemented simple serialization for persistence.\nOnce we have that abstraction everything else becomes trivial, all we need is a single additional class we\nhave below:\npublic class EditNote extends Form { private static final int[] COLORS = { 0x44a1eb, 0x77ddbb, 0xbbe535, 0xeeee22, 0xffbb22, 0xf56545, 0xff5997, 0xa767ff, 0xffffff }; Command hideShowCommand; public EditNote(Note n, boolean isNew, ActivityMain parentForm) { __**(1)** super(\u0026quot;\u0026quot;, new BorderLayout()); __**(2)** TextField title = new TextField(n.getTitle(), \u0026quot;Title\u0026quot;, 20, TextArea.ANY); TextArea body = new TextArea(n.getBody()); body.setHint(\u0026quot;Note\u0026quot;); title.getHintLabel().setUIID(\u0026quot;NoteTitle\u0026quot;); title.getHintLabel().getAllStyles().setFgColor(0xcccccc); add(BorderLayout.NORTH, title); add(BorderLayout.CENTER, body); title.setUIID(\u0026quot;NoteTitle\u0026quot;); body.setUIID(\u0026quot;NoteBody\u0026quot;); Font fnt = body.getUnselectedStyle().getFont(); __**(3)** body.getAllStyles().setFont(fnt.derive(Display.getInstance().convertToPixels(n.getFontSize()), Font.STYLE_PLAIN)); getContentPane().getUnselectedStyle().setBgTransparency(255); getContentPane().getUnselectedStyle().setBgColor(n.getColor()); getToolbar().addMaterialCommandToRightBar(\u0026quot;\u0026quot;, FontImage.MATERIAL_PALETTE, e -\u0026gt; { Dialog colorPicker = new Dialog(\u0026quot;dialog_note_colour\u0026quot;); __**(4)** colorPicker.setDisposeWhenPointerOutOfBounds(true); colorPicker.setBackCommand(\u0026quot;\u0026quot;, null, ee -\u0026gt; colorPicker.dispose()); colorPicker.setLayout(new GridLayout(3, 3)); for(int iter = 0 ; iter \u0026lt; COLORS.length ; iter++) { Button choose = new Button(\u0026quot;\u0026quot;); Style s = choose.getAllStyles(); s.setAlignment(Component.CENTER); int color = COLORS[iter]; s.setBorder(RoundBorder.create().color(color)); if(color == getContentPane().getUnselectedStyle().getBgColor()) { FontImage.setMaterialIcon(choose, FontImage.MATERIAL_CHECK_CIRCLE, 3.5f); } choose.addActionListener(ee -\u0026gt; { colorPicker.dispose(); getContentPane().getUnselectedStyle().setBgColor(color); repaint(); }); colorPicker.add(choose); } colorPicker.showPacked(BorderLayout.CENTER, true); }); getToolbar().setBackCommand(\u0026quot;\u0026quot;, e -\u0026gt; { n.setTitle(title.getText()); __**(5)** n.setBody(body.getText()); n.setColor(getContentPane().getUnselectedStyle().getBgColor()); if(isNew) { if(Dialog.show(\u0026quot;Save Changes\u0026quot;, \u0026quot;\u0026quot;, \u0026quot;Yes\u0026quot;, \u0026quot;No\u0026quot;)) { n.saveNote(); parentForm.addNote(n); } } else { n.saveNote(); } parentForm.showBack(); }); getToolbar().addMaterialCommandToOverflowMenu(\u0026quot;Font Size\u0026quot;, FontImage.MATERIAL_FORMAT_SIZE, e -\u0026gt; { Slider s = new Slider(); __**(6)** s.setMinValue(0); s.setMaxValue(50); s.setProgress(Math.round(n.getFontSize() * 10)); s.setEditable(true); InteractionDialog id = new InteractionDialog(); id.setUIID(\u0026quot;Dialog\u0026quot;); id.setLayout(new BorderLayout()); id.add(BorderLayout.CENTER, s); s.addDataChangedListener((i, ii) -\u0026gt; { n.setFontSize(1 + ((float)s.getProgress()) / 10.0f); body.getAllStyles().setFont(fnt.derive(Display.getInstance().convertToPixels(n.getFontSize()), Font.STYLE_PLAIN)); body.repaint(); }); Button ok = new Button(\u0026quot;OK\u0026quot;); id.add(BorderLayout.SOUTH, ok); ok.addActionListener(ee -\u0026gt; id.dispose()); id.show(getLayeredPane().getHeight() - Display.getInstance().convertToPixels(10), 0, 0, 0); }); addHideShowCommand(n); } void addHideShowCommand(Note n) { __**(7)** if(hideShowCommand != null) { getToolbar().removeOverflowCommand(hideShowCommand); } if(n.isBodyHidden()) { hideShowCommand = getToolbar().addMaterialCommandToOverflowMenu(\u0026quot;Show Body\u0026quot;, FontImage.MATERIAL_VISIBILITY, e -\u0026gt; { n.setBodyHidden(false); addHideShowCommand(n); }); } else { hideShowCommand = getToolbar().addMaterialCommandToOverflowMenu(\u0026quot;Hide Body\u0026quot;, FontImage.MATERIAL_VISIBILITY_OFF, e -\u0026gt; { n.setBodyHidden(true); addHideShowCommand(n); }); } } } I mixed several concepts from the original code (e.g. the color picker etc) into a single entry.\n__1 | The constructor of the form accepts the parent form and whether this is a new note. We need this\nto determine whether to add a new note when going back. __2 We use border layout which allows us to place the title in the north and the body in the center. This is very convenient to take up available space __3 We set some UI elements directly instead of via UIID setting in the designer, this allows us to modify things in runtime and is sometimes more convenient than going thru the design tool. In this case we need to set the font size that might differ per note __4 The color picker dialog is just a regular dialog with a grid layout that shows a round border to give the color options. Since the code was so simple I didn’t see the need to move it to another class. __5 The back command does the save operation for consistency with the original app. Personally I would rather have a check option to save rather than show a dialog but I preferred consistency over personal preference __6 Instead of 3 hardcoded sizes I chose to show a slider in an interaction dialog that allows editing the UI while working with the dialog. This creates a nice effect where you can drag the slider and instantly see the font grow/shrink __7 The command in the overflow menu changes based on state so I placed this in a separate method so it can be removed/re-added Now comes the point of binding this together into the first form…​ We’ll change the constructor to this:\npublic ActivityMain(com.codename1.ui.util.Resources resourceObjectInstance) { super(\u0026quot;app_name\u0026quot;); initGuiBuilderComponents(resourceObjectInstance); FloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_ADD); fab.bindFabToContainer(getContentPane()); fab.addActionListener(e -\u0026gt; { __**(1)** Note n = new Note(); new EditNote(n, true, ActivityMain.this).show(); }); ArrayList\u0026lt;Note\u0026gt; notes = Note.getNotes(); __**(2)** if(notes.size() \u0026gt; 0) { removeAll(); for(Note n : notes) { addNote(n); } } getToolbar().addSearchCommand(e -\u0026gt; search((String)e.getSource())); __**(3)** getToolbar().addCommandToOverflowMenu(\u0026quot;Backup Notes\u0026quot;, null, e -\u0026gt; Log.p(\u0026quot;Todo\u0026quot;)); getToolbar().addCommandToOverflowMenu(\u0026quot;Restore Notes\u0026quot;, null, e -\u0026gt; Log.p(\u0026quot;Todo\u0026quot;)); getToolbar().addCommandToOverflowMenu(\u0026quot;Rate App\u0026quot;, null, e -\u0026gt; Log.p(\u0026quot;Todo\u0026quot;)); } There are several interesting things here:\n__1 We listen to an event on the floating action button then launch the new edit UI code __2 We load the notes and place them into the UI, I’ll get into addNote below __3 Search is one line of code which we list below Lets start with add/create note which is one of the trickier methods here:\nprivate Container createNoteCnt(Note n) { Button title = new Button(n.getTitle()); __**(1)** title.setUIID(\u0026quot;NoteTitle\u0026quot;); CheckBox star = CheckBox.createToggle(\u0026quot;\u0026quot;); __**(2)** star.setUIID(\u0026quot;NoteTitle\u0026quot;); FontImage.setMaterialIcon(star, FontImage.MATERIAL_STAR_BORDER, 4); star.setPressedIcon(FontImage.createMaterial(FontImage.MATERIAL_STAR, \u0026quot;NoteTitle\u0026quot;, 4)); star.setSelected(n.isStarred()); star.setBlockLead(true); star.addActionListener(e -\u0026gt; { n.setStarred(star.isSelected()); n.saveNote(); }); Container cnt; if(!n.isBodyHidden()) { __**(3)** TextArea body = new TextArea(n.getBody()); body.getAllStyles().setBgColor(n.getColor()); body.setUIID(\u0026quot;NoteBody\u0026quot;); body.setEditable(false); Font fnt = body.getUnselectedStyle().getFont(); body.getAllStyles().setFont(fnt.derive(Display.getInstance().convertToPixels(n.getFontSize()), Font.STYLE_PLAIN)); cnt = BorderLayout.center( BoxLayout.encloseY(title, body) ).add(BorderLayout.EAST, star); } else { cnt = BorderLayout.center(title). add(BorderLayout.EAST, star); } cnt.setLeadComponent(title); cnt.getAllStyles().setBgTransparency(255); __**(4)** cnt.getAllStyles().setBgColor(n.getColor()); Button delete = new Button(\u0026quot;\u0026quot;); FontImage.setMaterialIcon(delete, FontImage.MATERIAL_DELETE, 4); SwipeableContainer sc = new SwipeableContainer(delete, cnt); __**(5)** delete.addActionListener(e -\u0026gt; { n.delete(); sc.close(); sc.remove(); getContentPane().animateLayout(800); }); title.addActionListener(e -\u0026gt; { __**(6)** if(!n.isDeleted()) { new EditNote(n, false, this).show(); addShowListener(ee -\u0026gt; { getContentPane().replace(sc, createNoteCnt(n), null); removeAllShowListeners(); }); } }); sc.putClientProperty(\u0026quot;note\u0026quot;, n); __**(7)** return sc; } __1 | A note entry in the main screen is a lead component. A lead component is a unique concept to Codename One.\nIn it a component (in this case the title button) takes the \u0026ldquo;lead\u0026rdquo; over the Container hierarchy so all clicks within that\nspecific hierarchy, state changes etc. map to the button and its events. This means that clicking the text area below\nthe button will act as if we clicked the button. __2 The star is a toggle button with two states, which solves a lot of the complexities. We exclude it from the lead component hierarchy so it can be toggled independently. __3 The body of the note can be hidden in which case we will have two states the font size of the body can be enlarged which is another special case we check here __4 The background is set in the Container to allow the whole thing to take up the selected color. I could have used a \u0026ldquo;round rect\u0026rdquo; background to look similar to the original but that design is somewhat outdated and I chose to go with the swipe container which works better with full row (it would look awkward with round borders). __5 We wrap everything in a SwipeableContainer to allow the user to swipe the UI and see the delete button. The original UI had a long press action for delete which is probably a bit outdated design wise. __6 If the user edits an existing node instead of writing code to apply the changes we just create a new node component and throw away the old node component. __7 Client properties allow us to store meta-data within a component. This is very useful and we use that data in the search method below! void search(String text) { if(text == null || text.length() == 0) { for(Component c : getContentPane()) { c.setHidden(false); c.setVisible(true); } } else { for(Component c : getContentPane()) { Note n = (Note)c.getClientProperty(\u0026quot;note\u0026quot;); text = text.toLowerCase(); boolean show = n.getTitle().toLowerCase().indexOf(text) \u0026gt; -1 || n.getBody().toLowerCase().indexOf(text) \u0026gt; -1; c.setHidden(!show); c.setVisible(show); } } getContentPane().animateLayout(200); } The search method is really simple, it has a special case up front to cancel search for an empty string.\nIt then proceeds to loop over the components and hide/show based on the Note associated with the component.\nNotice that we could have queried the component values but because the body might be hidden the hierarchy\nmight be slightly different so this is a simpler solution overall.\nWe then animate the layout to move the components into place…​\nMinor Tunings for the Final Result Since the overflow menu is overly \u0026ldquo;Android oriented\u0026rdquo; I decided to move everything into the title bar area which\nmakes the app look better everywhere as there is space available there.\nI also added a colors.xml file to allow native Android styling to use the theme colors, I just placed this file under\nthe native/android directory:\n\u0026lt;?xml version=\u0026quot;1.0\u0026quot; encoding=\u0026quot;utf-8\u0026quot;?\u0026gt; \u0026lt;resources\u0026gt; \u0026lt;color name=\u0026quot;colorPrimary\u0026quot;\u0026gt;#ffCE0A31\u0026lt;/color\u0026gt; \u0026lt;color name=\u0026quot;colorPrimaryDark\u0026quot;\u0026gt;#FFB00A31\u0026lt;/color\u0026gt; \u0026lt;color name=\u0026quot;colorAccent\u0026quot;\u0026gt;#800000ff\u0026lt;/color\u0026gt; \u0026lt;/resources\u0026gt; It makes very subtle differences you would mostly see while task switching.\nI also made some theme refinements adding padding in the right places and fixing some fonts/colors but\nnothing significant.\nFinal Thoughts Porting the whole app and writing this took me 1 day during which I also did other typical tasks. I’m assuming\nit would have taken longer to a person who isn’t as familiar with Codename One as I am although that person\nwouldn’t need to write an article about it either…​\nLooking over the Android code and the corresponding Codename One code the differences are staggering.\nI’m (obviously) biased but the amount of code and it’s complexity is significantly lower in Codename One.\nThe porting from Android isn’t a trivial task as it does require you to know Codename One. The process has a\nlot of kinks some of which just aren’t fixable since we don’t want Codename One to venture into the complexity\nlevels of Android.\nHowever, if you express interest and start filing issues/participating with the conversion wizard work that\nSteve has done we will invest time and effort to match your time \u0026amp; effort!\nThis should make future iterations of this tutorial even simpler and produce far more satisfying initial results.\nI’ve compared the native app side by side with the Codename One app and with the exception of the overflow\nmenu which could use some work, our app looks just as \u0026ldquo;native\u0026rdquo; on an Android phone.\nWith one simpler, shorter code base I was able to reach iOS, Android, Windows \u0026amp; JavaScript not to mention\ndesktop targets…​\nIn this specific app I can’t see any compromises in quality/appearance or functionality. This is obviously not the\ncase for every app in existence but it is the case for many (most?) apps.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/port-native-android-app-ios-iphone-guide/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/port-native-android-app-ios-iphone-guide/port-an-android-app-to-ios.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe get contacted quite a bit about the prospect of porting applications that were already written using the Android\u003cbr\u003e\nAPI. In this quick tutorial we will walk you thru the paces of converting a simple Android application to\u003cbr\u003e\na Codename One application. We will also start with some basic tips covering the differences between Android \u0026amp;\u003cbr\u003e\nCodename One development.\u003c/p\u003e\n\u003ch3 id=\"how-does-codename-one-differ-from-android-development\"\u003eHow does Codename One Differ from Android Development?\u003c/h3\u003e\n\u003cp\u003eCodename One allows Android developers familiar with Java to instantly build native applications for Android,\u003cbr\u003e\niOS, Windows and other platforms.\u003c/p\u003e","title":"How to: Port Native Android App to iOS (iPhone) Guide"},{"content":"\nGenerating a template from a PSD isn’t hard but it isn’t a trivial task either, in this recurring segment I will try to\ngenerate good looking Codename One templates from freely available PSD files. Since this requires some\neffort I don’t think I’ll be able to keep this as a weekly segment but I’ll try to post such a template once every\ntwo or three weeks. If you know of a free PSD that you’d like to see as a Codename One app point me at it\nin the comments and I might integrate it in a future post!\nUnlike previous tutorials I won’t cover the process of extracting the\ntemplate and building it as this will take MUCH longer than just doing it. I will try to discuss the highlights,\ncompromises etc. You can study the source code/theme and ask questions in the comments if something\nI achieved is unclear.\nThis time I will port the Mobile Screens Material UI PSD.\nThis is not from Google but it based on the Material design principals.\nYou can check out the full source code on github here.\nThe End Result I’m pretty pleased with the end result, this took me about a day and a half of work to do. The app build is 478kb\nwell bellow the free quota limit and this is with full HD resources. The resulting Android APK is 1.8mb which is\npretty small for an app like this.\nCheck out a preview of this UI running on the right here thanks to the JavaScript port of Codename One,\nnotice that you can also launch this same preview in full screen here. You can also\ndownload the Android APK to your device from here. We can’t\ndistribute demos thru appstores due to vendor restrictions so you will need to build for other platforms on your own…​\nWhen running the demo you can switch between the charts/profile pages by clicking any entry in the sidemenu.\nYou can restart the demo by clicking logout. You can also swipe the welcome form. I explicitly avoided implementing\nany form of functionality to keep things relatively simple.\nYou can see the PSD’s we used as a base in this directory.\nI extracted very few images from the PSD’s and mostly used the colors and components where possible, you can\nsee the exact image resources I extracted and used\nhere. Notice I provided\na duke image of our own since the swipe tutorial only had one page designed in the PSD and I had to makeup\nanother page.\nBelow are screenshots of this app running on my OPO Android device:\nFigure 1. Login screen\nFigure 2. Welcome wizard page 1\nFigure 3. I designed another page for the welcome wizard so we’ll have 2 pages…​\nFigure 4. User form with complex toolbar\nFigure 5. Sidemenu for the user form and chart form\nFigure 6. Chart form, I’m not sure if the original chart design is doable in any tool…​\nThe UI I’ve learned a bit about how we can make Codename One more friendly to UI designs, I’ll incorporate some of\nthese lessons into an update of this demo and make some changes to Codename One. I’ll go into more details\non that in an upcoming post.\nI chose to design all the forms as subclass of Form, this isn’t necessarily the best way but it’s a common pattern\nthat’s intuitive to most developers.\nThis allowed me to unify the code for the side menu which appears on two of the forms.\nThe title areas in this demo are either non-existent or heavily customized to the point of being a purely custom\ncomponent. This posed some challenges sometimes with the builtin functionalities (e.g. status bar, menu icon etc.).\nAs a result I just hid the menu bar icon entirely and added one of my own.\nA potential enhancement would be to shrink the title as we scroll down like this.\nFinal Word After this is cleaned up a bit I’d love to have this template as part of our builtin demos, I’d also like to build more\nof those as I feel this is a great learning tool for us and for you.\nI’ll try to post a followup article about the improvements required to make this code easier. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nBayu Sanjaya — October 11, 2016 at 12:45 pm (permalink) Bayu Sanjaya says:\nThis is awesome. Clean and clear. Will try this.\nChidiebere Okwudire — October 11, 2016 at 1:03 pm (permalink) Chidiebere Okwudire says:\nNice. Getting inspired… Can you share the URL from which you downloaded the free PSDs?\nShai Almog — October 11, 2016 at 1:32 pm (permalink) Shai Almog says:\nSure: https://colorlib.com/wp/fre…\nfaugan — October 12, 2016 at 3:02 pm (permalink) faugan says:\nhi,\ni am trying to integrate the new material screen ui kit project that i\nhave just download from github into my netbeans, but i am having some\nerror, the first one is import\ncom.codename1.components.FloatingActionButton; the FloatingActinButton\nseems not to be in the list of component, how can i fix that? (that\nerror is in the file \u0026ldquo;ProfileForm.java line 22″) , The second error is\nin the file SideMenuBaseForm.java from line 66 where we have\ngetToolbar().addMaterialCommandToSideMenu, how can i fix these two\nerrors, FWI i have create a new project then i copy one by one the files\nfrom the project i have downloaded from github\nShai Almog — October 13, 2016 at 2:22 am (permalink) Shai Almog says:\nHi,\nYou are using an old version of the Codename One libraries. You need to update to the latest.\nfaugan — October 13, 2016 at 9:30 am (permalink) faugan says:\nThanks i updated my codename one and it works, thanks, great work guys\nAdebisi Oladipupo — February 20, 2017 at 10:03 pm (permalink) Adebisi Oladipupo says:\nI downloaded this material UI Kit into INtelij but could not run it. I saw it shows errors on the java files that may be causing this. Also, I am unable to open the included forms in GUI builder probably due to the same reason. Should I be importing this project or opening it in my IDE? What settings do I need to change when trying to learn from these samples? I had this problem before with Chrome demo when I opened a downloaded copy. But the issue was corrected by creating a new project and selecting from the demo tab. However, this material UI Kit is not listed in the demo tab and I am stuck. Please help.\nShai Almog — February 21, 2017 at 7:06 am (permalink) Shai Almog says:\nMake sure your plugin is up to date. You don’t need to download it as the material demo (MSUIKit) is available in the new project wizard there. You can also follow this guide on setting up a project from git: https://www.codenameone.com…\nAdebisi Oladipupo — February 21, 2017 at 1:57 pm (permalink) Adebisi Oladipupo says:\nI suppose the samples are done in NetBeans as the sample is not in Intellij IDE. I will follow the workaround in the link you provided for my IDE. Just curious. Is the latest plugin v3.6 as that is what I have in IntelliJ?\nShai Almog — February 22, 2017 at 7:13 am (permalink) Shai Almog says:\nIt’s supposed to be in IntelliJ too. Just looked in the code and it seems we have an issue there. We’ll fix it for the next update.\nAdebisi Oladipupo — February 22, 2017 at 8:42 pm (permalink) Adebisi Oladipupo says:\nGreat. That way I don’t have to switch IDE from IntelliJ. Thanks\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/template-mobile-material-screens-ui-kit/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/template-mobile-material-screens-ui-kit/Mobile-Material-UI-Screens.png\"\u003e\u003c/p\u003e\n\u003cp\u003eGenerating a template from a PSD isn’t hard but it isn’t a trivial task either, in this recurring segment I will try to\u003cbr\u003e\ngenerate good looking Codename One templates from freely available PSD files. Since this requires some\u003cbr\u003e\neffort I don’t think I’ll be able to keep this as a weekly segment but I’ll try to post such a template once every\u003cbr\u003e\ntwo or three weeks. If you know of a free PSD that you’d like to see as a Codename One app point me at it\u003cbr\u003e\nin the comments and I might integrate it in a future post!\u003c/p\u003e","title":"Template – Mobile Material Screens UI Kit (Cross Platform PSD)"},{"content":"\nGoogle Play Services is a proprietary set of tools that Google licenses to vendors under limited conditions.\nIn recent years more and more features go into Google Play Services making it harder to build an app without it.\nIn our effort to \u0026ldquo;do the right thing\u0026rdquo; we include some of the Google Play Services tools into applications to remain\ncompatible with code that requires these libraries. This also makes some features (such as location) work better.\nHowever,if you don’t use: Ads, Push, Maps or Location then you might not need Google Play Services at all…​\nAt this time the overhead of including this subset of Google play services is 1.5mb to your final APK size. This\nisn’t much but if your app isn’t big then this might double its size and slow down the cloud build process.\nOnce you declare that one Google play service isn’t needed we implicitly assume you understand what you are\ndoing and let you pick the services manually so just setting the build hint android.playService.ads=false reduced\nthose 1.5mb from the app size with no ill effect.\nIn fact one of the services we include is the ads service and Google notices that when you submit an app. It\nproduces a warning if you add an app with the ads framework but declare that you don’t have ads, this small\ntrick removes it.\nCheck out the build hints section in the developer guide for more information on how you can deeply customize\nCodename One. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nSadart — October 10, 2016 at 2:44 pm (permalink) Sadart says:\nThanks for the tip. I have already seen the 1.5mb app size reduction in my latest build following the tip.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/tip-disable-google-play-services/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/tip-disable-google-play-services/google-play-services.png\"\u003e\u003c/p\u003e\n\u003cp\u003eGoogle Play Services is a proprietary set of tools that Google licenses to vendors under limited conditions.\u003cbr\u003e\nIn recent years more and more features go into Google Play Services making it harder to build an app without it.\u003c/p\u003e\n\u003cp\u003eIn our effort to \u0026ldquo;do the right thing\u0026rdquo; we include some of the Google Play Services tools into applications to remain\u003cbr\u003e\ncompatible with code that requires these libraries. This also makes some features (such as location) work better.\u003cbr\u003e\nHowever,if you don’t use: Ads, Push, Maps or Location then you might not need Google Play Services at all…​\u003c/p\u003e","title":"Tip: Disable Google Play Services"},{"content":"\nAs you may recall most of us are on vacation and the\nfew of us who are not have to work even harder than usual to keep things chugging along. I’m in India for\nOctober (not on vacation) which slows down my work even further outside of my \u0026ldquo;home base\u0026rdquo;.\nWe’re releasing a much needed plugin update today with huge GUI builder changes, new round border support\nin the designer and many bug fixes in the settings etc.\nOn stack overflow things were as usual:\nTestRecorder How-To run test You can run recorded tests via the tests ant target which maps directly to the tests IDE action in NetBeans\nRead on stackoverflow…​\nClosing a socket When you close a stream it implicitly closes the socket, when building this we thought that’s intuitive but I can\nsee how this can be confusing\nRead on stackoverflow…​\nLocal notifications in codename one These should work fine for all google supported tablets\nRead on stackoverflow…​\nFingerprint scanner in codename one Fingerprint scanning is still emerging, if we see enough demand for it we will add it just like any feature\nRead on stackoverflow…​\nHow to make date time picker components are editable in code name one? These map to native code so they aren’t as customizable as other Codename One API’s.\nRead on stackoverflow…​\nHow to listen for cell selection on a table? Overriding the create cell in the table allows the full power of Codename One components\nRead on stackoverflow…​\nHow to code an iPhone style popup menu in CN1? This was requested enough times to warrant a code sample\nRead on stackoverflow…​\nDownloading file in Codename one It’s important to keep FileSystemStorage \u0026amp; Storage separate\nRead on stackoverflow…​\nHow-to set app name and app icon This should be pretty easy especially with the new Codename One Settings UI\nRead on stackoverflow…​\nHow to generate JUnit XML reports in Codename One? I didn’t even remember we had this and it’s code that I wrote…​ I don’t know if I’m too old or if I wrote too much code…​\nRead on stackoverflow…​\nHow to use resource file of GUI Designer The transition to the new GUI builder will be painful because of the confusion aspect of two gui builders\nRead on stackoverflow…​\nActionlistener not working This was triggered by a new button created on top of the current button\nRead on stackoverflow…​\nTextArea / Textfield datachange listener with growing The whole single line text area is a source of a lot of confusion for developers, we need to find a way to make this\nmore intuitive\nRead on stackoverflow…​\nTextView Foreground Color Maybe we should deprecate getStyle() just to get people to notice the incorrect usage of that method?\nRead on stackoverflow…​\nRestoring the purchases made with codenameone This is builtin to the iOS implementation of IAP\nRead on stackoverflow…​\nWhere to place database There is a detailed guide for this in the developer guide section on SQL\nRead on stackoverflow…​\nDelete the storage file in iOS It’s important to keep FileSystemStorage \u0026amp; Storage separate, we need to simplify that code\nRead on stackoverflow…​\nRoundMask gives exception when image of specific size is used The mask and image sizes must be identical, we throw this exception to prevent worse errors later on\nRead on stackoverflow…​\nComponent not showing when swipeable container is swiped using code This is a bit hidden knowledge thats required for working with this\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xxvi/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xxvi/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAs you may recall \u003ca href=\"/blog/merged-peer-october-vacations-india-trip.html\"\u003emost of us are on vacation\u003c/a\u003e and the\u003cbr\u003e\nfew of us who are not have to work even harder than usual to keep things chugging along. I’m in India for\u003cbr\u003e\nOctober (not on vacation) which slows down my work even further outside of my \u0026ldquo;home base\u0026rdquo;.\u003c/p\u003e\n\u003cp\u003eWe’re releasing a much needed plugin update today with huge GUI builder changes, new round border support\u003cbr\u003e\nin the designer and many bug fixes in the settings etc.\u003c/p\u003e","title":"Questions of the Week XXVI"},{"content":"\nChen has been working quite a bit on the new GUI Builder and made some significant changes both to it’s look and\nfunctionality. These changes are wide reaching covering the appearance, functionality and stability of the GUI Builder.\nFigure 1. Starting page after recent changes see if you can spot them all…​\nPalette Relocation The component palette is using an accordion now and was relocated to the right side of the UI. It is also available\nas a popup below the tree…​\nIf you select a node in the tree and press the + sign below the tree you will see the palette entries and you can click\none of them to add it into the given node as such:\nFigure 2. New popup palette UI\nUp/Down Move Entries in the tree can now be moved up/down the tree even between container boundaries.\nYou can do this by selecting an entry and pressing the up arrow ^ or similar down arrow next to it below the tree.\nThis is useful for simple reordering without drag and drop. Ideally we wanted to enable drag \u0026amp; drop in the tree but\nthis collides with the scrolling functionality to some degree so we took the lazy approach.\nMaterial Icons Support You can now pick a material design icon directly from the designer. When you click any icon property you will\nsee this dialog\nFigure 3. Pick material icon or image from the resource file\nIf you choose to pick an image from the material design icon font you will be presented with a dialog like this\ncoupled with a search field:\nFigure 4. List of material design icons\nMissing In Action As part of these changes we removed a couple of features, let us know if they matter to you.\nMulti Select – This was a very powerful feature that allowed editing multiple entries at once \u0026amp; enclosing them\nin a parent Container. It had confusing usage and a few lingering bugs\nPalette Search – When migrating the palette from a Container to an Accordion search was removed. I personally\nliked that search a lot and used it quite a bit as I prefer typing\nWe have internal debates on whether these features are \u0026ldquo;really\u0026rdquo; needed/used. If you used them and want them\nback let us know!\nMoving Forward We hope to release a plugin update this coming Friday which will include all of these changes…​\nWhere do we go from here is very much up to you!\nWe need your bug reports, suggestions and requests to tune the designer to match your workflow. Naturally we\ncan’t entertain every request/suggestion but we try to listen and base our work on your needs. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\ndisqus — October 12, 2016 at 4:14 pm (permalink) Updated netbeans plugin to Version: 3.5.5. Post update GUI Builder button events not functional after update. On looking at the generated code found this\npublic void actionPerformed(com.codename1.ui.events.ActionEvent ev) {\ncom.codename1.ui.Component sourceComponent = ev.getComponent();\nif(sourceComponent.getParent().getLeadParent() != null) {\nsourceComponent = sourceComponent.getParent().getLeadParent();\n}\nif(sourceComponent == gui_Button) {\n}\n}\nwhich should be\nif(sourceComponent == gui_Button) {\nonButtonActionEvent(ev);\n}\nKindly fix the problem and let me know how can I do a dirty fix till then because this is generated code and gets overwritten everytime.\nChen Fishbein — October 12, 2016 at 6:33 pm (permalink) Thanks, it will be fixed for the next update.\nIn the meantime you can just add an ActionListener to your Button right after the call to initGuiBuilderComponents\nChidiebere Okwudire — November 1, 2016 at 10:02 am (permalink) How does the new GUI builder paradigm work with (UI) inheritance?\nUse case: Several forms share a lot in common (custom header/footer/common body layout). As such I would like to have a base form and in subsequent forms, include the form content in my custom body layout. A quick look didn’t reveal any obvious way to achieve this without overriding the Form.addComponent() methods…. Please share your thoughts on how this can best be realized\nShai Almog — November 1, 2016 at 10:17 am (permalink) We did just that in the new Phoenix demo, all forms derive from a common base form for the common side menu.\nChidiebere Okwudire — November 1, 2016 at 11:00 am (permalink) Chidiebere Okwudire says:\nPerfect timing. I’ll have a look!\ndisqus — November 5, 2016 at 8:59 pm (permalink) disqus says:\nworking in the new version of the plugin 3.5.7\nShai Almog — November 6, 2016 at 4:23 am (permalink) Shai Almog says:\nRight click the project. Select properties and click OK in the properties dialog. Try running the project again.\nFrancesco Galgani — June 16, 2017 at 1:30 pm (permalink) Francesco Galgani says:\nI recently found this old blog post, that clarify why I didn’t find the \u0026ldquo;Multi Select\u0026rdquo; feature that is indicated in the developer guide (that should be updated).\nI think that is very important to be able to put some components in a container easily (and viceversa, that is put some components out of their container).\nThe actual New Gui Builder has a lot of issues: if you change a value in the properties (like a component name), the tree is not updated; if I add two buttons and a container, I cannot drag and drop the buttons in the container (I can use move up/down buttons, but they are not convenient if I have a lot of components); if I select a container in tree and click on Cut, that container is still shown (the tree is not updated); if I select again that container and I click on Cut, I get the error \u0026ldquo;No component is selected\u0026rdquo;; if I cut and paste a component, its name will be changed; if I set a nested container as BorderLayout and then I click in tree to a button inside it, the box below the tree remain as it is, showing the layout of the container instead of properties of the button; I exerienced that in the preview some components are missing, but they are shown clicking on the Preview Design icon; if I set a container with a Table layout, in the settings I can set rows and columns only, I cannot customize every cell like in an html table; etc., maybe I did not understand how to use Gui Builder, but in my opinion it’s buggy and difficult to use. I’m waiting for a new version of the Gui Builder, thank you for your effort to make it better 🙂\nThere is also a small bug both in the Gui Builder and in the Codename One Designer: some menu items are not shown when I click on the menu. For example, in the Gui Builder if I click on \u0026ldquo;File\u0026rdquo; I’ll see the underlying commands (Save, Exit), but if I move the mouse cursor to \u0026ldquo;Edit\u0026rdquo; or \u0026ldquo;Help\u0026rdquo; no commands underlying Edit or Help are shown (to get them, I have to click again on Edit or Help). In the Codename One Designer, the issue is a bit different: for example, I click on the menu voice \u0026ldquo;Codename One\u0026rdquo;, I see: Signup, Login, a blank space, Advanced. To see the \u0026ldquo;Live preview\u0026rdquo; item istead of the blank space (and other missing items replaced by blank spaces), I have to set the Look\u0026amp;Feel as cross-platform every time that I open the Designer (however I prefer the System Look\u0026amp;Feel).\nShai Almog — June 17, 2017 at 7:08 am (permalink) Shai Almog says:\nThanks for this feedback!\nWe have a big update for the GUI builder coming soon, I hope it will make it into 3.7. If so it will change everything about the GUI builder in a big way…\nThe problem with documenting something like this that evolves so quickly is that I just can’t keep up. If I will do a screencast or new screenshots now they will be wrong by July.\nWe do need these issue reports but the comment system is a great place to lose such feedback. I would suggest filing issues in the issue tracker here: http://github.com/codenameo…\nAlso include screenshots with the issues as some of these things I don’t follow like the voice menu which isn’t something that’s a part of our app.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/further-refined-cross-platform-mobile-gui-builder/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/further-refined-cross-platform-mobile-gui-builder/new-gui-builder.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eChen has been working quite a bit on the new GUI Builder and made some significant changes both to it’s look and\u003cbr\u003e\nfunctionality. These changes are wide reaching covering the appearance, functionality and stability of the GUI Builder.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Starting page after recent changes see if you can spot them all\u0026hellip;\" loading=\"lazy\" src=\"/blog/further-refined-cross-platform-mobile-gui-builder/new-ux-for-gui-builder.png\"\u003e\u003c/p\u003e\n\u003cp\u003eFigure 1. Starting page after recent changes see if you can spot them all…​\u003c/p\u003e\n\u003ch3 id=\"palette-relocation\"\u003ePalette Relocation\u003c/h3\u003e\n\u003cp\u003eThe component palette is using an accordion now and was relocated to the right side of the UI. It is also available\u003cbr\u003e\nas a popup below the tree…​\u003c/p\u003e","title":"Further Refined Cross Platform Mobile GUI Builder"},{"content":"\nHistorical note: Codename One\u0026rsquo;s UWP target was discontinued in release 7.0.229. This post is preserved for historical context only, and its build/setup instructions no longer apply to current Codename One projects.\nWe’ve mentioned the progress we made with the Universal Windows Platform support in the past. This support\nis moving at a very fast pace…​\nBy now we support SQLite as well as Media, Capture and a slew of other features that weren’t available for\nthe initial beta. At this rate we think that 3.6 can actually include a production version of the UWP port!\nOther than that we also added support for things such as native OS sharing on UWP as well as low level graphics\ntransforms. We also fixed many bugs in the port with text positioning, missing status bar, crashes etc.\nWe’re confident that we will see many new Codename One apps poping up in the Microsoft appstore\nin the coming months.\nOne of the problems we discovered is that the Nokia Lumia simulator that we sometimes used to debug windows\napps uses the wrong theme. Instead of the black Windows Metro style theme it incorrectly used the Android\nholo theme. If you have that simulator skin installed we suggest updating it via the Skins → More menu option.\nThis problem caused us to incorrectly tune the colors in the native theme for the kitchen sink. After fixing this we\nwere able to adapt the code. It’s important to notice that the default colors on Windows are the exact opposite\nof the Android/iOS black over white so if you rely on colors you need to be explicit.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/uwp-update/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/uwp-update/uwp-on-codenameone.jpg\"\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003eHistorical note:\u003c/strong\u003e Codename One\u0026rsquo;s UWP target was discontinued in release \u003cstrong\u003e7.0.229\u003c/strong\u003e. This post is preserved for historical context only, and its build/setup instructions no longer apply to current Codename One projects.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eWe’ve mentioned the progress we made with the Universal Windows Platform support in the past. This support\u003cbr\u003e\nis moving at a very fast pace…​\u003cbr\u003e\nBy now we support \u003ccode\u003eSQLite\u003c/code\u003e as well as \u003ccode\u003eMedia\u003c/code\u003e, \u003ccode\u003eCapture\u003c/code\u003e and a slew of other features that weren’t available for\u003cbr\u003e\nthe initial beta. At this rate we think that 3.6 can actually include a production version of the UWP port!\u003c/p\u003e","title":"UWP Update"},{"content":"\nAs we discussed before October will be relatively slow, this means that our original plan of a December release\nfor 3.6 will be challenging and produce a sub-par release. In the interest of making 3.6 a more significant release\nwe decided to postpone it to January 16th 2017.\nThe code freeze for this release will also move to January 9th as a result.\nNormally we could have done the release sooner but past experience has shown that releasing anything in late\nDecember or early January is inadvisable.\nDue to this shift it makes sense to shift the entire schedule of 3.7 onwards:\n3.7 – is now planned for May 9th with code freeze on May 2nd\n3.8 – is now planned for October 4th with code freeze on September 27th\nWe hope to have no further delays beyond that as we move forward with these releases. We have some great\nideas planned for 3.7 and beyond!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/pushing-back-3-6/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/pushing-back-3-6/codenameone-3-6.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAs we discussed before October will be relatively slow, this means that our original plan of a December release\u003cbr\u003e\nfor 3.6 will be challenging and produce a sub-par release. In the interest of making 3.6 a more significant release\u003cbr\u003e\nwe decided to postpone it to January 16th 2017.\u003c/p\u003e\n\u003cp\u003eThe code freeze for this release will also move to January 9th as a result.\u003c/p\u003e\n\u003cp\u003eNormally we could have done the release sooner but past experience has shown that releasing anything in late\u003cbr\u003e\nDecember or early January is inadvisable.\u003c/p\u003e","title":"Pushing Back 3.6"},{"content":"\nWe released an update a day early to deal with some regressions we had related to minor method signature changes\ntriggered by an overhaul of pre-released versions. Other than that this week has been a bit uneventful in terms of\nour work.\nOn stack overflow things were pretty standard:\nHow do I import an existing android studio project to eclipse so that it is native and becomes a codename application? We currently support NetBeans here but this is a bit problematic regardless\nRead on stackoverflow…​\nHow to read textfile line by line into textarea in codename one There are other ways to do this but this is the shortest/simplest\nRead on stackoverflow…​\nData Storage Solutions We recommend looking thru the developer guide to get started with those things\nRead on stackoverflow…​\nFilter optimization on set of containers invokeAndBlock is a tool that is still very cryptic to developers\nRead on stackoverflow…​\nWhen I open the Eclipse application I get this exit code error issue. How do I resolve this? Eclipse is a bit painful with the various versions of Windows\nRead on stackoverflow…​\nNetwork check works in android but same doesn’t work in iOS Some low level features just don’t exist in iOS\nRead on stackoverflow…​\nNullPointerException called on the current variable in codename one There are several issues with the code but the null pointer is the least of them\nRead on stackoverflow…​\nTwo AutoCompleteTextField in same form Filter for an autocomplete should be \u0026ldquo;smart\u0026rdquo; and cache data as much as possible\nRead on stackoverflow…​\nRetrieve IMSI by using CodenameOne, Cordova and AngularJS iOS etc. don’t provide access to low level details such as IMSI\nRead on stackoverflow…​\nkeyboard issue in iOS – codenameone It’s hard to get the VKB to act \u0026ldquo;just right\u0026rdquo; so we need accurate test cases where we can reproduce all the odd edge cases\nRead on stackoverflow…​\nFlip transition of the form is not smooth in iOS The transitions that require a screenshot would be slightly slower on iOS as the pipeline for offscreen buffers is much slower\nRead on stackoverflow…​\nHow to attach a command to longpress on a command in the Toolbar? We don’t have that builtin but since you can do anything you want in the Toolbar it is possible\nRead on stackoverflow…​\nCannot find type System.ApplicationException in module CommonLanguageRuntimeLibrary This isn’t really a Codename One question but rather usage of the code we released for the UWP port\nRead on stackoverflow…​\nTableLayout heightPercentage: percentage of what? That’s a good question, we simplified layout by blocking recursion so the percentage is based on guesses of eventual\nsize\nRead on stackoverflow…​\nRebuild list of containers without scrolling the list This is a bit problematic due to code that tries to \u0026ldquo;do the right thing\u0026rdquo;\nRead on stackoverflow…​\nHow to detect a ‘pinch out’ in a list of containers? This isn’t builtin but can probably be done using some low level API’s\nRead on stackoverflow…​\nSetup Google Analytics with Codename One Google analytics has some configuration complexities\nRead on stackoverflow…​\nInfiniteContainer Scrolling This might also be a regression related to new peer. It’s very hard to see in newer devices but you see it for a split\nsecond in very old phones\nRead on stackoverflow…​\nMedia has stopped working the way it should This might be a regression related to the migration to the Android new peer mode\nRead on stackoverflow…​\nIOS Build fails with annotations We don’t support runtime annotations due to problematic use cases involved. We need to work on improving the\nfailure related to that or implementing it\nRead on stackoverflow…​\nScrolling issue with keyboard There are some odd edge cases with the virtual keyboards in the various OS’s. Normally native widget libraries\nrecommend various hacks but we try to make it seamless\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xxv/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xxv/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe released an update a day early to deal with some regressions we had related to minor method signature changes\u003cbr\u003e\ntriggered by an overhaul of pre-released versions. Other than that this week has been a bit uneventful in terms of\u003cbr\u003e\nour work.\u003c/p\u003e\n\u003cp\u003eOn stack overflow things were pretty standard:\u003c/p\u003e\n\u003ch3 id=\"how-do-i-import-an-existing-android-studio-project-to-eclipse-so-that-it-is-native-and-becomes-a-codename-application\"\u003eHow do I import an existing android studio project to eclipse so that it is native and becomes a codename application?\u003c/h3\u003e\n\u003cp\u003eWe currently support NetBeans here but this is a bit problematic regardless\u003c/p\u003e","title":"Questions of the Week XXV"},{"content":"\nWe introduced the new RoundBorder API a couple of weeks ago and it’s already\npicking some usage. But to really take off it needs to be within the themes, starting with the next plugin update\nthe border section of the designer tool will include the options for round border.\nThis is a bit confusing since we already support a rounded border type. The rounded border type is a rectangle\nwith rounded corners where the round border has completely round sides or appears as a circle.\nTo make matters worse the round border has a ridiculous number of features/configurations that would have made\nthe already cluttered UI darn near impossible to navigate. To simplify we split the UI into 3 tabs for standard borders,\nimage borders and round border. This new UI is still a bit flaky but the result is what counts and the ability to build\na theme with these types of borders is tremendous.\nI hope that this addition to the designer will make the creation of great looking themes a bit easier.\nFigure 1. The round border support in the designers border section\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/round-border-in-the-designer/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/round-border-in-the-designer/round-border.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe introduced the new \u003ca href=\"/blog/round-border.html\"\u003eRoundBorder\u003c/a\u003e API a couple of weeks ago and it’s already\u003cbr\u003e\npicking some usage. But to really take off it needs to be within the themes, starting with the next plugin update\u003cbr\u003e\nthe border section of the designer tool will include the options for round border.\u003c/p\u003e\n\u003cp\u003eThis is a bit confusing since we already support a rounded border type. The rounded border type is a rectangle\u003cbr\u003e\nwith rounded corners where the round border has completely round sides or appears as a circle.\u003c/p\u003e","title":"Round Border in the Designer"},{"content":"There are many Codename One resources for building native mobile apps but they are often all over the place, in this blog post I’ll try to concentrate the best resources for people who already know Java and are looking to pick up Codename One. If you don’t know Java yet, please check out this post where we discuss resources for beginners to learn Java.\nWritten Docs and Tutorials • Create an Uber Clone in 7 Days – Even if you don’t purchase the full book, the free chapters available to download will help you get started quickly.\n• Developer Guide – if you haven’t read the developer guide you should! Notice that it also comes in a PDF. • JavaDocs – our JavaDocs include some hidden features such as the component gallery \u0026amp; layout gallery. • Sviluppare app multipiattaforma – Indice del corso introduttivo – Italian language free course for mobile cross-platform development by Francesco Galgani. • Port an Android app to iOS (iPhone) – a step by step guide on porting a real world Android app to Codename One and getting it onto all the major stores. • Chat App Tutorial – this six part series covered many ideas in Codename One including social login (Facebook, Google) IM style interface etc. • Using the new GUI Builder – this tutorial starts by reviewing the differences between the old and the new GUI builder followed by a review of building a simple app. • Working with native maps – using Google Maps in your app. • PSD to App Revisited – this is a remake of a great video tutorial from Steve Hannah (see below) where he covered the process of taking a Photoshop PSD design and making the app look like the PSD. The results are stunning. • Integrating 3rd party native SDK’s – this is one of our most ambitious tutorials it included 3 parts. Part 1, part 2 \u0026amp; part 3. • Websocket Support – this tutorial covers the cn1lib for websockets • Create a Gorgeous Sidemenu – 5 minute video \u0026amp; text tutorial on the creation of a good looking side navigation interface. • Introduction to In-App Purchase – this is a part of a series on in-app-purchase covering also Non-Renewable Subscriptions \u0026amp; Auto-Renewing Subscriptions. • Connecting to a MySQL Database from Codename One – includes two versions the second uses Java on the server side while the first uses a PHP backend and is arguably simpler to setup on the server for some cases. • Using Icon Fonts Such as Fontello – in this tutorial we review icon font usage in Codename One. These are very useful for resolution independent images.\n• Avoiding Lists – A common question is how to use a \u0026ldquo;List\u0026rdquo; in Codename One. In this tutorial we explain why lists in Codename One are problematic and the strategies you can use to create a list interface. • Understanding the Table Component – this tutorial is pretty self explanatory. • Understanding device density – in a tutorial written for \u0026ldquo;back to the future day\u0026rdquo; Steve covers the nuances of device densities. • CSS Support – in this tutorial Steve talks about the CSS support he built for Codename One. There is also a followup article on new CSS capabilities. • Dynamic Autocomplete – in this tutorial we discuss the usage of an auto-complete text field and how we can use a webservice to provide suggestions to users. • Local notifications on iOS \u0026amp; Android – covered the support for firing local notifications when the app is in the background. • Deploy the same app multiple times – in this short tutorial we cover the process of making an app template that you can redeploy e.g. to sell similar apps to multiple customers or build a demo/release version. • Building Cloud-powered Native Mobile Apps with Parse.com – while parse was discontinued, parse4cn1 is still going strong with 3rd party parse alternatives. • Shrinking sizes \u0026amp; optimizing – how to reduce your application size. • Automating releases – this post covers the enterprise grade continuous integration support. • JQuery style selectors – use selectors to manipulate specific components. • Setup a Codename One Project from Git – covers the process of converting a git project to a local project. There are many other tutorials, too many to list, you can see some of them in the How Do I? and that is still a partial list as it doesn’t cover the older posts from before the site migration.\nVideos \u0026amp; Online Courses Notice that a while back, we shifted most of our effort to the Codename One Academy. Some of the older videos below might be out of date.\n• Codename One Academy – contains both free and premium courses covering almost everything there is to know in Codename One and the tools to build full featured apps. • Hello world video tutorial – video covering the steps of building/running a Codename One app. • Todo Video Tutorial – Covers Codename One basics by walking you through the basics of building a simple Todo app. • What is Codename One – a thorough walkthrough of Codename One underpinnings, it’s history and how it differs from other approaches to cross platform. • Learn mobile programming by example – this course walks you thru the source code of the Property Cross \u0026amp; Dr. Sbaitso demos. • Build mobile iOS apps in Java – walks thru the creation of a client/server image sharing app. It covers the creation of a webservice connection to a Java webserver, file upload, camera and many other details. • How Do I – this is a large collection of short videos covering everything from layouts to webservices etc. Some aren’t as fresh as the others but the list is pretty comprehensive. • How to use the Codename One Sources – as the name suggests, this tutorial gets you started with running a Codename One app compiled against the Codename One sources from git. • PSD to APP – the original tutorial from Steve took the form of a video webcast. We later updated it in text form but things such as photoshop might be easier to understand in a video. • Cordova/PhoneGap compatibility – this isn’t just a video but it covers a lot of the ideas behind the Cordova support we added to Codename One a while back. • Debug a Codename One app on an Android Device – this is technically a How Do I? video but it’s a really good one so it’s listed here. • Codename One Webinar – Steve did a couple of Codename One webinars, the second one is here. Those were both very interesting and covered multiple different topics. • Dr. Sbaitso \u0026amp; Property Cross – this is effectively the same content as the \u0026ldquo;by example\u0026rdquo; course above but on YouTube. • LTS Talk – a talk I gave to LTS over cross mobile device programming. • JavaZone 2013 talk – a lecture covering the basic principals of Codename One. • Lecture from Mateja Opacic – Mateja gave a lecture at the Coding Serbia Conference and discussed Codename One. More? We hope to produce more content as we move forward both to replace older/outdated content and to provide more \u0026ldquo;ready made\u0026rdquo; starting points.\nOur property cross and chat tutorials were very successful mostly because they represent real world types of applications developers want unlike the kitchen sink which is abstract.\nThese tutorials require a lot of time \u0026amp; effort so we don’t get to do as many as we might want.\nIf you have thoughts or wishlists for tutorials, we’d be happy to hear about them. Also if you have your own tutorial somewhere, feel free to post a link in the comments, as long as it’s relevant we’ll approve it thru moderation and maybe add it to the post. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nUrfi Mirza — November 3, 2016 at 9:25 am (permalink) Urfi Mirza says:\nHI….How can I create a Mobile app using NetBeans 8 Codeone project for Mobile phone deleted file recovery program? or is there any API that I can incude in my project and complete the project…..Thanks\nShai Almog — November 4, 2016 at 5:51 am (permalink) Shai Almog says:\nHi,\nmobile phones block low level filesystem access so an app like that will be impractical natively without rooting the device which is problematic even on Android.\nDaniel Charlie — April 21, 2017 at 10:08 am (permalink) Daniel Charlie says:\nInteresting topics. nice information helped me a lot. if it possible share some more………..\nJuan Carlos Vásquez — October 24, 2019 at 6:26 pm (permalink) Juan Carlos Vásquez says:\nHello, can you post a tutorial on how to login to a backend server via MySQL-PHP-JSON? Thank you!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/build-apps-with-java-for-ios-android-tutorials-resources/","summary":"\u003cp\u003eThere are many Codename One resources for building native mobile apps but they are often all over the place, in this blog post I’ll try to concentrate the best resources for people who already know Java and are looking to pick up Codename One. If you don’t know Java yet, please check out \u003ca href=\"/blog/codapps-io-is-back-java-on-mobile-from-scratch.html\"\u003ethis post\u003c/a\u003e where we discuss resources for beginners to learn Java.\u003c/p\u003e\n\u003ch3 id=\"written-docs-and-tutorials\"\u003eWritten Docs and Tutorials\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://uber.cn1.co/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e• Create an Uber Clone in 7 Days\u003c/a\u003e – Even if you don’t purchase the full book, the free chapters available to download will help you get started quickly.\u003c/p\u003e","title":"Tutorials \u0026 Resources – Build Apps with Java for iOS, Android etc"},{"content":"\nA few years back I wrote an article for O`Reilly\ncovering the advantages of cross platform over native OS code. Almost 3 years have passed and a lot has changed\nin our industry so I wanted to re-examine how this impacts my perspective on cross platform vs. native.\nI can sum up the sentiment in a single sentence: \u0026ldquo;Cross platform is both more essential \u0026amp; more practical than ever before!\u0026rdquo;.\nFlat Design Simplified Portability Both iOS and Android applications are far more similar. Google releases material design applications for iOS without\nmajor backlash as they don’t look out of place. Yes there are still platform sensibilities to take into account but\nthey are far fewer than they were three years ago.\nFlat design removed the clutter from applications making the functionality \u0026amp; clean design front and center. This\nis wonderful for WORA tools. The focus on functionality allows WORA tools to reuse code and gain on native\ndevelopers.\nNative Backlash Users would often complain about sub-par performance of WORA tools. This has been mitigated on two fronts.\nThe tools themselves have improved by leaps and bounds, Codename One is far better than it was in 2013 and\nother tools in the field have also improved tremendously.\nBut the bigger change is in user sentiment, for every user who complains about \u0026ldquo;nativeness\u0026rdquo; you have another\nuser complaining vigorously about their platform not getting the same treatment. E.g. dropbox who has pretty good\nnative iOS/Android apps recently released an iOS app update that included a great feature: \u0026ldquo;Scan to PDF\u0026rdquo;.\nThis feature would be very useful for me on Android but a quick search revealed that it isn’t available yet and that\nthe community is pretty mad about this.\nThis is about an Android port from a unicorn company that doesn’t lack for resources!\nSome people will always complain about an app that doesn’t look good or isn’t responsive but a lot of users\nwho don’t understand the technical details associate the word native with \u0026ldquo;fast, good looking \u0026amp; responsive\u0026rdquo;\nwhich you can achieve without recoding the app 2-4 times…​\nRise of Windows 10 Windows Phone is dead but Windows 10 is rising. In fact Microsofts surface is\nleading in the detachable keyboard tablet space.\nThis specific segment is hugely important in the corporate world where access to legacy Windows software\nis crucial.\nThis means we now need to deal with 3 prominent platforms and stores instead of 2 (ignoring the Kindle or\nsimilar Android stores for simplicity).\nCoding your app twice might have been reasonable but doing it three times and requiring two separate machines\n(Mac and Windows) isn’t as practical.\nStability/Stagnation in Mobile OS’s Mobile changed very quickly in the past but over the past few years it didn’t innovate as much. Google \u0026amp; Apple\nspent resources on watches, cars \u0026amp; glasses all of which didn’t take off. Mobile phone apps refined but didn’t change\nin a fundamental way, this is good as a stable platform is much easier to track for cross platform developers.\nAs I mentioned above platforms converged a lot. This is obvious in the UI level where iOS, Android \u0026amp; Windows look\nmore alike every day. But it’s also important in the underlying behavior.\nAndroid was remarkably flexible when it launched allowing background services to do just about anything. iOS was\nfar more restrictive, disallowing multitasking altogether in its initial launch.\nBoth yielded to a common middle ground. Android placed restrictions on background processes to prevent wasted\nbattery with project doze. iOS added support for many use cases which are still not as flexible as activities and\nservices but provide almost all of the commonly needed use cases.\nPermissions and security also saw a similar convergence where Android shifted it’s over complicated and misunderstood\npermissions system to one that is more similar to the one iOS has.\nThese convergences make WORA (Write Once Run Anywhere) far easier as they allow developers to run get a similar\nexperience (e.g. permission prompts) across various devices.\nFinal Word Let’s be clear, if you pick a WORA solution. Any WORA solution. Some purists will notice and complain.\nIf you miss a feature or even an entire platform people will complain.\nIn the past a customer asked me \u0026ldquo;lets assume I have all the money in the world and no restrictions, should I use\nnative or Codename One?\u0026rdquo;.\nI gave the obvious answer and it stems from the Tao of programming :\nA manager went to the master programmer and showed him the requirements document for a new application. The manager asked the master: \u0026ldquo;How long will it take to design this system if I assign five programmers to it?\u0026rdquo;\n\u0026ldquo;It will take one year,\u0026rdquo; said the master promptly.\n\u0026ldquo;But we need this system immediately or even sooner! How long will it take if I assign ten programmers to it?\u0026rdquo;\nThe master programmer frowned. \u0026ldquo;In that case, it will take two years.\u0026rdquo;\n\u0026ldquo;And what if I assign a hundred programmers to it?\u0026rdquo;\nThe master programmer shrugged. \u0026ldquo;Then the design will never be completed,\u0026rdquo; he said.\n— Tao of programming – 3.14\nThe more resources we have the more time things take and the bigger the disaster (e.g. JavaFX). WORA tools\nallow us to focus our attention on the product and the user not on the politics of Apple, Google or Microsoft. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChibuike Mba — September 27, 2016 at 4:33 pm (permalink) Chibuike Mba says:\nNice points Shai, no matter the tools you use some users will still complain.\nFor me, its better to deploy on multiple platforms using WORA tools like Codename One rather than being stock in one platform with native. Though it depends on the scenario and who makes the decision.\nI enjoyed reading the Tao of Programming you referenced in this article, having read Tao Te Ching, the tonality was similar, it was fun and educating at the same time.\nHristo Vrigazov — October 3, 2016 at 5:28 am (permalink) Hristo Vrigazov says:\nThanks for awesome service and keep it up guys!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/cross-platform-mobile-still-better-than-native-in-age-of-flat-design/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/cross-platform-mobile-still-better-than-native-in-age-of-flat-design/write-once-run-anywhere-is-better.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA few years back \u003ca href=\"http://radar.oreilly.com/2013/11/wora-can-be-better-than-native.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eI wrote an article for O`Reilly\u003c/a\u003e\u003cbr\u003e\ncovering the advantages of cross platform over native OS code. Almost 3 years have passed and a lot has changed\u003cbr\u003e\nin our industry so I wanted to re-examine how this impacts my perspective on cross platform vs. native.\u003c/p\u003e\n\u003cp\u003eI can sum up the sentiment in a single sentence: \u0026ldquo;Cross platform is both more essential \u0026amp; more practical than ever before!\u0026rdquo;.\u003c/p\u003e","title":"Cross Platform Mobile still Better than Naive in age of Flat Design"},{"content":"\nWe often build one app and sell it to multiple customers. After all, most customers ask for similar things with minor\nchanges. E.g. if I build a restaurant app and then sell it to one establishment I can then resell it to another with almost\nno change at all…​\nAnother common use case is the demo or free version of a paid app, you want to reuse as much of the work as possible\nwithout maintaining two code bases.\nThis question has come up quite a few times in the forums and most recently again\non stackoverflow.\nIt’s something we need to document better so here is a brief tutorial.\nHow does the Appstore \u0026ldquo;Know\u0026rdquo;? The first thing we need to understand is how the appstore identifies your application.\nPretty much all apps use a unique identifier string that is similar to package names, which we map to the main\napplication package name.\n__ Apple doesn’t allow underscores in these names, Java doesn’t allow the minus character - so avoid both Getting Started Lets assume we created an app for acme corporation under the package com.acme.apps.supercoolapp. We\nnow want to sell a similar app to\nEvil Corp. (please no spoilers for those who didn’t see this yet…​)\nwhich we will ship as com.evil.apps.supercoolapp. To do this I need to follow these steps…​\nStep 1: Create the Acme app as usual This is pretty strait forward and I’m assuming you all know how to do that…​\nStep 2: Create the Evil Corp Package We can just create a new package in the IDE named com.evil.apps.supercoolapp and place a main class there.\nIdeally it should have the same name as the main class we have in com.acme.apps.supercoolapp, I’ll assume they\nare both named Main.\nThe cool thing as that one main can derive functionality from another e.g.:\npackage com.evil.apps.supercoolapp; public class Main extends com.acme.apps.supercoolapp.Main { @Override public void init(Object context) { super.init(context); } @Override public void start() { super.start(); } @Override public void stop() { super.stop(); } @Override public void destroy() { super.destroy(); } } Notice that I can just write additional logic in every one of these methods or even replace them entirely to provide\nunique functionality for Evil Corp.\nE.g. I can set the theme to a different theme and some common strings from the resource bundle to different values.\nStep 3: Run in the Simulator The simulator is really just a java class that gets the main class/package as an argument. You can change that\nin the project settings under the run section. NetBeans is particularly good with these things as it allows you to define\nproject configurations and you can switch dynamically between said configurations with just a right click.\nStep 4: Build Native App Just replace all the references to com.acme.apps.supercoolapp with com.evil.apps.supercoolapp in the\ncodenameone_settings.properties. You will also need to update the certificates/provisioning information depending\non the customer. Make sure to save the provisioning/certificate data of each customer separately so you don’t get\nconfused…​\nYou might also want to update the title and other properties within the file. Some developers keep multiple versions\nof the file and the application icon and just replace them dynamically with a script. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nNick Koirala — October 6, 2016 at 1:28 am (permalink) Nick Koirala says:\nCan you elaborate on how to run in the simulator? I set up a new configuration and put the package/class as the arguments in the run section and it still runs the original Main, not the new Main\nShai Almog — October 6, 2016 at 5:22 am (permalink) Shai Almog says:\nDid you select that configuration as the active one?\nIn which IDE?\nIs there output in the console?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/deploy-same-mobile-app-template-multiple-times/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/deploy-same-mobile-app-template-multiple-times/clone-app.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe often build one app and sell it to multiple customers. After all, most customers ask for similar things with minor\u003cbr\u003e\nchanges. E.g. if I build a restaurant app and then sell it to one establishment I can then resell it to another with almost\u003cbr\u003e\nno change at all…​\u003c/p\u003e\n\u003cp\u003eAnother common use case is the demo or free version of a paid app, you want to reuse as much of the work as possible\u003cbr\u003e\nwithout maintaining two code bases.\u003c/p\u003e","title":"Deploy the Same Mobile App/Template Multiple Times"},{"content":"\nWe’ve had a very challenging week with a lot of backend work for some enterprise customers so we didn’t get as\nmuch done as we do most weeks. I can say that I’ve seen some of the apps in the pipeline and I’m very excited\nabout the things to come…​\nTodays update includes many bug fixes on Android, UWP but not much in terms of new features.\nOn stack overflow things were pretty standard:\nCodenameOne set indexing of fields for virtual keyboard The order of the fields is determined by the focus and that can be manipulated using setNextFocusDown\nRead on stackoverflow…​\nLogin form is shown for a couple of second in iOS The iOS section in the developer guide explains the iOS splash screen system in-depth\nRead on stackoverflow…​\nHow to show side menu icon in particular forms only Just don’t add commands into that form that go into the side menu. That’s pretty easy to do with the Toolbar class\nRead on stackoverflow…​\nCodenameone Detect keyboard showing Detecting a keyboard isn’t good practice since the behavior differs a lot between iOS/Android etc.\nRead on stackoverflow…​\nHiding element while preserving its space in page layout setVisible hides elements like the title mentioned but in his case he was asking about setEnabled\nRead on stackoverflow…​\nCodename One class file for PrintWriter not found The webservice wizard is a bit confusing, it’s important to generate the server code to a server project\nRead on stackoverflow…​\nIs it possible to arrange commands properly on a GUI Element in iOS? If you aren’t using Toolbar yet we recommend switching to it for better control\nRead on stackoverflow…​\ntheme.res not found on Codenameone IntellijIDEA IDE This was caused because he picked the Android SDK instead of the JDK when creating the project\nRead on stackoverflow…​\nCodenameone Plugin not Loaded in Android Studio We don’t support Android Studio, Google broke a lot of things in IntelliJ to make it work for Android\nRead on stackoverflow…​\nAuto start, cross platform, background mobile web service with codename one or cordova There are limitations of mobile native OS’s at play and you hit them sooner than you hit the limitations of Codename One\nRead on stackoverflow…​\nHow to avoid that swiping a SwipeableContainer also creates an event in the top container? This includes some \u0026ldquo;black magic\u0026rdquo; to get this working…​\nRead on stackoverflow…​\nCan I use an SVG image as an button icon? We don’t really support SVG, ideally we’ll improve that but native platforms don’t support it either…​\nRead on stackoverflow…​\nRecommended way to change the size of the Toolbar in Codename One We rely heavily on the fact that Container is transparent and has 0 padding/margin\nRead on stackoverflow…​\nChange CodenameOne InfiniteContainer PullToRefresh Behaviour You can override the refresh method in that class\nRead on stackoverflow…​\nDate Time Picker on double tap display typing Feature We recommend using separate date picker \u0026amp; time picker. You should avoid the Date \u0026amp; Time picker as that is a\nfeature that is iOS specific.\nRead on stackoverflow…​\nGUI builder does not show up Eclipse has slightly slower update cycles than NetBeans/IntelliJ at this time. Normally that isn’t a problem but\nwith a fast evolving tool like the GUI builder it might be a bit of a hindrance.\nRead on stackoverflow…​\nApps Error no virtual method This was a result of using a pre-release version of the API as we made minor adjustments to the method signatures\nRead on stackoverflow…​\nTicker mode You can enable tickering for any component that derives label which includes buttons etc.\nRead on stackoverflow…​\nSize of URLImage as a Label icon URLImage resizes and caches the data based on placeholder size and settings\nRead on stackoverflow…​\nconnection and Toastbar not displaying issue ToastBar is bound to a form so if you are on a different form this might be a problem\nRead on stackoverflow…​\ndownloadUrlToStorageInBackground in ImageList model for imageViewer downloads \u0026amp; overrides the image every time The download method always downloads and doesn’t check if the file is already there…​\nRead on stackoverflow…​\nTrouble changing background color of TextField in Codename One The requirement to define the border as empty breeds a lot of confusion\nRead on stackoverflow…​\nManaging Demo / Full version of my app in Codename One This is a common case that I was pretty sure we had documented somewhere, it should probably be in the developer\nguide somewhere\nRead on stackoverflow…​\nUWP SQLite CodenameOne with native interface This was actually a pretty interesting question as it made me think on the potential approaches for a relatively complex\nmissing feature\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xxiv/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xxiv/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve had a very challenging week with a lot of backend work for some enterprise customers so we didn’t get as\u003cbr\u003e\nmuch done as we do most weeks. I can say that I’ve seen some of the apps in the pipeline and I’m very excited\u003cbr\u003e\nabout the things to come…​\u003c/p\u003e\n\u003cp\u003eTodays update includes many bug fixes on Android, UWP but not much in terms of new features.\u003c/p\u003e\n\u003cp\u003eOn stack overflow things were pretty standard:\u003c/p\u003e","title":"Questions of the Week XXIV"},{"content":"\nWe’ve discussed codapps.io before, it’s a MOOC (online course) that allows you to learn Java\nprogramming and uses mobile/Codename One as its vehicle. Our current documentation and tutorials can be quite\nintimidating to a person who is a complete Java newbie so this course is quite helpful in bridging that gap.\nI think learning GUI programming is probably the best way to learn programming as it lets you \u0026ldquo;see\u0026rdquo; the results\ninstantly and experiment.\nThe codapps.io MOOC focuses on typical apps created with the GUI builder and tries to smooth\nthe entry into the lower level Java coding.\nAnother interesting tutorial for complete beginners is from Loke Hansen and we discussed it\nhere. Hansen created a series of tutorials\ncovering the process of building a game from scratch without any experience in Java. He explains a lot of\ncomplex details very clearly and because this is a game the course is both entertaining and goal oriented!\nOther Resources We have a lot of documentation, but picking up a 900 page developer guide might be intimidating\nwhen you are completely new to Java.\nHere are some helpful resources to get you started:\nComponent Gallery – shows\nthe common components that are a part of Codename One in a visual index\nLayout gallery –\nlayouts are one of the hardest concepts to grasp in Codename One, this visual gallery covers the basic Codename One\nlayout managers\nJavaDoc – the JavaDoc is a standard \u0026ldquo;reference guide\u0026rdquo; to the Codename One\nAPI and what’s available in it you can search any method/class by clicking one of the index files\nDeveloper guide\nDemos – the Codename One demos e.g. the Kitchen Sink are a\ngreat place to start. You can create most demos by just going thru the wizard process by selecting\nNew Project → Codename One → Demos →#Name of demo#\nHelp Stack overflow is the best place to ask for help but it can sometimes be intimidating as you need to ask in the \u0026ldquo;right way\u0026rdquo;\n\u0026amp; that can be difficult when you don’t know anything. Try asking on the discussion forum\nnotice that sometimes things get flagged as SPAM by the automatic Google filters. To avoid that you should probably\njoin the group before posting and use a verified gmail account.\nI learned Java by reverse engineering the first public beta and a lot of experimentation 20 years ago. Things that\nare obvious to me might be baffling to people making their first steps into programming…​\nWhen you ask a question keep in mind that sometimes we might be detached from your current experience level\nand guide us toward the type of answer you need.\nKeep in mind that engineering, math and all such disciplines eventually boil down to patience. Putting in the hours,\neffort and asking for help when necessary will eventually pay off.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codapps-io-is-back-java-on-mobile-from-scratch/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codapps-io-is-back-java-on-mobile-from-scratch/codapps.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve discussed \u003ca href=\"http://codapps.io/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ecodapps.io\u003c/a\u003e before, it’s a MOOC (online course) that allows you to learn Java\u003cbr\u003e\nprogramming and uses mobile/Codename One as its vehicle. Our current documentation and tutorials can be quite\u003cbr\u003e\nintimidating to a person who is a complete Java newbie so this course is quite helpful in bridging that gap.\u003c/p\u003e\n\u003cp\u003eI think learning GUI programming is probably the best way to learn programming as it lets you \u0026ldquo;see\u0026rdquo; the results\u003cbr\u003e\ninstantly and experiment.\u003c/p\u003e","title":"Codapps.io is back Java on Mobile from Scratch"},{"content":"\nI love going to JavaOne, I used to do it every year and it’s loads of fun. I’ve been speaking on a regular basis at\nJavaOne since 2008 and got a rockstar award a while back. Two years ago we purchased a booth to promote\nCodename One as well.\nLast year we skipped the show and it has been so great we decided to skip it again.\nWhile JavaOne is loads of fun it does nothing to the bottom line even if you have a booth in place. We had many\nmeetings, talks \u0026amp; introductions. These resulted in very little in terms of revenue or traction shift.\nThe reason for this is pretty core to what Codename One is, to adopt Codename One you need to make an effort.\nYou need to write code or make some form of commitment. People coming to conferences want to learn about new\ntechnologies but aren’t necessarily willing to go to extremes for a new technology…​\nFurthermore, the demographic of JavaOne is heavily biased to JavaEE by a big margin. That meant that 90% of\nthe people I spoke to would be completely irrelevant as mobile is not within their responsibility.\nThere are exceptions and we met a lot of great developers at JavaOne, but going to that expense to reach those\ndevelopers seems redundant. Over the Internet we reach people when they are ready to make that commitment\nnot at an arbitrary point in time.\nConferences probably work for smaller solutions that require a lesser commitment than Codename One does. They\nmight be more relevant when we grow further but right now they place a heavy strain on our limited resources.\nWill we go Back? Currently we have no short term conference plans, we found that promoting over the Internet is far superior in\nterms of return.\nFrom talks with a lot of Java developers I’ve met over the years it seems that JavaOne isn’t as important as it used\nto be either. Most developers seem to prefer the smaller substance driven conferences which we might choose\nto attend as we grow.\nI think the biggest hindrance to JavaOne is the lack of Android content, without that there are no mobile developers\nin attendance and this makes our attendance pointless. Other conferences didn’t make that mistake and are far more\nrelevant to us as a result.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/why-we-no-longer-attend-javaone/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/why-we-no-longer-attend-javaone/generic-java-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI love going to JavaOne, I used to do it every year and it’s loads of fun. I’ve been speaking on a regular basis at\u003cbr\u003e\nJavaOne since 2008 and got a rockstar award a while back. Two years ago we purchased a booth to promote\u003cbr\u003e\nCodename One as well.\u003cbr\u003e\nLast year we skipped the show and it has been so great we decided to skip it again.\u003c/p\u003e\n\u003cp\u003eWhile JavaOne is loads of fun it does nothing to the bottom line even if you have a booth in place. We had many\u003cbr\u003e\nmeetings, talks \u0026amp; introductions. These resulted in very little in terms of revenue or traction shift.\u003c/p\u003e","title":"Why we no longer Attend JavaOne"},{"content":"\nHistorical note: Codename One\u0026rsquo;s UWP target was discontinued in release 7.0.229. This post is preserved for historical context only, and its build/setup instructions no longer apply to current Codename One projects.\nThe latest plugin update includes a new kitchen sink version that includes quite a few bug fixes, enhancements\nand a new side menu design that looks much better. We also got the demo published on the Windows Store\nthru the UWP port which isn’t so much a testament to the maturity of the port as much as it is to the limited\ntesting done by Microsoft.\nThe demo on UWP is still broken in some fundamental ways e.g. shape graphics required for the clock are still\nnot ready. Quite a few other things should be implemented but it should still install \u0026amp; run. You can install this\ndemo on a Windows 10 device or desktop from here.\nWe made a lot of fixed for the UWP port over the past few days so if you were having issues they might have been\nresolved by now. There are still some pieces of functionality missing which we hope to get to during the 3.6\nline but realistically a production release of UWP that is \u0026ldquo;feature complete\u0026rdquo; might wait to 3.7.\nNotice that the version of the kitchen sink that is currently in the store (2.01) predates some of the latest fixes,\nwe’ve submitted updates to the versions in all the stores but naturally the update process takes time for approval\non iOS/Windows. Version 2.02 should contain most of the fixes for the kitchen sink and the current batch of UWP\nfixes, since that platform is evolving faster we might need to update it further.\nCommenting the Demo Bryan posted a comment on\na previous post \u0026amp; I think this bares repeating in a post:\nRe Kitchen Sink – I’ve been looking at the source to see how some of the stuff in the demo is done, and it would\nbe really good if there were more comments or description in the code (or accompanying the demo) so\ndevelopers could copy some of the techniques used. There’s a bunch of stuff obviously possible with CN1,\nbut much of it is hidden away and not always obvious that what’s possible.\nThat’s great feedback, you can do this to help us find these cases that are unclear:\nGo to the sources that aren’t clear, press the edit icon on the top right and just insert your comments or even\n\u0026ldquo;can you explain this?\u0026rdquo; comments.\nOnce you are done with the change just click the pull request button.\nWe will merge the pull request and then fix the \u0026ldquo;explain this\u0026rdquo; comments. You don’t even need to check out the project.\nThis doesn’t just apply to the kitchen sink!\nYou can do this to any demo or even Codename One itself, if code isn’t clear or a comment isn’t clear just let us\nknow directly in the code. This way the entire community can benefit from this.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/kitchensink-uwp/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/kitchensink-uwp/kitchensink-sidemenu.png\"\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003eHistorical note:\u003c/strong\u003e Codename One\u0026rsquo;s UWP target was discontinued in release \u003cstrong\u003e7.0.229\u003c/strong\u003e. This post is preserved for historical context only, and its build/setup instructions no longer apply to current Codename One projects.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eThe latest plugin update includes a new kitchen sink version that includes quite a few bug fixes, enhancements\u003cbr\u003e\nand a new side menu design that looks much better. We also got the demo published on the Windows Store\u003cbr\u003e\nthru the UWP port which isn’t so much a testament to the maturity of the port as much as it is to the limited\u003cbr\u003e\ntesting done by Microsoft.\u003c/p\u003e","title":"KitchenSink UWP"},{"content":"\nLast week we merged the new Android peer code into the main branch. That means that we can no longer support\nthe android.newPeer flag as all non-versioned requests will use the new peers. This is a good thing as it will allow\nus to focus on one implementation moving forward.\nWe would like to bring the new peer implementations to other platforms but so far this has proven itself somewhat\nchallenging especially with our resource constraints. Ideally we wanted to have this for 3.6 but it’s possible that it\nwill get pushed back all the way to 3.7.\nVacations We don’t announce staff vacations normally but October will be busy with very few actual office days. If you have\nprojects that are pending release or tasks that might be impacted we suggest arranging your schedule around\nOctober.\nI would still be available for support and help but I will be in India for the entire month of October. This might impact\nmy typical responsiveness and availability.\nOther engineers would be available for some parts of the month but might be forced to deal with urgent issues\nbased on priority. This means that some things might be left for November when we should all get ready for the 3.6\nrelease which would then be imminent.\nI will be in Mysore during my trip. If any Codename One developers are in that area and want to share some Chai \u0026amp;\na chat I’d be happy to meet. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbeck — September 19, 2016 at 3:00 pm (permalink) beck says:\ncome to Nepal too if possible… We will have good time….\nChidiebere Okwudire — September 19, 2016 at 3:01 pm (permalink) Chidiebere Okwudire says:\nWhen are you coming to The Netherlands? 😉 Enjoy your vacation!\nShai Almog — September 20, 2016 at 5:21 am (permalink) Shai Almog says:\nThanks for the invite.\nThis trip is mostly for my spouses studies, I don’t like traveling much although I do enjoy the far east.\nShai Almog — September 20, 2016 at 5:23 am (permalink) Shai Almog says:\nI don’t have any immediate travel plans but we do have some family in Amsterdam so it might happen. We’re just so busy and they usually prefer coming here to get out of the gray weather and roast themselves in the sun…\nbeck — September 29, 2016 at 4:24 am (permalink) beck says:\nMy pleasure. Enjoy your vacation in India. If by any chance,you change your mind, here is for the weekend. Its very very near frm India. https://www.youtube.com/wat…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/merged-peer-october-vacations-india-trip/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/merged-peer-october-vacations-india-trip/vacation.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eLast week we merged the new Android peer code into the main branch. That means that we can no longer support\u003cbr\u003e\nthe \u003ccode\u003eandroid.newPeer\u003c/code\u003e flag as all non-versioned requests will use the new peers. This is a good thing as it will allow\u003cbr\u003e\nus to focus on one implementation moving forward.\u003c/p\u003e\n\u003cp\u003eWe would like to bring the new peer implementations to other platforms but so far this has proven itself somewhat\u003cbr\u003e\nchallenging especially with our resource constraints. Ideally we wanted to have this for 3.6 but it’s possible that it\u003cbr\u003e\nwill get pushed back all the way to 3.7.\u003c/p\u003e","title":"Merged Peer, October Vacations \u0026 India Trip"},{"content":"\nThis has been a busy week with new features and some interesting announcements. We are releasing a plugin\nupdate today with a lot of fixes especially to the GUI builder which should be far more stable.\nNetBeans announced they will be moving to Apache and we volunteered to help.\nWe’ll post some thoughts about this next week.\nJava One is coming back, again we chose not to go. I wanted to write a bit about it but didn’t find the time to\nput down my thoughts. Overall I love Java One, it’s loads of fun…​\nBut flying there from another continent is probably not the best use of our time/budget.\nOn stackoverflow things were as usual:\nUWP SQLite CodenameOne with native interface We do need to support a more consistent cross platform database. SQLite is pretty inconsistent between platforms\nRead on stackoverflow…​\nHow do I access UI components in a .res file with Codename One? This is so much easier in the new GUI builder, hopefully this weeks update will tip the scales for most developers\nRead on stackoverflow…​\nList adding functionality Lists are always a pain which is why we recommend avoiding them\nRead on stackoverflow…​\nHow to compress project size in codenameone This should actually be on by default for most scripts\nRead on stackoverflow…​\nWrong paths in Codename One preferences Unfortunately we were unable to reproduce the exact issue, hopefully it was resolved. If not we could use a\ngood way to reproduce it consistently\nRead on stackoverflow…​\nUWP deployment failed with CodenameOne We had some UWP deployment issues that should be fixed in todays update\nRead on stackoverflow…​\niOS certification generation with Codename One The certificate generation process is by definition \u0026ldquo;flaky\u0026rdquo; as we rely on undocumented behavior. That’s why we\nhide it behind a webservice so we can patch it without asking everyone to update their install\nRead on stackoverflow…​\nHow to make enable https in codenameone I’m really grateful when people answer these questions, it’s always hard to answer the obvious questions\nRead on stackoverflow…​\nIssues with Mirah I haven’t played with the Mirah integration that Steve built a while back, if you like languages like Ruby this\nmight be interesting to you\nRead on stackoverflow…​\nAdd Checkbox to CodenameOne TableModel in Table component MVC is always challenging even when it’s a simplified version like the one in Table\nRead on stackoverflow…​\nClickable Component We should probably block users from setting a lead component to another lead component\nRead on stackoverflow…​\nIs Self Signed Certificate work for IOS? When first reading this I thought it was about signing but it seems to be a question about https server setup\nRead on stackoverflow…​\nLayered Layout not fill the screen This question is probably not as important with the new support for the floating button\nRead on stackoverflow…​\nHow to use Google Speech API from Codename One? There are some hidden features in Codename One such as the ability to record audio without user interaction to\na specific format type. This was one of those features that we added for an enterprise developer a while back\nand never really promoted\nRead on stackoverflow…​\nHow to use drawImage instead of scaled for performance Some of the performance tips are specific for usage\nRead on stackoverflow…​\nPost request don’t send argument These issues are much easier to debug when you look at the output on the server and describe the request that\nworked for you as a dump. Otherwise we are just guessing…​\nRead on stackoverflow…​\nHow do I use the codename one migration tool on my Android Studio project? People asked us a lot about building a tool like this, when we finally put the effort in and built it we expected\nmore interest around it. This demonstrates perfectly why you can’t take feature requests from non-users seriously…​\nRead on stackoverflow…​\nError on Build: \u0026ldquo;error: cannot find symbol method compare(int, int)\u0026rdquo; This is one of those \u0026ldquo;Codename One doesn’t support Java feature X\u0026rdquo; which prompted us to write\nthis.\nRead on stackoverflow…​\nCalling custom JavaScript function The javascript package\ncontains pretty extensive documentation on this\nRead on stackoverflow…​\nMediaPlayer doesn’t release video on form change We should make media playback more intuitive than it is right now\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xxiii/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xxiii/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis has been a busy week with new features and some interesting announcements. We are releasing a plugin\u003cbr\u003e\nupdate today with a lot of fixes especially to the GUI builder which should be far more stable.\u003c/p\u003e\n\u003cp\u003eNetBeans announced they will be moving to Apache and \u003ca href=\"https://wiki.apache.org/incubator/NetBeansProposal\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ewe volunteered to help\u003c/a\u003e.\u003cbr\u003e\nWe’ll post some thoughts about this next week.\u003c/p\u003e\n\u003cp\u003eJava One is coming back, again we chose not to go. I wanted to write a bit about it but didn’t find the time to\u003cbr\u003e\nput down my thoughts. Overall I love Java One, it’s loads of fun…​\u003cbr\u003e\nBut flying there from another continent is probably not the best use of our time/budget.\u003c/p\u003e","title":"Questions of the Week XXIII"},{"content":"\nThis is something we run into every week. A new Codename One user writes asks why \u0026ldquo;feature X\u0026rdquo; from Java isn’t\nsupported. In this post we’d like to explain the \u0026ldquo;bigger picture\u0026rdquo; or why less is more…​\nSupporting the full Java API in Codename One would be a mistake that will lead us down a problematic path.\nIt would cost you a great deal in functionality, performance, portability, stability and more!\n__ We are still adding features to the VM but we trickle them in rather than supporting \u0026ldquo;everything\u0026rdquo; Why we Don’t Support \u0026ldquo;Everything\u0026rdquo;? For the lazy here is the \u0026ldquo;cliff notes\u0026rdquo; version:\nSupporting everything will increase the size of the distribution, eliminate true portability, reduce performance \u0026amp;\nironically make Java compliance harder!\nSize/Performance This is pretty easy to prove, the JDK’s rt.jar is 63mb and even supporting an incomplete version of it closer to\nwhat Android supports would result in a binary that is 10x-20x larger than ours for a simple hello world.\nThis is pretty easy to calculate, ARM code is at least 4x larger than bytecode. iOS apps need at least 2 ARM\nplatforms which means at least 8x without the bitcode portion. A good compiler can strip out unused bytecode\nwhich is why an implementation will be 10x-20x larger (rather than 60x larger) but there are limits.\nIn fact we did look at some experimental attempts to provide a larger portion of the JVM. Those attempts delivered\n50MB binaries for things we delivered in 3MB.\nPerformance is a complicated subject in mobile CPU’s but size is a big factor in such devices. Furthermore, mobile\nOS’s place restrictions on larger applications (no OTA updates etc.). If we are paying in size/performance, what we\nare getting in return should be worth it!\nNo Benefit in Supporting the Full JVM The assumptions for many developers is that if we support the full JVM they can just \u0026ldquo;take code\u0026rdquo; and it will work…​\nThis is a problematic and incorrect assumption for most cases.\nCode that relies on java.io will need work so it can fit into device filesystem restrictions.\nUI needs to be adapted to mobile and most Java UI framework code can’t be.\nSQL/Database code can’t be used since connecting from a device to a remote database is \u0026ldquo;impractical\u0026rdquo;.\nBytecode manipulation won’t work since compiled code no longer has the bytecode. Reflection would be problematic\nas it will increase the distribution size even more and be ridiculously slow on mobile without a JIT.\nFurthermore, on platforms such as Android we obfuscate the code to make it faster/smaller and harder to crack.\nObfuscation is recommended by Google and an important performance tool reducing size significantly. However,\nit collides with some features in Java such as reflection and dynamic class loading.\nDynamic class loading is also redundant as all classes must be packaged in advance and known during compile.\nUsing tools such as Class.forName() creates redundant indirection that problems with obfuscation/optimization,\nthese can be replaced with class literals e.g. MyClass.class. Class literals don’t suffer from these problems and provide\nsimilar flexibility in devices.\nJava EE/Android Code There are two HUGE markets of Java developers: Java EE \u0026amp; Android developers.\nAll other markets (Swing/FX/JavaME/Embedded etc.) are small and shrinking.\nJava EE developers can’t reuse code \u0026ldquo;as is\u0026rdquo; anyway so the point of compatibility is mute, you would need to do\na lot of work to move code from Java EE so doing a bit more shouldn’t be a deal breaker.\nReusing Android code to some extent is an attractive proposition, however the real value we can provide is in reusing\nAndroid UI elements. We get a lot of developer requests to do this but when we started an effort to bring this to\ndevelopers there was no tangible activity around this. If you would like to see more Android compatibility so you\ncan port apps more easily check out this blog post.\nTestability A large product is harder to test. Testing on devices is harder still!\nI’ve worked for years at Sun, we had a great QA team and test suites (none of which are accessible to open source\nprojects). Some developers think picking the Android or Oracle code bases means that those code bases are\nstable on devices such as iOS. The fact is that this couldn’t be further from the truth!\nE.g. iOS has some limitations on networking that are unintuitive. Code would seem to work on device and\nsimulator but would fail to work in some conditions in the field…​\nCodename One avoids this fate by brining in code in small pieces in a way designed for portability.\nPortability To increase portability we need a small well defined porting layer. The more features we add the harder it is to port.\nThe VM layer is the hardest one to add features to as it’s not portable by definition. Each platform has its own\nVM and thus we need to add changes to every single platform. This is error prone and can produce inconsistencies.\nE.g. we picked up SimpleDateFormat based on code contribution from a developer. It’s natively implemented on\nAndroid so this created inconsistency between our iOS implementation of java.text.SimpleDateFormat and the\nAndroid version.\nThe solution was to place our version in the com.codename1.l10n package and thus provide a portable/consistent\nversion.\nConsistency proved itself superior to functionality in this case, placing functionality in the com.codename1 package\nspace meant we could reuse/enhance and improve on the original implementation.\nCompliance Someone who didn’t go thru a Java compliance process would assume implementing the full VM would make compliance\neasier. This isn’t the case.\nJava compliance is comprised of tiers from lower spec VM’s for embedded/mobile upwards. The full JDK compliance\nprocess is hard, extensive and might not be available for mobile devices…​\nWe would want to reach compliance with a Java standard and the sensible goal is to aim low. At a VM level that\nis in the JavaME 8 camp and not at the full Java SE specification.\nThat would mean far fewer tests to pass and since every test suite needs to run on all supported platforms this\nmatters a lot.\nIn Detail Above I listed some of the high level problems related to supporting the full JVM but lets go into some more details.\nReflection/IoC As mentioned above mobile code is usually obfuscated and statically linked.\nBoth of these technologies are designed for decoupling implementation from other logic (e.g. UI, tests etc.). Since\nall the code is packaged this isn’t really useful at runtime.\nFor some cases it might be practical to offer a bytecode manipulation solution during compilation that will allow\nsome injection functionality. We are gathering feedback on such requirements for a potential future feature.\nArbitrary JARs The ability to include an arbitrary JAR into the project is a common request. That’s problematic as we can’t\ncheck such JARs and see that they don’t use features that we don’t support. They might work in the simulator and even\nAndroid but then fail on iOS or JavaScript…​\nIn theory we could run such tests but in most cases they would fail as most real world JARs use files, networking,\n\u0026amp; countless other features.\nMaven/Gradle A few developers complained about the use of the antiquated Ant build system in favor of Maven/Gradle.\nWe’ve made several attempts at moving to both and eventually abandoned those attempts as both tools aren’t\nnearly as good as ant.\nBoth Gradle and Maven are MUCH slower than Ant\nTheir key feature is dependency management which wouldn’t be helpful due to the arbitrary JAR limits\nThey don’t support cn1libs\nGoogle’s Android team chose to go with a Gradle build process. This resulted in a painfully slow build process for\nAndroid development that provides very limited benefits.\njava.net API’s The java.net API’s are very elaborate and layered. All the networking code is implemented on top of sockets which\nare modeled according to typical POSIX sockets. The problem is that most mobile platforms don’t have \u0026ldquo;proper\u0026rdquo; POSIX\nsockets and when they do they might have some issues associated with them (e.g. iOS).\nIt’s impossible to implement java.net in a compliant way while still working correctly on devices!\nIn the future we might introduce a higher level abstractions that implements some common use cases of java.net\nbut aren’t compliant. This would just mean changing the package name for 99% of the code to get it to work.\nIt’s the 1% of unique functionality that is problematic.\njava.io.File Mobile devices don’t have filesystems in the same way that desktops do. There are areas to you are restricted to\nand apps are typically \u0026ldquo;isolated\u0026rdquo; from one another. We might provide a compatibility migration API similar to the one\nwe might include for java.net code.\nNIO There are several pieces of NIO but the most applicable piece is probably buffers which allow direct memory/filesystem access.\nWe don’t really need NIO since we don’t keep secure access to the native code, there is no need since we already\nare in native code on iOS.\nHaving said that it might still be useful to add these to native interfaces especially when running on Android or\nother JVM platforms. We don’t have any short/long term plans for doing this as of this writing but it’s possible.\nThe main use case for NIO is IO performance, our current recommended strategy is to use native code for such cases\nwhich alleviates the need for NIO.\nString.split() This is a tough one. I love String.split() and would love to have it as part of the \u0026ldquo;official\u0026rdquo; API. But it has two major\nproblems that are currently holding it back: It’s in String \u0026amp; it’s complex.\nString is a core class which means we can’t strip it from the JVM when compiling an iOS app. If we include split()\nthe cost of that additional method (and it’s complex regex parsing engine) will apply to all apps whether they use\nit or not.\nThat seems like a fair price but the problem is far worse…​\nSince the implementation for iOS will be developed by us and not by Oracle/Google it will likely differ in subtle ways.\nSimple things like split(\u0026quot;;\u0026quot;) will probably work the same but complex calls might fail on iOS and succeed elsewhere.\nThe worst bugs are the ones that happen on device and don’t happen on the simulator, they are hard to track and\npainful. Any minute saved by using String.split() instead of our regex package or StringUtils class could be wiped\nby weeks of tracking a device specific bug. By keeping the API small we can assure that it is more consistent\nacross the various devices we support.\nFinal Word We try to add things to the VM’s when possible, it’s non-trivial because we have to do this for every one of the VM’s.\nWhen we implement things in the VM level caution and a conservative stance are key. These promote portability\nand code reuse. That means we only need to do a task once instead of 4x.\nHaving said that we are always looking at the places where we can improve and help migrate code. The date/timezone\nclasses need work, Number etc. are all things we’d love to add/improve in the VM’s given the resources.\nWe’d also like to add a standardized alternative to common reflection use cases based on static bytecode manipulation.\nIf you have feedback on these things and how we can improve the supported API we’d love to hear it. Feel free to\npost questions/thoughts in the comments. We’d also love RFE’s with things that you are missing in Codename One\nbut we want you to justify that enhancement. Specifically don’t ask for something because you want it but rather\nexplain the problem that can’t be solved or is awkward to solve without this. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nSanny Sanoff — September 17, 2016 at 8:48 am (permalink) Sanny Sanoff says:\nhow we can improve the supported API we’d love to hear it\nPlease have the suggestions in http://pastebin.com/cYcKaedD\n(apart from gc-related stuff which I just saw)\nShai Almog — September 18, 2016 at 4:03 am (permalink) Shai Almog says:\nYou’ve submitted pull requests in the past so why not submit pull requests here?\nIt’s a bit hard to read and some things seem redundant e.g. Integer.SIZE?\nNotice that for all of these changes to take effect you need to change them in CLDC so they map to the compile classpath too. Then you need to add them to the other ports where applicable.\nPrintStackTrace won’t work with that implementation as far as I can tell…\nThe timezone fix is interesting, did you test it? We have a couple of timezone related issues we need to address.\nBENSALEH ZainElabidine — May 2, 2018 at 1:00 pm (permalink) BENSALEH ZainElabidine says:\nHi, i have a java API that encrypte passwords from desktop application.With this api, i can use a database that was generated by FOSUser bundle which he use Sha512 encrypt…\nI hardly make the api in the desktop application, now in my Mobile app , i need to use the API , so i need to make the equivalente of that api in my codenameone app.\nand i need the equivalente of those class in codenameone if there is:\ni searched for the Base64 and i com.codename1.util.Base64 but i need those one too:\nimport java.security.MessageDigest;\nimport java.security.SecureRandom;\nthis is my api in github https://github.com/zain17/F…\nAnd thank you very much for your help 🙂\nShai Almog — May 3, 2018 at 6:02 am (permalink) Shai Almog says:\nThese are available in the bouncy castle cn1lib. SecureRandom is under a different package name \u0026ldquo;javabc\u0026rdquo;.\nMessageDigest is problematic as I explained here: https://stackoverflow.com/q…\nMartin Grajcar — November 11, 2018 at 3:58 pm (permalink) Martin Grajcar says:\nConcerning reflection, I have some 300 generated classes, which I need to create by name (they’re used for parsing and formatting a stupid EANCOM-like format). So I generated a huge switch like case \u0026quot;StupidName1\u0026quot;: return new StupidName1(); and a Map\u0026lt;class\u0026lt;?\u0026gt;, String\u0026gt; as a Class#getSimpleName replacement. It seems to work, at least in Android. Can I expect it to work everywhere? Should I expect problems?\nShai Almog — November 12, 2018 at 4:20 am (permalink) Shai Almog says:\nIt should work fine in iOS too. We use that trick as well for some cases.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/why-we-dont-support-the-full-java-api/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/why-we-dont-support-the-full-java-api/generic-java-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is something we run into every week. A new Codename One user writes asks why \u0026ldquo;feature X\u0026rdquo; from Java isn’t\u003cbr\u003e\nsupported. In this post we’d like to explain the \u0026ldquo;bigger picture\u0026rdquo; or why less is more…​\u003c/p\u003e\n\u003cp\u003eSupporting the full Java API in Codename One would be a mistake that will lead us down a problematic path.\u003cbr\u003e\nIt would cost you a great deal in functionality, performance, portability, stability and more!\u003c/p\u003e","title":"Why we don't Support the Full Java API"},{"content":"\nThe material design floating action button is a powerful tool for promoting an action within your application. Quite\na few Codename One developers implemented with own interpretation of this UI element and with the coming update\nwe will have an official implementation.\nThe FloatingActionButton is a round button that resides on top of the UI typically in the bottom right hand side.\nIt has a drop shadow to distinguish it from the UI underneath and it can hide two or more additional actions under\nthe surface. E.g. we can create a simple single click button such as this:\nFloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_ADD); fab.addActionListener(e -\u0026gt; ToastBar.showErrorMessage(\u0026quot;Not implemented yet...\u0026quot;)); fab.bindFabToContainer(form.getContentPane()); Which will place a + sign button that will perform the action. Alternatively we can create a nested action\nwhere a click on the button will produce a submenu for users to pick from e.g.:\nFloatingActionButton fab = FloatingActionButton.createFAB(FontImage.MATERIAL_ADD); fab.createSubFAB(FontImage.MATERIAL_PEOPLE, \u0026quot;\u0026quot;); fab.createSubFAB(FontImage.MATERIAL_IMPORT_CONTACTS, \u0026quot;\u0026quot;); fab.bindFabToContainer(form.getContentPane()); Figure 1. FloatingActionButton with submenu expanded\nThose familiar with this widget know that there are many nuances to this UI that we might implement/expose\nin the future. At the moment we chose to keep the API simple and minimal for the common use cases and refine\nit based on demand. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — September 14, 2016 at 3:10 pm (permalink) Another nice one! Does the \u0026ldquo;+\u0026rdquo; also animate to an \u0026ldquo;x\u0026rdquo; when opening the sub-menu? 🙂\nLukman Javalove Idealist Jaji — September 14, 2016 at 3:15 pm (permalink) Lukman Javalove Idealist Jaji says:\nSo many good things coming out this week…i m happy… Am I the only developer who refreshes the homepage daily to check new blog posts? I find these articles and tutorials more useful.\nBayu Sanjaya — September 14, 2016 at 7:32 pm (permalink) Bayu Sanjaya says:\nHi I got this error when trying to add fab into my container (not by form.getcontentPane()).\njava.lang.IllegalArgumentException: Component is already contained in Container: Container[x=0 y=0 width=0 height=0, layout = LayeredLayout, scrollableX = false, scrollableY = false, components = [Container, Container]]\nShai Almog — September 15, 2016 at 3:58 am (permalink) Shai Almog says:\nThat’s one of the nuances I was referring to. I have some thoughts on how to do these subtle animations but I don’t think they will work nicely with the FontImage class. I want to do it in a way that is elegant.\nShai Almog — September 15, 2016 at 4:00 am (permalink) Shai Almog says:\nI think I changed the sample code before posting and broke it, I’ll update the article later today. Notice that this will be available only on the Friday update. What you have right now is experimental.\nShai Almog — September 15, 2016 at 4:01 am (permalink) Shai Almog says:\nThanks!\nFYI we have an RSS feed so you can just subscribe to that or use RSS to email services such as ifttt\nhttps://www.codenameone.com…\nBayu Sanjaya — September 15, 2016 at 4:04 am (permalink) Bayu Sanjaya says:\nHi, I use a workaround for this one, I use a container for fab.bindFabToContainer(myContainer) and add it into main form. I think it’s stable enough to implement even it is still experimental. But I’m not really sure.\nBtw, how to change the color, i tried with UIID but the button changed into square.\nShai Almog — September 15, 2016 at 4:59 am (permalink) Shai Almog says:\nI’ve given this some thought and decided to just change the implementation so the code above \u0026ldquo;just works\u0026rdquo;. Set the background color of the UIID: FloatingActionButton\nJérémy MARQUER — September 15, 2016 at 7:17 am (permalink) Jérémy MARQUER says:\nYou’re not the only one 🙂\nAndreas Grätz — September 17, 2016 at 3:47 pm (permalink) Andreas Grätz says:\nFABs are great! But what if we have more FABs as space on the screen? The list of FABs and sub-FABs isn’t scrollable. We are working on an app, which loads the business logic from an application server. We don’t now the final count of commands.\nShai Almog — September 18, 2016 at 4:05 am (permalink) Shai Almog says:\nGoogle’s design explicitly forbids scrolling.\nThey consider these to be \u0026ldquo;speed dial\u0026rdquo; which means you pick the top 4 entries and anything beyond that should reside in a \u0026ldquo;…\u0026rdquo; more action. This is indeed more intuitive for such cases.\ndisqus — September 30, 2016 at 9:42 pm (permalink) disqus says:\nHow do I add a floating button to a Gui Builder generated form? How do I add any initialization code on Gui Builder generated forms since init method is generated code and is not supposed to be edited?\nShai Almog — October 1, 2016 at 1:30 am (permalink) Shai Almog says:\nYou can edit the constructors just fine so code that runs before the init can go before it and code that runs after can go after the init method.\nShmuDesign — March 1, 2017 at 8:11 am (permalink) ShmuDesign says:\nHi, this is good, but is it possible to remove the shadow or change the thickness ? Because I have a strange square ! (http://shmu.fr/wooz/square-… I change the color to show what append) that problem appear only on IOS !\nShai Almog — March 2, 2017 at 8:35 am (permalink) Shai Almog says:\nHi,\nyou can customize every aspect in the style including the shadow. I think the padding for the component might be too small causing the shadow to crop but if I’m wrong then it might be a clipping bug we need to fix in which case we’ll need to file an issue\nMo — June 24, 2017 at 10:40 pm (permalink) Mo says:\nHi, I have been having trouble trying to show the FloatingActionButton when switching Locale (RTL), while the LTR works as expected, below is the code am currently using to align Right, Center,\nfab.bindFabToContainer(root, Component.RIGHT, Component.CENTER); Shai Almog — June 25, 2017 at 4:45 am (permalink) Shai Almog says:\nBy convention in Codename One right becomes left in RTL mode unless you explicitly disable RTL behavior for that component. I don’t think we tested RTL on the FAB so it might be broken there. I’d expect that code to place the FAB on the left side in Codename One. I’m guessing it doesn’t? How does it look?\nMo — June 25, 2017 at 1:28 pm (permalink) Mo says:\nHi Shai, thank you for getting back to me, when changing to Arabic locale (RTL) it’s not showing at all and unlike when it’s LTR direction, keeping in mind that, the root container is correctly changing direction!!\nMo — June 25, 2017 at 11:08 pm (permalink) Mo says:\nHi Shai, any thoughts as to when this will be looked at or fixed, since I am planning to utilise this component on most of my Containers ??\nShai Almog — June 26, 2017 at 4:37 am (permalink) Shai Almog says:\nHi,\nfirst you need to file an issue and then we need to set a priority. We’re just releasing 3.7 so it will probably take a while if it’s even scheduled for 3.8 as that release is already pretty full with issues.\nSince this issue probably existed since 2016 without a report that probably indicates the low priority of this issue.\nI think you might be able to workaround this by disabling RTL on the content pane and aligning the FAB to the left.\nFYI You can also try to fix this issue yourself and submit a pull request which is excellent practice. I have a tutorial about that here: https://www.codenameone.com…\nMo — July 2, 2017 at 10:53 am (permalink) Mo says:\nApologies for the late reply!!,\nIssue filed for this at (https://github.com/codename…), and have been trying to implement the workaround suggested, sadly this caused my other component layout to miss-behave, thus, I would rather wait for the fix and hopefully not too long!\nShai Almog — July 3, 2017 at 3:13 pm (permalink) Shai Almog says:\nIf you only apply the LTR mode to the button and the layered layout (not the other components) it shouldn’t impact anything else.\nTommy Mogaka — July 12, 2018 at 10:51 am (permalink) Tommy Mogaka says:\nHi,\nHow do I add an action to each of the submenu items? I have\nbeen able to create a floating action button with three submenus but when I\nadd an actionlister it is fires on the main button and not the sub\nbuttons.\nFloatingActionButton fabtn = FloatingActionButton.createFAB(FontImage.MATERIAL_ADD);\nfabtn.getAllStyles().setFont(font_small_bold);\nfabtn.getAllStyles().setFgColor(0xffd800);\nfabtn.getAllStyles().setBgColor(0xffd800);\nfabtn.addActionListener(e -\u0026gt; ToastBar.showErrorMessage(\u0026ldquo;Add Personel Not implemented yet…\u0026rdquo;));\nfabtn.createSubFAB(FontImage.MATERIAL_PEOPLE, \u0026ldquo;Add Personel\u0026rdquo;).getAllStyles().setBgColor(0xffd800);\nfabtn.setTextPosition(BOTTOM);\nfabtn.addActionListener(f -\u0026gt; ToastBar.showErrorMessage(\u0026ldquo;Add Equipment Not implemented yet…\u0026rdquo;));\nfabtn.createSubFAB(FontImage.MATERIAL_COMMENT, \u0026ldquo;Add Equipment\u0026rdquo;).getAllStyles().setBgColor(0xffd800);\nfabtn.setTextPosition(BOTTOM);\nAlso, I can’t seem to get the submenu text to show! Finally, how do I style the submenu items individually e.g. text position or font colour? I have only been able to change the icon colours for the main button and the sub buttons as shown above.\nThanks!\nShai Almog — July 13, 2018 at 4:51 am (permalink) Shai Almog says:\ncreateSubFab returns its own FAB instance. You need to bind your listener to that instance.\nTommy Mogaka — February 3, 2019 at 1:34 pm (permalink) Tommy Mogaka says:\nHi Shai.. I was able to a create a separate ActionListener for each SubFab but how do I style each SubFub separately?\nBelow is what I have done but the way I’ve done it doesn’t allow changing the BgColor for each SubFub as previously. Could you please show my how I can be able to do so?\nfabtn.createSubFAB(FontImage.MATERIAL_HELP, \u0026ldquo;Help\u0026rdquo;).addActionListener(new ActionListener()\n{\n@Override\npublic void actionPerformed(ActionEvent evt)\n{\nToastBar.showErrorMessage(\u0026ldquo;Help button pressed…\u0026rdquo;);\n}\n});\nfabtn.createSubFAB(FontImage.MATERIAL_BUILD, \u0026ldquo;Settings\u0026rdquo;).addActionListener(new ActionListener()\n{\n@Override\npublic void actionPerformed(ActionEvent evt)\n{\nToastBar.showErrorMessage(\u0026ldquo;Admin button pressed…\u0026rdquo;);\n}\n});\nShai Almog — February 4, 2019 at 3:31 am (permalink) Shai Almog says:\nInstead of adding the action listener save the returned instance of the subfab and then add the action listener. Then customize the color on that returned instance.\nTommy Mogaka — February 4, 2019 at 7:31 am (permalink) Tommy Mogaka says:\nThanks Shai for the prompt reply… I will have to expose that my Java skills are quiet questionable as I am mostly self-taught and so I am not familiar with some concepts e.g. how to return an instance of a component.\nCould you please share some code snippet on how I can return an instance of a Subfab and how to save and style it? Many thanks!\nShai Almog — February 5, 2019 at 3:10 am (permalink) Shai Almog says:\nFloatingActionButton subFabHelp = fabtn.createSubFAB(FontImage.MATERIAL_HELP, \u0026quot;Help\u0026quot;); subFabHelp.addActionListener(…); subFabHelp.setUIID(\u0026quot;SubFabStyle\u0026quot;); Or similar.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/floating-button/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/floating-button/floating-action.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe material design floating action button is a powerful tool for promoting an action within your application. Quite\u003cbr\u003e\na few Codename One developers implemented with own interpretation of this UI element and with the coming update\u003cbr\u003e\nwe will have an official implementation.\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003eFloatingActionButton\u003c/code\u003e is a round button that resides on top of the UI typically in the bottom right hand side.\u003cbr\u003e\nIt has a drop shadow to distinguish it from the UI underneath and it can hide two or more additional actions under\u003cbr\u003e\nthe surface. E.g. we can create a simple single click button such as this:\u003c/p\u003e","title":"Floating Button"},{"content":"\nCircles and completely round border sides are problematic for multi-resolutions. You need to draw them dynamically\nand can’t use image borders which can’t be tiled/cut to fit round designs. Up until now we recommended using\nbackground images or changing the design entirely but now we have a new option: RoundBorder.\nWe designed the RoundBorder to enable two distinct types of borders:\nCircular borders – e.g. Android floating action\nRectangles with round (not rounded) sides\nNotice that this border doesn’t address the case of rounded corner border.\nCurrently we don’t have a way to define this border from the theme and we are still ironing out all the features\nthat will go into it but we already have the basic underpinnings.\nBorder Builder A round border is created using the builder pattern. You can get a new instance using RoundBorder.create(),\nthis will produce a red circular border with no shadow or stroke. You can then chain operations together to produce\nvarious effects e.g. this is our starting point:\nForm hi = new Form(\u0026quot;Round\u0026quot;, new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER)); Label l = new Label(\u0026quot;X\u0026quot;); l.getUnselectedStyle().setAlignment(Component.CENTER); l.getUnselectedStyle().setBorder( RoundBorder.create() ); hi.add(BorderLayout.CENTER, l); hi.show(); Figure 1. Plain round border with no options\nWe can set the color:\nRoundBorder.create().color(0xff) Figure 2. Round border with blue color\nWe can change the opacity:\nRoundBorder.create().color(0xff).opacity(100) Figure 3. Round border with blue color and transparency\nBorder can have drop shadows, however since they increase the size required for the border we also added\nsome padding to the code:\nForm hi = new Form(\u0026quot;Round\u0026quot;, new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER)); Label l = new Label(\u0026quot;X\u0026quot;); l.getUnselectedStyle().setAlignment(Component.CENTER); l.getUnselectedStyle().setPaddingUnit(Style.UNIT_TYPE_DIPS); l.getUnselectedStyle().setPadding(5, 5, 5, 5); l.getUnselectedStyle().setBorder( RoundBorder.create().shadowOpacity(90) ); hi.add(BorderLayout.CENTER, l); hi.show(); Figure 4. Round border with dropshadow\nYou can control the shadow spread (how big it is), its opacity, blur \u0026amp; x/y position (to create light source perspective).\nSo if we want a slightly larger shadow from a light source coming from the top right we can do something like this:\nl.getUnselectedStyle().setPadding(3, 8, 8, 3); l.getUnselectedStyle().setBorder( RoundBorder.create().shadowOpacity(90). shadowSpread(Display.getInstance().convertToPixels(4)). shadowX(1). shadowY(0) ); __ | Notice that we had to change the padding so the X will remain the center as the border is now larger on the\nbottom left sides due to the shadow. Figure 5. Larger dropshadow that is cast to the bottom left\nRound borders can also be used for more rectangular shapes such as this:\nLabel l = new Label(\u0026quot;Label Text\u0026quot;); l.getUnselectedStyle().setAlignment(Component.CENTER); l.getUnselectedStyle().setBorder( RoundBorder.create().rectangle(true) ); Figure 6. Rectangle mode in the round border\nWe can even stroke round borders with a line around the edges \u0026amp; all of the operations work on circles/rectangles etc!\nTo stroke we need to define the Stroke object and can optionally define color/opacity for the stroke:\nRoundBorder.create().rectangle(true).stroke(new Stroke(2, Stroke.CAP_SQUARE, Stroke.JOIN_MITER, 4)). strokeColor(0xff).strokeOpacity(120) Figure 7. Stroked round rectangle\nPutting it all Together The sample below puts all of these features together into a single UI that works well in portrait/landscape and\nall DPI’s. We chose to use hardcoded style settings so the sample will be self contained:\nForm hi = new Form(\u0026quot;Round\u0026quot;, new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER)); Button ok = new Button(\u0026quot;OK\u0026quot;); Button cancel = new Button(\u0026quot;Cancel\u0026quot;); Label loginLabel = new Label(\u0026quot;Login\u0026quot;, \u0026quot;Container\u0026quot;); loginLabel.getAllStyles().setAlignment(Component.CENTER); Label passwordLabel = new Label(\u0026quot;Password\u0026quot;, \u0026quot;Container\u0026quot;); passwordLabel.getAllStyles().setAlignment(Component.CENTER); TextField login = new TextField(\u0026quot;\u0026quot;, \u0026quot;Login\u0026quot;, 20, TextArea.ANY); TextField password = new TextField(\u0026quot;\u0026quot;, \u0026quot;Password\u0026quot;, 20, TextArea.PASSWORD); Style loginStyle = login.getAllStyles(); Stroke borderStroke = new Stroke(2, Stroke.CAP_SQUARE, Stroke.JOIN_MITER, 1); loginStyle.setBorder(RoundBorder.create(). rectangle(true). color(0xffffff). strokeColor(0). strokeOpacity(120). stroke(borderStroke)); loginStyle.setMarginUnit(Style.UNIT_TYPE_DIPS); loginStyle.setMargin(Component.BOTTOM, 3); Style passwordStyle = password.getAllStyles(); passwordStyle.setBorder(RoundBorder.create(). rectangle(true). color(0xffffff). strokeColor(0). strokeOpacity(120). stroke(borderStroke)); Container box = BoxLayout.encloseY( loginLabel, login, passwordLabel, password, GridLayout.encloseIn(2, cancel, ok)); Button closeButton = new Button(); Style closeStyle = closeButton.getAllStyles(); closeStyle.setFgColor(0xffffff); closeStyle.setBgTransparency(0); closeStyle.setPaddingUnit(Style.UNIT_TYPE_DIPS); closeStyle.setPadding(3, 3, 3, 3); closeStyle.setBorder(RoundBorder.create().shadowOpacity(100)); FontImage.setMaterialIcon(closeButton, FontImage.MATERIAL_CLOSE); Container layers = LayeredLayout.encloseIn(box, FlowLayout.encloseRight(closeButton)); Style boxStyle = box.getUnselectedStyle(); boxStyle.setBgTransparency(255); boxStyle.setBgColor(0xeeeeee); boxStyle.setMarginUnit(Style.UNIT_TYPE_DIPS); boxStyle.setPaddingUnit(Style.UNIT_TYPE_DIPS); boxStyle.setMargin(4, 3, 3, 3); boxStyle.setPadding(2, 2, 2, 2); hi.add(BorderLayout.CENTER, layers); hi.show(); Figure 8. Sample containing round border variants Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nYaakov Gesher — September 14, 2016 at 6:01 am (permalink) This looks great! Is there a Material Design theme available/in the works?\nShai Almog — September 15, 2016 at 3:43 am (permalink) Thanks, we are working on bringing material design concepts into Codename One. E.g. yesterdays floating button post.\nMost of those concepts don’t really fit into the idea of a \u0026ldquo;theme\u0026rdquo; but rather widgets… If you have a specific thought or something else you want from material design let us know.\nChibuike Mba — September 16, 2016 at 7:36 pm (permalink) Nice one Shai. Good job.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/round-border/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/round-border/round-border.png\"\u003e\u003c/p\u003e\n\u003cp\u003eCircles and completely round border sides are problematic for multi-resolutions. You need to draw them dynamically\u003cbr\u003e\nand can’t use image borders which can’t be tiled/cut to fit round designs. Up until now we recommended using\u003cbr\u003e\nbackground images or changing the design entirely but now we have a new option: \u003ccode\u003eRoundBorder\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eWe designed the \u003ccode\u003eRoundBorder\u003c/code\u003e to enable two distinct types of borders:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eCircular borders – e.g. Android floating action\u003c/p\u003e","title":"Round Border"},{"content":"\nWhen we designed the icon for the new Kitchen Sink demo we tried to use material design principals. We thought it\nwould look reasonable on iOS but it looked awful. So we decided to adapt the design and create a separate\nyet similar icon for iOS.\nThis is actually quite common but many developers aren’t aware of how easy it is to do these sort of things. The\nbuild process for Codename One is mostly transparent and you can replace/customize pieces of it. In this\ncase we edited the build.xml file and modified this build target:\n\u0026lt;target name=\u0026quot;build-for-ios-device\u0026quot; depends=\u0026quot;clean,copy-ios-override,copy-libs,jar,clean-override\u0026quot;\u0026gt; \u0026lt;codeNameOne jarFile=\u0026quot;${dist.jar}\u0026quot; displayName=\u0026quot;${codename1.displayName}\u0026quot; packageName = \u0026quot;${codename1.packageName}\u0026quot; mainClassName = \u0026quot;${codename1.mainName}\u0026quot; version=\u0026quot;${codename1.version}\u0026quot; icon=\u0026quot;${codename1.icon}\u0026quot; vendor=\u0026quot;${codename1.vendor}\u0026quot; subtitle=\u0026quot;${codename1.secondaryTitle}\u0026quot; targetType=\u0026quot;iphone\u0026quot; certificate=\u0026quot;${codename1.ios.debug.certificate}\u0026quot; certPassword=\u0026quot;${codename1.ios.debug.certificatePassword}\u0026quot; provisioningProfile=\u0026quot;${codename1.ios.debug.provision}\u0026quot; appid=\u0026quot;${codename1.ios.appid}\u0026quot; automated=\u0026quot;${automated}\u0026quot; /\u0026gt; \u0026lt;/target\u0026gt; We changed one line:\nicon=\u0026quot;iosicon.png\u0026quot; We also had to do the same change in the release target:\n\u0026lt;target name=\u0026quot;build-for-ios-device-release\u0026quot; depends=\u0026quot;clean,copy-ios-override,copy-libs,jar,clean-override\u0026quot;\u0026gt; This is really convenient as it allows you to override and automate many stages of the build. Every device build\nhas a target and you can modify things such as which files get packaged.\nXML Updates The pitfall with this technique is that XML files are updated occasionally. The Codename One Settings application\nor the IDE preferences will detect out of date build.xml files and offer to update them, this might be required to\ntake advantage of newer features such as offline build…​\nThis update will eliminate your changes so you will need to reintegrate them. If you have many changes just move them\nto an external file that you can include in the right spot so re-integrating changes is easy. Also make sure to keep\nthe build.xml in version control so an accidental overwrite won’t destroy your work. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — September 16, 2016 at 5:29 am (permalink) bryan says:\nRe Kitchen Sink – I’ve been looking at the source to see how some of the stuff in the demo is done, and it would be really good if there were more comments or description in the code (or accompanying the demo) so developers could copy some of the techniques used. There’s a bunch of stuff obviously possible with CN1, but much of it is hidden away and not always obvious that what’s possible.\nShai Almog — September 16, 2016 at 9:41 am (permalink) Shai Almog says:\nHere is a neat trick you can do:\nPress the edit icon on the top right and just insert your comments or even \u0026ldquo;can you explain this?\u0026rdquo; comments. Once done just click the pull request button.\nI will merge the pull request and then fix the \u0026ldquo;explain this\u0026rdquo; comments… You don’t even need to check out the project.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/different-icons/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/different-icons/kitchensink-2-flat.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen we designed the icon for the new Kitchen Sink demo we tried to use material design principals. We thought it\u003cbr\u003e\nwould look reasonable on iOS but it looked awful. So we decided to adapt the design and create a separate\u003cbr\u003e\nyet similar icon for iOS.\u003c/p\u003e\n\u003cp\u003eThis is actually quite common but many developers aren’t aware of how easy it is to do these sort of things. The\u003cbr\u003e\nbuild process for Codename One is mostly transparent and you can replace/customize pieces of it. In this\u003cbr\u003e\ncase we edited the \u003ccode\u003ebuild.xml\u003c/code\u003e file and modified this build target:\u003c/p\u003e","title":"Different Icons"},{"content":"\nWe made a lot of changes to Codename One over the past week but eventually decided to postpone the plugin\nupdate to next week so we can do more work on the GUI builder. We have quite a few new features and fixes lined\nup for next week already.\nOn stackoverflow things were as usual:\nhow to use phone contacts instead of gmail contacts for social app in codenameone Getting device contacts is actually easier than getting gmail contacts\nRead on stackoverflow…​\nNew GUI builder from CodeNameOne introduces exception? There seems to be a problem in the GUI builder IDE integration, this should be fixed in the next plugin update\nRead on stackoverflow…​\nSave a photo with a specific name and compressed size in codenameone You can select the size in megabytes in advance but you can monitor the size and control it via resolution change\nRead on stackoverflow…​\nJava 8 and Java time Codename One supports a subset of Java 8 with subset being an important keyword here…​ I’d like to explain this\ninto greater details, perhapse with a blog post\nRead on stackoverflow…​\nConvert time to utc Timezones are a pain no matter which technology you use, they are just awful\nRead on stackoverflow…​\nInstall Error for iOS Ideally we’ll mirror and eventually remove the appspot servers completely\nRead on stackoverflow…​\niOS Build Server Issue With the update coming out today we should have more logging that will allow tracking down these issues\nRead on stackoverflow…​\nReflection not working in ios in codename one Dynamic class loading \u0026ldquo;might\u0026rdquo; work but it isn’t reliable across platforms and might run into issues with obfuscation\nor optimizers. You should use class literals instead\nRead on stackoverflow…​\nCodename One and jformdesigner Some AWT/Swing GUI builder code can be copied to Codename One \u0026ldquo;as is\u0026rdquo; with package names and a few class\nname changes\nRead on stackoverflow…​\nSidemenu customization We don’t currently support tinting the form on which the side menu is overlaid\nRead on stackoverflow…​\nHow to change the background of an SVG in Codename One Codename One doesn’t really support SVG’s. We convert them to PNG when importing them to the IDE.\nWe might improve on that in the future but the demand isn’t great…​\nRead on stackoverflow…​\nHow to kill web browser instance after close form You can explicitly call destroy() but often you need to sign out first\nRead on stackoverflow…​\nJava Scanner – Mobile App Build Error Sometimes in the attempts to workaround/fix a problem you create a bigger problem.\nRead on stackoverflow…​\nhow to show gmail contact in android after signin with google in codenaoneone You can access the Google+ contacts as well as the on-device contacts\nRead on stackoverflow…​\nInvoke codename code from native interface There are several tricks to do this listed in the developer guide…​\nRead on stackoverflow…​\nAdMob ads not showing in iOS This isn’t the first time banner ads posed a problem, we made a mistake when we integrated them into the build\nflow and should have integrated them as a cn1lib\nRead on stackoverflow…​\nshowForm – java.lang.reflect.InvocationTargetException The error message from the simulator is somewhat unintuitive sometimes as it is wrapped in the simulator code.\nThe actual exception was the NullPointerException below the InvocationTargetException\nRead on stackoverflow…​\nCodenameone plugin giving null pointer exception Handling the case where the .gui file is missing or in a different location is a bit problematic in the various IDE’s.\nRead on stackoverflow…​\nGraphics drawing code generates blank images, only on iOS This is covered in an issue submission so we need to evaluate this thru the issue\nRead on stackoverflow…​\nGetting line numbers in stack traces We use the Android VM as-is so the stack trace lines are pretty much what Android gives us\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xxii/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xxii/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe made a lot of changes to Codename One over the past week but eventually decided to postpone the plugin\u003cbr\u003e\nupdate to next week so we can do more work on the GUI builder. We have quite a few new features and fixes lined\u003cbr\u003e\nup for next week already.\u003c/p\u003e\n\u003cp\u003eOn stackoverflow things were as usual:\u003c/p\u003e\n\u003ch3 id=\"how-to-use-phone-contacts-instead-of-gmail-contacts-for-social-app-in-codenameone\"\u003ehow to use phone contacts instead of gmail contacts for social app in codenameone\u003c/h3\u003e\n\u003cp\u003eGetting device contacts is actually easier than getting gmail contacts\u003c/p\u003e","title":"Questions of the Week XXII"},{"content":"\nIf you relied on the android.newPeer=false build hint it will no longer be available starting with this update. When\nyou build for 3.5 you will still get the old behavior if you define that hint but otherwise it will be ignored. This is a\nprecursor step to merging the newPeer branch into the main branch. It’s an important step to help us move forward\nwith one code base!\nGUI Builder UI Change With the new update of the GUI builder we will move the tree tab into it’s own space below the tabs so it will\nlook like this:\nFigure 1. New look for the GUI builder sidebar\nAfter experimenting with this for a while we came to the conclusion that this is far more convenient than the\nprevious arrangement.\nA missing piece is the ability to drag into/within the tree, this is indeed something we would like to do but because\nthe tree is physically within a SideMenuBar the task is non-trivial.\nYou can expect to see this change in the next plugin update, we are thinking of making such an update next week\nbut these updates are more fluid than the standard Friday releases.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-peer-gui-builder-tree/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-peer-gui-builder-tree/generic-java-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIf you relied on the \u003ccode\u003eandroid.newPeer=false\u003c/code\u003e build hint it will no longer be available starting with this update. When\u003cbr\u003e\nyou build for 3.5 you will still get the old behavior if you define that hint but otherwise it will be ignored. This is a\u003cbr\u003e\nprecursor step to merging the newPeer branch into the main branch. It’s an important step to help us move forward\u003cbr\u003e\nwith one code base!\u003c/p\u003e","title":"New Peer \u0026 GUI Builder Tree"},{"content":"\nThe two key factors to improve any product are: get help from your biggest fans \u0026amp; learn from your detractors.\nObviously there is a lot of nuance to that wide reaching advice…​\nRating widgets embody this advice. They prompt a user for a rating. If it’s good we ask him to review the app in\nthe appstore and thus bring more users. If it’s bad we ask him to tell us why!\nFor years people asked us how to build such a tool and we gave a general guideline, no one contributed it back.\nSo we decided it’s time to build it ourselves:\nFigure 1. The initial prompt of the widget\nFigure 2. If the rating is 4 or higher it prompts for store rating\nFigure 3. If the rating is lower than 4 it asks for feedback\nHow Does it Work? The widget is really simple and relies on our previous star rating widget code.\nTo use it we need the appstore URL first, there are other ways to do it but the simplest one is:\npublic String getAppstoreURL() { if(Display.getInstance().getPlatformName().equals(\u0026quot;ios\u0026quot;)) { return \u0026quot;https://itunes.apple.com/us/app/kitchen-sink-codename-one/id635048865\u0026quot;; } if(Display.getInstance().getPlatformName().equals(\u0026quot;and\u0026quot;)) { return \u0026quot;https://play.google.com/store/apps/details?id=com.codename1.demos.kitchen\u0026quot;; } return null; } Once we have that we can bind the widget in the start() method:\npublic void start(){ if(getAppstoreURL() != null) { RatingWidget.bindRatingListener(180000, getAppstoreURL(), \u0026quot;[[email protected]](/cdn-cgi/l/email-protection)\u0026quot;); } if(currentForm != null \u0026amp;\u0026amp; !(currentForm instanceof Dialog)) { currentForm.show(); return; } showSplashAnimation(); } Notice that the bind is invoked every time that start is invoked, which will happen also after an app is minimized.\nWe time the prompt to 3 minutes (180 seconds) but if the user minimizes the app after a minute we want to pause the\ncounting…​ This allows us to resume the counting.\nThat is why the stop method includes this line of code:\nRatingWidget.suspendRating(); That way the rating countdown is suspended when the app is minimized.\nThe Widget The widget itself is really simple, it uses a thread to wait until the right time although we use notify to wakeup in case\nof suspend. This is more efficient than using a sleep loop.\nYou can check out the\nfull up to date code\nin the kitchen sink github project.\nPasted below for your convenience is the current version:\npublic class RatingWidget { private static RatingWidget instance; private boolean running; private int timeForPrompt; private String appstoreUrl; private String supportEmail; private RatingWidget() { } private void init(String appstoreUrl, String supportEmail) { this.appstoreUrl = appstoreUrl; this.supportEmail = supportEmail; running = true; Thread t = Display.getInstance().startThread(() -\u0026gt; checkTimerThread(), \u0026quot;Review thread\u0026quot;); t.start(); } void checkTimerThread() { while(running) { long lastTime = System.currentTimeMillis(); int timeEllapsedInApp = Preferences.get(\u0026quot;timeElapsedInApp\u0026quot;, 0); Util.wait(this, timeForPrompt - timeEllapsedInApp); long total = System.currentTimeMillis() - lastTime; if(total + timeEllapsedInApp \u0026lt; timeForPrompt) { Preferences.set(\u0026quot;timeElapsedInApp\u0026quot;, (int)(total + timeEllapsedInApp)); } else { Display.getInstance().callSerially(() -\u0026gt; showReviewWidget()); running = false; instance = null; return; } } } void showReviewWidget() { // block this from happening twice Preferences.set(\u0026quot;alreadyRated\u0026quot;, true); InteractionDialog id = new InteractionDialog(\u0026quot;Please Rate \u0026quot; + Display.getInstance().getProperty(\u0026quot;AppName\u0026quot;, \u0026quot;The App\u0026quot;)); int height = id.getPreferredH(); Form f = Display.getInstance().getCurrent(); id.setLayout(new BorderLayout()); Slider rate = createStarRankSlider(); Button ok = new Button(\u0026quot;OK\u0026quot;); Button no = new Button(\u0026quot;No Thanks\u0026quot;); id.add(BorderLayout.CENTER, FlowLayout.encloseCenterMiddle(rate)). add(BorderLayout.SOUTH, GridLayout.encloseIn(2, no, ok)); id.show(f.getHeight() - height - f.getTitleArea().getHeight(), 0, 0, 0); no.addActionListener(e -\u0026gt; id.dispose()); ok.addActionListener(e -\u0026gt; { id.dispose(); if(rate.getProgress() \u0026gt;= 9) { if(Dialog.show(\u0026quot;Rate On Store\u0026quot;, \u0026quot;Would you mind rating us in the appstore?\u0026quot;, \u0026quot;Go To Store\u0026quot;, \u0026quot;Dismiss\u0026quot;)) { Display.getInstance().execute(appstoreUrl); } } else { if(Dialog.show(\u0026quot;Tell Us Why?\u0026quot;, \u0026quot;Would you mind writing us a short message explaining how we can improve?\u0026quot;, \u0026quot;Write\u0026quot;, \u0026quot;Dismiss\u0026quot;)) { Message m = new Message(\u0026quot;Heres how you can improve \u0026quot; + Display.getInstance().getProperty(\u0026quot;AppName\u0026quot;, \u0026quot;the app\u0026quot;)); Display.getInstance().sendMessage(new String[] {supportEmail}, \u0026quot;Improvement suggestions for \u0026quot; + Display.getInstance().getProperty(\u0026quot;AppName\u0026quot;, \u0026quot;your app\u0026quot;), m); } } }); } private void initStarRankStyle(Style s, Image star) { s.setBackgroundType(Style.BACKGROUND_IMAGE_TILE_BOTH); s.setBorder(Border.createEmpty()); s.setBgImage(star); s.setBgTransparency(0); } private Slider createStarRankSlider() { Slider starRank = new Slider(); starRank.setEditable(true); starRank.setMinValue(0); starRank.setMaxValue(10); Font fnt = Font.createTrueTypeFont(\u0026quot;native:MainLight\u0026quot;, \u0026quot;native:MainLight\u0026quot;). derive(Display.getInstance().convertToPixels(5, true), Font.STYLE_PLAIN); Style s = new Style(0xffff33, 0, fnt, (byte)0); Image fullStar = FontImage.createMaterial(FontImage.MATERIAL_STAR, s).toImage(); s.setOpacity(100); s.setFgColor(0); Image emptyStar = FontImage.createMaterial(FontImage.MATERIAL_STAR, s).toImage(); initStarRankStyle(starRank.getSliderEmptySelectedStyle(), emptyStar); initStarRankStyle(starRank.getSliderEmptyUnselectedStyle(), emptyStar); initStarRankStyle(starRank.getSliderFullSelectedStyle(), fullStar); initStarRankStyle(starRank.getSliderFullUnselectedStyle(), fullStar); starRank.setPreferredSize(new Dimension(fullStar.getWidth() * 5, fullStar.getHeight())); return starRank; } /** * Binds the rating widget to the UI if the app wasn't rated yet * * @param time time in milliseconds for the widget to appear * @param appstoreUrl the app URL in the store * @param supportEmail support email address if the rating is low */ public static void bindRatingListener(int time, String appstoreUrl, String supportEmail) { if(Preferences.get(\u0026quot;alreadyRated\u0026quot;, false)) { return; } instance = new RatingWidget(); instance.timeForPrompt = time; instance.init(appstoreUrl, supportEmail); } /** * This should be invoked by the stop() method as we don't want rating countdown to proceed when the app isn't * running */ public static void suspendRating() { if(instance != null) { synchronized(instance) { instance.notify(); } instance.running = false; instance = null; } } } Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/rating-widget/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/rating-widget/rating-widget.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe two key factors to improve any product are: get help from your biggest fans \u0026amp; learn from your detractors.\u003cbr\u003e\nObviously there is a lot of nuance to that wide reaching advice…​\u003cbr\u003e\nRating widgets embody this advice. They prompt a user for a rating. If it’s good we ask him to review the app in\u003cbr\u003e\nthe appstore and thus bring more users. If it’s bad we ask him to tell us why!\u003c/p\u003e","title":"Rating Widget"},{"content":"\nEvery now and again developers ask us how we do the graphics for our posts/promotions and up until recently the\nanswer was \u0026ldquo;photoshop\u0026rdquo;. While knowing photoshop is still very worthwhile we still like these 3 tools that provide great\nshortcuts to creating both screenshots and art.\nThe App Launchpad App Launchpad is a newcomer to the scene, it’s still a new tool at the MVP stage.\nThe potential is still great and it generates reasonably attractive graphics such as these:\nFigure 1. App launchpad images contain a device frame with text/colors\nThe UX for the tool is reasonably intuitive and you can work on several screenshots at once. There are some missing\nbasic features that I’d like to see moving forward but the tool is already pretty useful. E.g. we used it for the kitchensink\nscreenshots on Android and\niOS.\nHopefully they will improve the tool by adding:\nLandscape support\nTablet skins\nThin fonts\nMore customization abilities e.g. image/texture backgrounds\nSmart Mockups Smart Mockups is a PlaceIt clone that isn’t\nas aggressively monetized. It allows you to take a screenshot and place it within a context of a device held by a user.\nNormally this is slightly challenging to do in photoshop unless you have a ready made template.\nThe image at the top of this post was generated with Smart Mockups and Adobe Spark…​\nAdobe Spark Spark is a tool that makes typography easy. It does quite a few things to generate images\nsuch as the image above that mix image filters, typography, shape decoration etc.\nAll of those allow you to create meme style images as well as a wide variety of banners/promo images that you\ncan use to market your apps in the stores.\nFigure 2. Adobe Spark \u0026amp; Smart Mockups were used to create this image\nGood Looking Graphics The app icon and screenshots are where the initial opinion of your app is formed. If the promotional material isn’t\ngood some users will still give your app the benefit of the doubt, but they will do so with a negative first impression.\nGood promotional material is no substitute for good app design, but it’s a step that you need to take. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChris Moore — May 30, 2019 at 7:49 am (permalink) Hey Shai!\nNice tips. I wonder whether you’ve tried Promomatic (https://www.promomatic.com/)) for building app screenshots instead of AppLaunchPad? Super easy to use and cost effective when building for the app store launch. Found them on Product Hunt a few months back.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/3-image-tools-for-app-marketing/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/3-image-tools-for-app-marketing/image-tools-for-app-marketing.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eEvery now and again developers ask us how we do the graphics for our posts/promotions and up until recently the\u003cbr\u003e\nanswer was \u0026ldquo;photoshop\u0026rdquo;. While knowing photoshop is still very worthwhile we still like these 3 tools that provide great\u003cbr\u003e\nshortcuts to creating both screenshots and art.\u003c/p\u003e\n\u003ch3 id=\"the-app-launchpad\"\u003eThe App Launchpad\u003c/h3\u003e\n\u003cp\u003e\u003ca href=\"http://theapplaunchpad.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eApp Launchpad\u003c/a\u003e is a newcomer to the scene, it’s still a new tool at the MVP stage.\u003cbr\u003e\nThe potential is still great and it generates reasonably attractive graphics such as these:\u003c/p\u003e","title":"3 Image Tools for App Marketing"},{"content":"\nHistorical note: Codename One\u0026rsquo;s UWP target was discontinued in release 7.0.229. This post is preserved for historical context only, and its build/setup instructions no longer apply to current Codename One projects.\nThe UWP (Universal Windows Platform) port is finally stable enough to get an\napp into the Microsoft store.\nSteve published out Solitaire demo into the Microsoft appstore and it passed thru the whole process. You\ncan download it, install it on your device and try it.\nWe’ll try to setup a company account to publish the kitchen sink as well moving forward.\nThis is a huge step for the UWP port showing its maturity and readiness for prime-time.\nFuture of Windows Phone Port We weren’t bullish on the continued maintenence of the Windows Phone port but with recent events e.g. MS discontinuing\nSkype on Windows Phone it is pretty clear the platform is dead. Had the port been mature this wouldn’t have been a\nproblem, but the Windows Phone port has huge glaring problems…​\nFixing these problems is an enormous task and one that just isn’t viable for a discontinued platform. So we are officially\ndeprecating the Windows Phone target and will mark it as deprecated starting with the next release.\nAt the moment we won’t remove it since we know people are still using it but we might do so in the near future as\nwe need to self host the servers to support this platform and that is a very problematic setup. These problems don’t\naffect the UWP port! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — September 5, 2016 at 8:30 pm (permalink) bryan says:\nOverflow menu commands don’t display correctly\nShai Almog — September 6, 2016 at 3:56 am (permalink) Shai Almog says:\nThanks, we noticed that too after this went live. It’s an odd issue.\nbryan — September 6, 2016 at 3:59 am (permalink) bryan says:\nIt’s the same issue I raised a few days ago. It works fine in a debug build, but not in an app store build.\nRoss Taylor — September 6, 2016 at 12:51 pm (permalink) Ross Taylor says:\nStrange afaik, Skype will be discontinued for Windows phones 7 – 8.1, but nothing was mentioned about Windows Phone 10?\nShai Almog — September 6, 2016 at 1:30 pm (permalink) Shai Almog says:\nMS’s lineup is a confusing mess.\nThere is no Windows Phone 10 and there never will be.\nThere is Windows 10 Mobile which is really a shrunk down version of Windows 10. To reach both Windows 10 (Desktop \u0026amp; Mobile) MS invented the Universal Windows Platform == UWP.\nSo we support the Windows 10+ versions that run on phones, desktops and tablets. We are ending support for the exact same thing that Skype is no longer supporting.\nRoss Taylor — September 6, 2016 at 1:49 pm (permalink) Ross Taylor says:\nAh, thanks clearing things up! Good to know CN1 is making effort to reach all platforms.\nJaanus Hansen — September 11, 2016 at 11:01 am (permalink) Jaanus Hansen says:\nVery cool news, but why images are so blurry on Desktop?\nShai Almog — September 12, 2016 at 4:20 am (permalink) Shai Almog says:\nI think that’s due to the apps resources. When I originally wrote the app I had a set of cards at a given resolution. It would have meant quite a bit of work to do a new high DPI deck.\nNotice that the toolbar icons aren’t blurry.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/first-uwp-app-and-the-way-forward/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/first-uwp-app-and-the-way-forward/solitaire-uwp.jpg\"\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003eHistorical note:\u003c/strong\u003e Codename One\u0026rsquo;s UWP target was discontinued in release \u003cstrong\u003e7.0.229\u003c/strong\u003e. This post is preserved for historical context only, and its build/setup instructions no longer apply to current Codename One projects.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eThe UWP (Universal Windows Platform) port is finally stable enough to get an\u003cbr\u003e\n\u003ca href=\"https://www.microsoft.com/en-us/store/p/codename-one-solitaire/9nblggh51z60\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eapp into the Microsoft store\u003c/a\u003e.\u003cbr\u003e\nSteve published out Solitaire demo into the Microsoft appstore and it passed thru the whole process. You\u003cbr\u003e\ncan download it, install it on your device and try it.\u003c/p\u003e","title":"First UWP App and the Way Forward"},{"content":"\nAugust is finally over and we can get back to our more usual brisk pace of progress!\nThe xcode migration which was one of the biggest pains to go thru is also mostly behind us and we can now\nturn our gaze to improving Codename One and its general usage experience.\nThis week was mostly uneventful in terms of stack overflow, the biggest news is the migration on Android to API\nlevel 23 which might include some issues.\nCodename one concurrent animations? There are many things we can do with animations thanks to the new animation manager!\nRead on stackoverflow…​\nWhen call up from Background my Codename App Shows bug Mobile app lifecycle has always been a difficult subject. I think we simplified this but it’s still non-trivial especially\nwith suspend/resume.\nRead on stackoverflow…​\nOnline database Connection Connecting to a database thru the mobile network is a problematic idea\nRead on stackoverflow…​\nHow to validate form in codeonename People often confuse the new/old GUI builder and try to create a form on the old one in a non-GUI builder project\nRead on stackoverflow…​\nGenerating certificate for iOS using codename one certificate wizard Yes you need to pay Apple to build native apps for a device you purchased. This is true even when working natively\nalthough later versions of xcode allow you to circumvent that slightly.\nRead on stackoverflow…​\n\u0026ldquo;Unrecognized Selector Sent to Instance\u0026rdquo; error in iOS native code Two really confusing things for developers new to Objective-C that had me stumped too:\nArgument names are a part of the method signature. If you change the name of the argument you break the code!\nThe compiler doesn’t check that a method (message) exists. This is common in scripting languages but odd for\na compiled language\nRead on stackoverflow…​\nError=13, Permission denied when adding event in CodenameOne The old designer is bound to the IDE in a problematic way so if more than one IDE instance exists or if the IDE\ninstallation isn’t standard things can get \u0026ldquo;weird\u0026rdquo;. This only exists in NetBeans as we found more elegant\nways of addressing this binding in other IDE’s.\nRead on stackoverflow…​\nWhat are the exact steps to deploy application on Windows Phone Those are listed in the developer guide for UWP, Windows Phone port is phasing out\nRead on stackoverflow…​\nHow to customize the look of a Tab for Android in codename one? The need to override the border UIID element is often confusing.\nRead on stackoverflow…​\nHow to remove commands added to overflow menu This was missing from the API, we added a new API to remove overflow commands explicitly\nRead on stackoverflow…​\nNeed to set java8 in codenameone project with IDE Myeclipse 2015 Java 8 support is painful under Eclipse where the ini needs to be edited\nRead on stackoverflow…​\nUWP app name can’t chinese. name change to? There was an issue with setting UWP application names to some locales this should be fixed in todays builds\nRead on stackoverflow…​\nGoogle Play Warning: SSL Error Handler Vulnerability I’m not sure why this error message was received. If other users got it we’d like to know as we didn’t get it for our\nsubmissions. The code mentioned in the message doesn’t exist in our workspace so maybe it’s related to a cn1lib?\nRead on stackoverflow…​\nSpecify absolute position of GUI element in CN1 I’m still not sure I understand the question correctly, I try to communicate more clearly but sometimes wires don’t\ncross properly and the original intention of the question gets lost\nRead on stackoverflow…​\nHow to get mobile info in codenameone? This isn’t so much a Codename One question, it’s a mobile question. The answer is easy on iOS: you can’t.\nRead on stackoverflow…​\nConstraints (West, center…) not visible in new GUI Builder The UX of the new GUI builder still needs some work. The biggest thing we need to fix is having the tree always\nopen so developers can see the selected component.\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xxi/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xxi/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAugust is finally over and we can get back to our more usual brisk pace of progress!\u003cbr\u003e\nThe xcode migration which was one of the biggest pains to go thru is also mostly behind us and we can now\u003cbr\u003e\nturn our gaze to improving Codename One and its general usage experience.\u003c/p\u003e\n\u003cp\u003eThis week was mostly uneventful in terms of stack overflow, the biggest news is the migration on Android to API\u003cbr\u003e\nlevel 23 which might include some issues.\u003c/p\u003e","title":"Questions of the Week XXI"},{"content":"\nIn the coming update we have a new API to expand/collapse an Accordion component programmatically similar to the Tree component.\nTo achieve this we introduced three new API’s to the Accordion class:\n/** * Returns the body component of the currently expanded accordion element or null if none is expanded * @return a component */ public Component getCurrentlyExpanded(); /** * Expands the accordion with the given \u0026quot;body\u0026quot; * @param body the body component of the accordion to expand */ public void expand(Component body); /** * Closes the accordion with the given \u0026quot;body\u0026quot; * @param body the body component of the accordion to close */ public void collapse(Component body); All of these methods get/return the body of the accordion which is probably the best way to identify an accordion node.\nXcode Migration The migration to the new xcode servers is going well so far. We did experience some minor issues the biggest was the need to use https has kicked in as a result of the newer tooling.\nPretty much everything seems to be in order and we migrated other servers to pick up the load so builds should be back to their typical build times. Before that builds might have been slower but once the migration is complete we’ll have more servers than we had when we started off making builds even faster.\nRight now we still have the iphone_old build target running, we plan to remove it by 3.6 (due December) so if you depend on it we suggest you keep us posted!\nNotice that once it’s removed we won’t be able to restore it as it depends on a legacy version of Mac OS X no longer sold.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/accordion-control-xcode-migration-update/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/accordion-control-xcode-migration-update/accordion-post.png\"\u003e\u003c/p\u003e\n\u003cp\u003eIn the coming update we have a new API to expand/collapse an \u003ccode\u003eAccordion\u003c/code\u003e component programmatically similar to the \u003ccode\u003eTree\u003c/code\u003e component.\u003c/p\u003e\n\u003cp\u003eTo achieve this we introduced three new API’s to the \u003ccode\u003eAccordion\u003c/code\u003e class:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e/**\n * Returns the body component of the currently expanded accordion element or null if none is expanded\n * @return a component\n */\npublic Component getCurrentlyExpanded();\n\n/**\n * Expands the accordion with the given \u0026quot;body\u0026quot;\n * @param body the body component of the accordion to expand\n */\npublic void expand(Component body);\n\n/**\n * Closes the accordion with the given \u0026quot;body\u0026quot;\n * @param body the body component of the accordion to close\n */\npublic void collapse(Component body);\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eAll of these methods get/return the body of the accordion which is probably the best way to identify an accordion node.\u003c/p\u003e","title":"Accordion Control \u0026 Xcode Migration Update"},{"content":"\nI try all things, I achieve what I can.\n— Herman Melville\nMoby-Dick\nOpening with a Moby-Dick quote seems rather appropriate for taking on the kitchen sink demo. It often seemed like a task that is too big and unsurmountable as we were working our way thru it. In fact the version that we are releasing now has far less features and abilities than our original whiteboard…​\nThe kitchen sink was our first demo, we drew inspiration from previous demos we did at Sun where the custom is to show off every UI element.\nOver the years it aged and included bad practices in the code. Since it’s such a major demo we knew we needed something special and set about with the following goals:\nDifferent tablet UI – We think it’s important for applications to adapt intelligently to tablet UI’s and the kitchen sink always demonstrated that Figure 1. The kitchen sink demo running on an iphone\nFigure 2. The kitchen sink demo running on an ipad\nUsable in free tier – the old kitchen sink was a multi-megabyte demo unusable by free subscribers. We wanted a big demo that would still fit in the 1mb free user limit\nAesthetically refined – we wanted a UI that’s modern and subtle, the goal isn’t to create something \u0026ldquo;exceptional\u0026rdquo;…​ The goal is to create something reasonable and achievable\nRealistic use cases – with the one exception of the layouts demo, most of the demos show usage that might be reasonable in a \u0026ldquo;real world\u0026rdquo; application\nCheck the live version running on the right hand side thanks to the power of the Codename One JavaScript port!\nNotice that the demo to the right is running in phone mode, to see it running in tablet mode open it in the desktop browser using this link.\nYou can install the native Android version of the kitchen sink from Google Play \u0026amp; the native iOS version from itunes. We’ll try to publish a UWP version and will update this space when we get it out.\nWith those goals in mind we recreated and re-invented the demos that are a part of kitchen sink.\nBefore going into the individual demos notice that app now has a UI that is more \u0026ldquo;card like\u0026rdquo;. We dynamically round the edges of the images (using masking) and allow you to search thru the demos using the standard search Toolbar.\nYou can also switch between grid/list view in the standard cell phone mode (this isn’t available in the tablet mode due to the different UX).\nFigure 3. List mode – click the top right icon to toggle modes\nWhen in list mode we use round version of the images (again with masking). We layer a decorative border on top to make them stand out a bit.\nThe current 2.0 version contains the following demos:\nLayouts Shows some of the core layouts in Codename One this is the one demo that bares some semblance to the old kitchen sink demo\nFigure 4. Layouts demo\nDogs Demonstrates usage of a webservice to fetch a list of dog images that are then rendered as a list and fetched dynamically. We use InfiniteContainer to fetch data in batches.\nWhen you click an entry we open it in an ImageViewer and dynamically fetch the full sized image.\nFigure 5. Dogs websevice/image demo\nTime This is the old clock demo. It demonstrates low level graphics and also presents dynamic image creation\nFigure 6. Time Demo\nThemes The themes demo shows dynamically downloadable/installable themes. We tried to keep this demo as simple as possible so we integrated the theme list and hardcoded them in.\nWe could have embedded the themes in the app but that would have increased its size considerably thus crossing the free quota limit.\nFigure 7. Theme demo\nContacts This is one of the more elaborate demos, we fetch the device contacts when available. E.g. JavaScript has no access to device contacts so we show a list of GoT characters.\nYou can swipe any contacts to the left/right to show details/options e.g. on the left you can dial a contact or share the contact information. On the right you can delete the contact permanently from your phone…​\nFigure 8. The contacts demo\nInput A simple table UI showing user input e.g. text fields etc.\nThis UI adapts itself to use the extra tablet space. When running in the phone it works differently for portrait/landscape. On rotation it adapts the UI with an animation.\nWe can also grab a picture from the gallery/camera to use on the top of the input form.\nFigure 9. The input UI when running in portrait\nFigure 10. The input UI when running in landscape or a tablet\nSales The sales demo shows off a typical business application UI with a simple table whose changes you can see reflected in the chart above.\nYou can maximize/restore both the table and the chart using the icon on the top right.\nWe have two simple charts, the API is far more elaborate but we wanted to allow easy editing so we avoided complex UI’s.\nFigure 11. Sales demo chart\nFinal Word We spent some time refining this demo and we hope it shows. We think there is still a lot we should improve with it.\nWe will include the updated version in upcoming plugin updates but you can check out the code in github here.\nNotice that when we ship the demo in the stores we don’t call it a demo and refer to it as a tutorial…​ This is intentional, appstores prohibit demos but are fine with tutorial applications. It’s a silly semantic nuance but essential so you can try Codename One without jumping thru hoops.\n__ We made the store screenshots using theapplaunchpad.com, check it out Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nLukman Javalove Idealist Jaji — September 1, 2016 at 4:40 am (permalink) Hi Shai\nThis is beautiful and congrtd to you and the team for the beautiful work. I must confess this demo will sell Codenameone better as it gives a better first impression. I once read one of the articles which says you’re working also on new Themes, It’s still the old ones that are here. Did I read wrongly or the themes will come in the coming updates.?\nLukman\nShai Almog — September 1, 2016 at 6:25 am (permalink) Hi,\nthanks!\nWe do want to work on better themes but this is something we tried repeatedly in the past with partial success. I think the right thing to do is work with a designer unfortunately we don’t have one on-staff at this time.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/kitchensink-ii/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/kitchensink-ii/kitchensink-2-flat.jpg\"\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eI try all things, I achieve what I can.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e— Herman Melville\u003cbr\u003e\nMoby-Dick\u003c/p\u003e\n\u003cp\u003eOpening with a Moby-Dick quote seems rather appropriate for taking on the kitchen sink demo. It often seemed like a task that is too big and unsurmountable as we were working our way thru it. In fact the version that we are releasing now has far less features and abilities than our original whiteboard…​\u003c/p\u003e\n\u003cp\u003eThe kitchen sink was our first demo, we drew inspiration from previous demos we did at Sun where the custom is to show off every UI element.\u003c/p\u003e","title":"KitchenSink II"},{"content":"\nOne of the biggest changes we made in the past couple of years was the introduction of Java 8 language support features and making it the default target. We are now ready for the next step: removing compatibility for Java 5 targeted builds.\nNotice that this won’t break existing projects…​ They will compile with the retrolambda pipeline even if you set the build hint java.version=5.\nWe are doing this so we can integrate Java 8 features into the core of the Codename One itself and make the implementation more efficient/easy.\nThis change will go in this Friday, if you have old projects that you haven’t compiled in a while we would suggest testing them.\nAndroid API 23 Default We mentioned Android permissions a while back. We are now switching to API level 23 by default as this makes more sense moving forward.\nUnlike the language change you could still revert this change manually by defining android.targetSDKVersion=21. Notice that this is a short term solution as our goal is to keep up with the current Android release cycle. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nSimone Peirani — September 7, 2016 at 7:16 am (permalink) Simone Peirani says:\nHi,\nI noticed an issue with BTDemo on Android 6.0.1 device (with API 23 in build hints). To get works the App the user should go under settings –\u0026gt; App – – \u0026gt; BTDemo –\u0026gt; Authorizations, and manually enable the position authorization.\nBy setting API 21 under build hints, BTDemo perfectly works instead.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/java-8-api-23-defaults/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/java-8-api-23-defaults/marshmallow.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the biggest changes we made in the past couple of years was the introduction of Java 8 language support features and making it the default target. We are now ready for the next step: removing compatibility for Java 5 targeted builds.\u003c/p\u003e\n\u003cp\u003eNotice that this won’t break existing projects…​ They will compile with the retrolambda pipeline even if you set the build hint \u003ccode\u003ejava.version=5\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eWe are doing this so we can integrate Java 8 features into the core of the Codename One itself and make the implementation more efficient/easy.\u003c/p\u003e","title":"Java 8 \u0026 API 23 defaults"},{"content":"\nDiamond asked us about an easy way to do dropshadows in Codename One to which I answered that it’s pretty easy thanks to our Gaussian blur support…​\nWe ended up with this code which is usable but probably not as intuitive for most:\nForm hi = new Form(\u0026quot;Drop Shadow\u0026quot;, new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER)); FontImage mm = FontImage.createMaterial(FontImage.MATERIAL_PERSON, \u0026quot;Button\u0026quot;, 30); int[] rgb = mm.toImage().getRGB(); for(int iter = 0 ; iter \u0026lt; rgb.length ; iter++) { rgb[iter] = rgb[iter] \u0026amp; 0xff000000; } Image shadow = Image.createImage(rgb, mm.getWidth(), mm.getHeight()); if(Display.getInstance().isGaussianBlurSupported()) { shadow = Display.getInstance().gaussianBlurImage(shadow, 10); } Label top = new Label(mm, \u0026quot;Container\u0026quot;); Label bottom = new Label(shadow, \u0026quot;Container\u0026quot;); bottom.getAllStyles().setMargin(1, 0, 1, 0); bottom.getAllStyles().setMarginUnit(Style.UNIT_TYPE_DIPS); hi.add(BorderLayout.CENTER, LayeredLayout.encloseIn(bottom, top)); hi.show(); The effect is attractive and commonplace so I think it would be great to add it universally so we added two methods which will be a part of the coming update. These methods are in the Effects class and are both simple utility methods. Once creates a shadow and incorporates it into a new image at the given location. The other returns the shadow alone which you can shift/position as you see fit (e.g. if you have similarly shaped images this might also be useful in terms of CPU/RAM).\n/** * Generates a shadow for the source image and returns a new larger image containing the shadow * * @param source the source image for whom the shadow should be generated * @param blurRadius a shadow is blurred using a gaussian blur when available, a value of 10 is often satisfactory * @param opacity the opacity of the shadow between 0 - 1 where 1 is completely opaque * @param xDistance the distance on the x axis from the main image body in pixels e.g. a negative value will represent a lightsource from the right (shadow on the left) * @param yDistance the distance on the y axis from the main image body in pixels e.g. a negative value will represent a lightsource from the bottom (shadow on top) * @return a new image whose size incorporates x/yDistance */ public static Image dropshadow(Image source, int blurRadius, float opacity, int xDistance, int yDistance); /** * Generates a shadow for the source image and returns either the shadow itself or the image merged with the * shadow. * * @param source the source image for whom the shadow should be generated * @param blurRadius a shadow is blurred using a gaussian blur when available, a value of 10 is often satisfactory * @param opacity the opacity of the shadow between 0 - 1 where 1 is completely opaque * @return an image containing the shadow for source */ public static Image dropshadow(Image source, int blurRadius, float opacity); This can result in simple code to do a drop shadow effect:\nForm hi = new Form(\u0026quot;Drop Shadow\u0026quot;, new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER)); int twoMM = Display.getInstance().convertToPixels(2); Image img = duke.scaledWidth(Display.getInstance().getDisplayWidth() / 2); hi.add(BorderLayout.CENTER, new Label(Effects.dropshadow(img, 10, 0.8f, twoMM, twoMM), \u0026quot;Container\u0026quot;)); hi.show(); __ The variable duke is the image of the icon placed into the src directory Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbeck — September 11, 2016 at 9:46 am (permalink) beck says:\nWe can use the shadow effect in img only or in the components as well. eg I have a blue background container. Can i have the shadow effect in this container as well?\nShai Almog — September 12, 2016 at 4:17 am (permalink) Shai Almog says:\nIf the background of the container is fixed you can draw the image with the background then create a shadow for that and place everything in a layered layout.\nBayu Sanjaya — September 12, 2016 at 1:09 pm (permalink) Bayu Sanjaya says:\ncan you give us an example for shadowed container?\nShai Almog — September 13, 2016 at 3:47 am (permalink) Shai Almog says:\nContainers are transparent by default so doing this generically isn’t necessarily ideal. It might also pose a problem if the container is scrollable or if it reflows (e.g. on rotation). I would suggest doing this for individual components within the container. Just paint the component on an image and use that as the shadow base then do something like LayeredLayout.encloseIn(new Label(myShadow), myComponent)\nAli Ahmadur Rahman — August 5, 2018 at 8:42 pm (permalink) Ali Ahmadur Rahman says:\nNice tutorial. Hope to get more from you.\nMartin Brook — October 28, 2018 at 10:17 am (permalink) Martin Brook says:\nGreat article. thanks a lot for sharing with us.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/in-the-shadow/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/in-the-shadow/dropshadow.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://twitter.com/diamondobama\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDiamond\u003c/a\u003e asked us about an easy way to do dropshadows in Codename One to which I answered that it’s pretty easy thanks to our \u003ca href=\"/blog/toastbar-gaussian-blur.html\"\u003eGaussian blur support\u003c/a\u003e…​\u003c/p\u003e\n\u003cp\u003eWe ended up with this code which is usable but probably not as intuitive for most:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eForm hi = new Form(\u0026quot;Drop Shadow\u0026quot;, new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER));\n\nFontImage mm = FontImage.createMaterial(FontImage.MATERIAL_PERSON, \u0026quot;Button\u0026quot;, 30);\nint[] rgb = mm.toImage().getRGB();\nfor(int iter = 0 ; iter \u0026lt; rgb.length ; iter++) {\n    rgb[iter] = rgb[iter] \u0026amp; 0xff000000;\n}\nImage shadow = Image.createImage(rgb, mm.getWidth(), mm.getHeight());\nif(Display.getInstance().isGaussianBlurSupported()) {\n    shadow = Display.getInstance().gaussianBlurImage(shadow, 10);\n}\n\nLabel top = new Label(mm, \u0026quot;Container\u0026quot;);\nLabel bottom = new Label(shadow, \u0026quot;Container\u0026quot;);\nbottom.getAllStyles().setMargin(1, 0, 1, 0);\nbottom.getAllStyles().setMarginUnit(Style.UNIT_TYPE_DIPS);\nhi.add(BorderLayout.CENTER, LayeredLayout.encloseIn(bottom, top));\n\nhi.show();\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThe effect is attractive and commonplace so I think it would be great to add it universally so we added two methods which will be a part of the coming update. These methods are in the \u003ccode\u003eEffects\u003c/code\u003e class and are both simple utility methods. Once creates a shadow and incorporates it into a new image at the given location. The other returns the shadow alone which you can shift/position as you see fit (e.g. if you have similarly shaped images this might also be useful in terms of CPU/RAM).\u003c/p\u003e","title":"In the Shadow"},{"content":"\nWe will make another attempt to migrate to the new xcode 7.x build servers this Sunday. This might introduce some disruptions to your iOS builds but those should be fixable.\nOne of the stackoverflow discussions below sparked an interesting group discussion about improving the UI design of a Codename One app. If you feel your app could use a design/UX improvement feel free to post it to the forum. We are no substitute to a proper UX/UI designer but having worked on a lot of apps we might be able to help a bit with some feedback/ideas.\nOur updated release from this week contains some bug fixes but nothing groundbreaking.\nOnwards to the questions on stackoverflow:\nRounded URLImage not displaying It would be great if we could find a way to workaround this so it would throw an exception.\nRead on stackoverflow…​\nGet current Date without time on CN1 Date/time is painful. I wish we did have JSR310, ideally we’ll port it to Codename One at some point.\nRead on stackoverflow…​\nVirtual keyboard not getting displayed in android device You can’t really customize virtual keyboards on native devices unless you replace them completely which isn’t very portable…​\nRead on stackoverflow…​\nHandle clicks on Image in ImageViewer (Codenameone) We don’t provide an action listener on the ImageViewer because it is not a button…​\nRead on stackoverflow…​\nValidator not highlighting required fields Validator appends Invalid to the end of the UIID’s. Make sure to define the *Invalid UIID in the theme.\nRead on stackoverflow…​\nFacebook login not being fired on Android This was a regression related to the intent issue mentioned below\nRead on stackoverflow…​\nBackground fetch not firing on ios Features related to background execution are sensitive so it’s important to verify that everything in the iOS stop() method is correct…​\nRead on stackoverflow…​\nAre there \u0026ldquo;helpers\u0026rdquo; in Codename One to write Material Design apps as in Android There are several classes that provide material design look in Codename One but the most important thing to do is understand the goals\nRead on stackoverflow…​\nAre there \u0026ldquo;helpers\u0026rdquo; in Codename One to write Material Design apps as in Android Apple Developer and AppStore Cert Not generated in codename one There was a certificate generation regression this week due to changes made on Apples website. We later resolved those and this should be working again…​\nRead on stackoverflow…​\nScrollbars recently appeared I’m not sure why this workaround might be necessary\nRead on stackoverflow…​\nRemove sidemenubar from screen(form) SideMenuBar.closeCurrentMenu() is sometimes unintuitive…​\nRead on stackoverflow…​\nLimit size of an image (up to 1 MB) while uploading You can’t do that. The only thing you can do is save, check size rinse repeat…​\nRead on stackoverflow…​\nHow to post JSON to a REST webservice in codenameone The postRequest() method name is confusing…​\nRead on stackoverflow…​\nWill Codename one application work with Appium? Probably not. But we’d like to.\nIf you are an enterprise developer who would like to see this feature please contact us…​\nRead on stackoverflow…​\nHow to integrate ZXing source lib into my project so i not need to install ZXING App This was asked quite a few times and eventually Nick from littlemonkey got fed up with it and built his own cn1lib…​\nRead on stackoverflow…​\nDoes Codename one support Split Pane UI component? Not but it should be reasonably easy to build\nRead on stackoverflow…​\nSetting values to each comboBox item This question demonstrates exactly why we are moving away from List. Understanding that a model represents the logical value is pretty hard for developers…​\nRead on stackoverflow…​\nHow to get unique identification number of iphone iOS is generally resistant to such information, we have the UDID but since apps may depend on it we can’t provide better options today.\nRead on stackoverflow…​\nIntentResultListener not being called We had some issues with monitoring intents on Android that should be resolved now. This also impacted QR scanning and other issues\nRead on stackoverflow…​\nQrcode (zxing) scan successful but not returning to main form QR scanning had some issues on Android due to intent changes\nRead on stackoverflow…​\nCodeScanner not working This is the same question as the last one…​\nRead on stackoverflow…​\nBarcode scanning broken Because we shifted from regular scanning to the cn1lib etc. things might have broken in between. They work well in the latest version\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xx/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xx/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe will make another attempt to migrate to the \u003ca href=\"/blog/xcode-migration-take-2.html\"\u003enew xcode 7.x build servers\u003c/a\u003e this Sunday. This might introduce some disruptions to your iOS builds but those should be fixable.\u003c/p\u003e\n\u003cp\u003eOne of the stackoverflow discussions below sparked an \u003ca href=\"https://groups.google.com/d/msg/codenameone-discussions/baW-85V9d08/zItzsmmeDAAJ\" target=\"_blank\" rel=\"noopener noreferrer\"\u003einteresting group discussion\u003c/a\u003e about improving the UI design of a Codename One app. If you feel your app could use a design/UX improvement feel free to post it to the forum. We are no substitute to a proper UX/UI designer but having worked on a lot of apps we might be able to help a bit with some feedback/ideas.\u003c/p\u003e","title":"Questions of the Week XX"},{"content":"\nWe had almost everything ready for the release of the kitchen sink demo this week until one of our fixes broke the build and we couldn’t get everything out in time. It’s disappointing but this means one more week to refine the demo.\nDuring our debugging of the contacts demo that is a part of the new kitchen sink we noticed its performance was sub par. I assumed this was due to the implementation of getAllContacts \u0026amp; that there is nothing to do. While debugging another issue Steve noticed an anomaly during the loading of the contacts.\nHe then discovered that we are loading the same resource file over and over again for every single contact in the list!\nIn the new Contacts demo we have a share button for each contact, the code for constructing a ShareButton looks like this:\npublic ShareButton() { setUIID(\u0026quot;ShareButton\u0026quot;); FontImage.setMaterialIcon(this, FontImage.MATERIAL_SHARE); addActionListener(this); shareServices.addElement(new SMSShare()); shareServices.addElement(new EmailShare()); shareServices.addElement(new FacebookShare()); } This seems reasonable until you realize that the constructors for SMSShare, EmailShare \u0026amp; FacebookShare load the icons for each of those…​\nThese icons are in a shared resource file that we load and don’t properly cache. The initial workaround was to cache this resource but a better solution was to convert this code:\npublic SMSShare() { super(\u0026quot;SMS\u0026quot;, Resources.getSystemResource().getImage(\u0026quot;sms.png\u0026quot;)); } Into this code:\npublic SMSShare() { super(\u0026quot;SMS\u0026quot;, null); } @Override public Image getIcon() { Image i = super.getIcon(); if(i == null) { i = Resources.getSystemResource().getImage(\u0026quot;sms.png\u0026quot;); setIcon(i); } return i; } This way the resource uses lazy loading as needed.\nThis small change boosted the loading performance and probably the general performance due to less memory fragmentation.\nThe lesson that we should learn every day is to never assume about performance…​\nScroll Performance – Threads aren’t magic Another performance pitfall in this same demo came during scrolling. Scrolling was janky (uneven/unsmooth) right after loading finished would recover after a couple of minutes.\nThis relates to the images of the contacts.\nTo hasten the loading of contacts we load them all without images. We then launch a thread that iterates the contacts and loads an individual image for a contact. Then sets that image to the contact and replaces the placeholder image.\nThis performed well in the simulator but didn’t do too well even on powerful mobile phones. We assumed this wouldn’t be a problem because we used Util.sleep() to yield CPU time but that wasn’t enough.\nOften when we see performance penalty the response is: \u0026ldquo;move it to a separate thread\u0026rdquo;. The problem is that this separate thread needs to compete for the same system resources and merge its changes back into the EDT. When we perform something intensive we need to make sure that the CPU isn’t needed right now…​\nIn this and past cases we solved this using a class member indicating the last time a user interacted with the UI.\nHere we defined:\nprivate long lastScroll; Then we did this within the background thread\n// don't do anything while we are scrolling or animating long idle = System.currentTimeMillis() - lastScroll; while(idle \u0026lt; 1500 || contactsDemo.getAnimationManager().isAnimating() || scrollY != contactsDemo.getScrollY()) { scrollY = contactsDemo.getScrollY(); Util.sleep(Math.min(1500, Math.max(100, 2000 - ((int)idle)))); idle = System.currentTimeMillis() - lastScroll; } Notice that we also check if the scroll changes, this allows us to notice cases like the animation of scroll winding down.\nAll we need to do now is update the lastScroll variable whenever user interaction is in place. This works for user touches:\nparentForm.addPointerDraggedListener(e -\u0026gt; lastScroll = System.currentTimeMillis()); This works for general scrolling:\ncontactsDemo.addScrollListener(new ScrollListener() { int initial = -1; @Override public void scrollChanged(int scrollX, int scrollY, int oldscrollX, int oldscrollY) { // scrolling is sensitive on devices... if(initial \u0026lt; 0) { initial = scrollY; } lastScroll = System.currentTimeMillis(); ... } }); __ Due to technical constraints we can’t use a lambda in this specific case…​ Final Word Performance is a chase that never ends. Its non-trivial and always changes on device/between devices.\nThe nice thing about cross platform tools is that once you optimize something on Android this often maps back to iOS etc. giving you a nice cross platform boost.\nSome performance tips are generic and you can check them out in our developer guide but performance is basically application specific. We wouldn’t have seen the ShareButton issue since the overhead is so small. But once we used ShareButton in an app where we created hundreds of buttons it became an issue…​ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJérémy MARQUER — August 26, 2016 at 7:19 am (permalink) Jérémy MARQUER says:\nOne more time an interesting post …I feel particularly concerned by this performance problem because I’m using multiple threads in addition to EDT and network one. I have noticed that my application is affected by performance when there is a lot of components in a form (with images) on an IPAD 3 while it’s running very smoothly on IPAD AIR 2. I know that there is a huge difference between this 2 iPad but I have seen a lot of applications running smoothly on IPAD 3 …\nShai Almog — August 27, 2016 at 5:10 am (permalink) Shai Almog says:\nThanks.\nNotice that this behavior affects native code too, it’s mostly about stealing CPU from the rendering thread.\nWe tried several workarounds in the past such as reducing the CPU priority of the network/auxiliary threads but that wasn’t very effective. We already have some API’s designed to indicate that CPU is needed for animation but they aren’t exposed, I think we need to offer something like this as a standard API but I need to give this some thought…\nCarlos — March 10, 2017 at 6:21 pm (permalink) Carlos says:\nThank you. I had a similar performance issue due to loading images in a scrolling component. The scrolling was really bad during some seconds even in a very powerful device. I solved it by loading every image in a separate thread, now it works fine. It would be indeed helpful to have an api for this.\nShai Almog — March 11, 2017 at 6:14 am (permalink) Shai Almog says:\nI’ve had a similar thought when I wrote this up but I can’t think of an API that would be generic enough to implement this pattern intelligently and intuitively.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/performance-true-story/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/performance-true-story/phone-espresso.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe had almost everything ready for the release of the kitchen sink demo this week until one of our fixes broke the build and we couldn’t get everything out in time. It’s disappointing but this means one more week to refine the demo.\u003c/p\u003e\n\u003cp\u003eDuring our debugging of the contacts demo that is a part of the new kitchen sink we noticed its performance was sub par. I assumed this was due to the implementation of \u003ccode\u003egetAllContacts\u003c/code\u003e \u0026amp; that there is nothing to do. While debugging another issue Steve noticed an anomaly during the loading of the contacts.\u003c/p\u003e","title":"Performance True Story"},{"content":"\nOne of the first Codename One performance tips is: \u0026ldquo;Don’t use gradients\u0026rdquo;. We already wrote about improved performance to gradients in the past but that covered linear gradients and didn’t cover radials on iOS.\nWith recent commits radial gradients are now performant on iOS/Android and elsewhere. On iOS Steve implemented gradients as a shader which should deliver great performance.\nI’m not sure if this is good enough to deliver the level of performance we see from image borders and it’s harder to work with low level graphics primitives.\nI think the old assessments still stand. Gradients perform better so it might not be a problem to use them, but I would still use \u0026amp; recommend images over them.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/performant-radial-gradients/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/performant-radial-gradients/gradients.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the first Codename One performance tips is: \u0026ldquo;Don’t use gradients\u0026rdquo;. We already \u003ca href=\"/blog/should-we-use-gradients.html\"\u003ewrote about improved performance to gradients\u003c/a\u003e in the past but that covered linear gradients and didn’t cover radials on iOS.\u003c/p\u003e\n\u003cp\u003eWith recent commits radial gradients are now performant on iOS/Android and elsewhere. On iOS Steve implemented gradients as a shader which should deliver great performance.\u003c/p\u003e\n\u003cp\u003eI’m not sure if this is good enough to deliver the level of performance we see from image borders and it’s harder to work with low level graphics primitives.\u003c/p\u003e","title":"Performant Radial Gradients"},{"content":"\nA lot of our focus in the past couple of releases has been around the material design icon fonts, they changed the way we build UIs. We also support arbitrary font icons, this features isn’t limited to material icons and we blogged about it a while back.\nAfter going back and forth with developers we got the sense that using an icon font such as fontello wasn’t clear. In this short tutorial we’ll try to explain the process and benefits.\n__ | On an unrelated note, if you haven’t upvoted our stackoverflow ad please do this now \u0026amp; help us promote Codename One!\nClick on the up arrow next to the ad if you have a stackoverflow account. Why Icon Font \u0026amp; Not MultiImage? Both have their place. When in doubt I would pick an icon font as it allows us to adapt the colors dynamically. It can even change the color based on state (e.g. different icon color for pressed/released state).\nAnother big advantage for icon fonts is application size which can be small. Some designs aren’t achievable with icon fonts in which case there is no other option.\nGetting Started Go to the icon font website e.g. fontello.com and select the icons you want.\n__ Notice the license terms for each font as fontello might mix different font licenses! Once you picked the desired icons click the download button and save/extract the font zip file.\nFigure 1. Fontello website with icon selection\nOnce you unzip the file copy the fontello.ttf file to the src directory in your project. Then open the demo.html file in the browser. Click the show codes checkbox on the top right side and you should see something like this:\nFigure 2. Fontello demo html file\nIf you look at the symbols you will notice they are hex values, e.g. notice the heart symbol in my font matches 0xe809. This would be the value for the FontImage when we create it, you can convert it to Java syntax with the u notation as ue809;\nE.g. I can create a 4mm red heart icon using:\nFont fnt = Font.createTrueTypeFont(\u0026quot;fontello\u0026quot;, \u0026quot;fontello.ttf\u0026quot;); int size = Display.getInstance().convertToPixels(4); FontImage fm = FontImage.createFixed(\u0026quot;ue800\u0026quot;, fnt, 0xff0000, size, size); A better approach would use styles. We can define UIID’s in the designer and pick fontello.ttf from the combobox of fonts as such:\nFigure 3. Using styles for icon fonts is the best way to define icon fonts\nOnce you define a style in the theme it’s easy to keep it consistent with everything else. E.g. I can change the code above to create a red heart like this:\nStyle s = UIManager.getInstance().getComponentStyle(\u0026quot;RedIcon\u0026quot;); FontImage fm = FontImage.createFixed(\u0026quot;ue800\u0026quot;, s); We can also create a selected variation using getComponentSelectedStyle:\nStyle s = UIManager.getInstance().getComponentSelectedStyle(\u0026quot;RedIcon\u0026quot;); FontImage fm = FontImage.createFixed(\u0026quot;ue800\u0026quot;, s); And the pressed version using getComponentCustomStyle:\nStyle s = UIManager.getInstance().getComponentCustomStyle(\u0026quot;RedIcon\u0026quot;, \u0026quot;press\u0026quot;); FontImage fm = FontImage.createFixed(\u0026quot;ue800\u0026quot;, s); Final Word We love flat design, it made font icons pervasive and those are easy to work with. Once you pick them up you will find it hard to stop using them.\nIf you have any thoughts on how to make the font image API’s easier to use let us know…​ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\n3lix — August 23, 2016 at 4:39 pm (permalink) Hi, I noticed with the material design support , the back button (more so the back command) now has a ripple effect when clicked, but not the hamburger menu (at least testing on android).\nCan I add this ripple effect to any button in general , or icon ? If so, I would like to know how.\nThanks!\nShai Almog — August 24, 2016 at 3:54 am (permalink) This isn’t ripple, it’s a pressed color. Did you define the theme constant sideMenuImage?\nIf so try removing it and see if the pressed color for the item changes.\n3lix — August 24, 2016 at 3:23 pm (permalink) I believe that what I am seeing on my device is a ripple effect. The background button has a circular background The background color for the back button when clicked / long pressed changes gradually starting from the center down to the circle’s edges over about a half a second time period.\nIf it was just a background color that is set when clicked then it would not change \u0026ldquo;gradually\u0026rdquo; it would instead get updated all at once.\nI will try this week to recreate this behavior from a bare bone app and share it. I see the ripple effect only on an android device.\nThe ripple effect is not a necessity to me at this point. But I do see the effect supported somehow already. I will test more this afternoon.\nShai Almog — August 25, 2016 at 5:23 am (permalink) Shai Almog says:\nIf I understand you correctly you are using an older project with a native theme. This means you aren’t using the Toolbar and are using the native ActionBar which is an approach we moved away from.\nSince that is a native component it will have the native ripple effect.\n3lix — August 25, 2016 at 2:38 pm (permalink) 3lix says:\nI see that makes sense now. I was not using the toolbar on that specific form. Also you are right I don’t see the effect if I use the Toolbar.\nI actually used \u0026ldquo;Form\u0026rdquo;.setBackCommand(backCommand Also I am not using a native theme but I think probably due to the way I am using the theme it is indeed using the native component.\nThank you for the insights and for your time! I understand what is going on now.\nCh Hjelm — April 13, 2019 at 9:51 am (permalink) Ch Hjelm says:\nHi, I would like to start using external Icon fonts in addition to the CN1 Material font. Is there some way to use external fonts as easily as the built-in Material icons, e.g. use them in Label.setMaterialIcon()? A method like setMaterialIcon() is really practical because it automatically sets size and color of the icon as defined by the Label UIID style, but it currently seems to have hard-coded support for the predefined CN1 Material icons only?\nShai Almog — April 14, 2019 at 3:57 am (permalink) Shai Almog says:\nThat would be great but I’m not sure how we can enable something like that in terms of the API?\nOne of the ideas that floated around when we introduced FontImage was to create it in an \u0026ldquo;auto-adapt\u0026rdquo; mode so it will use component styles all the time. This makes the code a bit awkward as you’d need to create multiple FontImage instances and won’t be able to reuse them.\nThe material code is easy to do because we just pass the character and possibly the size. Here we’d need the additional information of the font which changes the balance a bit. If you have a suggestion of how the API should look I’d be interested in hearing that.\nCh Hjelm — April 14, 2019 at 9:07 am (permalink) Ch Hjelm says:\nI’m not much into the inner workings of CN1 but the external api could maybe be something like Label.setFontIcon(Font font, char icon).\nI can see that FontImage.setMaterialIcon((Label l, char icon, float size) calls getMaterialDesignFont() to get the Material font, so if that font could somehow be passed as a parameter instead, maybe that would do trick.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/using-icon-fonts-such-as-fontello/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/using-icon-fonts-such-as-fontello/font-awesome.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA lot of our focus in the past couple of releases has been around the material design icon fonts, they changed the way we build UIs. We also support arbitrary font icons, this features isn’t limited to material icons \u003ca href=\"/blog/icon-fonts-oldvm-swan-song.html\"\u003eand we blogged about it a while back\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eAfter going back and forth with developers we got the sense that using an icon font such as fontello wasn’t clear. In this short tutorial we’ll try to explain the process and benefits.\u003c/p\u003e","title":"Using Icon Fonts Such as Fontello"},{"content":"\nWhen picking up a new UI API people often start with a list of items. Lists are often used for navigation, logic and data so it’s a natural place to start. Codename One’s List class is a bad place to start though…​ It’s complex and encumbered and has far better alternatives.\nHow did we Get Here? When we initially created the List API we were heavily inspired by Swing’s architecture. The ability to create an infinitely sized list without a performance penalty was attractive and seemed like a good direction for our original 2mb RAM target devices (back in 2006-7). We knew the renderer/model approach was hard for developers to perceive but we also assumed a lot of Swing developers would find it instantly familiar.\nWe made attempts to improve List in the years since e.g.: MultiList, GenericListCellRenderer, ContainerList etc.\nThese helped but the core problems of List remain.\nWhat Changed? Modern interfaces are far more dynamic, we have features such as swipable containers, drag and drop to rearrange etc. The renderer approach complicates trivial tasks e.g.:\nVariable sized entries – this is impossible in a standard List or MultiList. We designed ContainerList to solve this but it’s both ridiculously inefficient and buggy\nMore than one clickable item per row – it’s common to have more than one item within a row in the List that can handle an event. E.g. a delete button. This is a difficult (albeit possible) task for List items.\nPerformance – List can perform well but writing performant List code is a challenge. Anything under 5000 entries would perform better with alternative solutions. If you need more than 5000 rows, reconsider…​\nScrolling beyond 1000 rows on a mobile device is challenging.\nCustomizability – You can customize the look of the List component but there are nuances and some limits.\nModel – MVC is a good idea but it’s hard. Features like dynamic image download in lists challenge even experienced Codename One developers.\nWhat Should we use Instead? This varies based on your needs but the general answer is a scrollable BoxLayout.Y_AXIS container.\nThe Simple Use Case E.g. if I write a simple List such as this:\ncom.codename1.ui.List\u0026lt;String\u0026gt; lst = new com.codename1.ui.List\u0026lt;String\u0026gt;(\u0026quot;A\u0026quot;, \u0026quot;B\u0026quot;, \u0026quot;C\u0026quot;); lst.addActionListener(e -\u0026gt; Log.p(\u0026quot;You picked: \u0026quot; + lst.getSelectedItem())); I can convert it to this:\nString[] abc = new String[] {\u0026quot;A\u0026quot;, \u0026quot;B\u0026quot;, \u0026quot;C\u0026quot;}; Container list = new Container(BoxLayout.y()); list.setScrollableY(true); for(String s : abc) { Button b = new Button(s); list.add(b); b.addActionListener(e -\u0026gt; Log.p(\u0026quot;You picked: \u0026quot; + b.getText())); } Admittedly there is more code in the second version, but it’s far more powerful and as your UI design grows the code will shrink by comparison!\nE.g. if you don’t want the default look of the list or want thumbnail image, or want a single entry to behave differently the latter option is far simpler.\nLead Component When you click an entry within the list you can click anywhere and it will work. If you compose an entry in the list from more than one piece those pieces act as one.\nE.g. we have this code in the developer guide section covering List renderers:\nclass ContactsRenderer extends Container implements ListCellRenderer { private Label name = new Label(\u0026quot;\u0026quot;); private Label email = new Label(\u0026quot;\u0026quot;); private Label pic = new Label(\u0026quot;\u0026quot;); private Label focus = new Label(\u0026quot;\u0026quot;); public ContactsRenderer() { setLayout(new BorderLayout()); addComponent(BorderLayout.WEST, pic); Container cnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); name.getAllStyles().setBgTransparency(0); name.getAllStyles().setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_MEDIUM)); email.getAllStyles().setBgTransparency(0); cnt.addComponent(name); cnt.addComponent(email); addComponent(BorderLayout.CENTER, cnt); focus.getStyle().setBgTransparency(100); } public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected) { Contact person = (Contact) value; name.setText(person.getName()); email.setText(person.getEmail()); pic.setIcon(person.getPic()); return this; } public Component getListFocusComponent(List list) { return focus; } } We can create a similar container using this approach:\nContainer list = new Container(BoxLayout.y()); list.setScrollableY(true); for(Contact c : contacts) { list.add(createContactContainer(c)); } private Container createContactContainer(Contact person) { Label name = new Label(\u0026quot;\u0026quot;); Label email = new Label(\u0026quot;\u0026quot;); Label pic = new Label(\u0026quot;\u0026quot;); Container cnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); name.getAllStyles().setBgTransparency(0); name.getAllStyles().setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_MEDIUM)); email.getAllStyles().setBgTransparency(0); cnt.add(name); cnt.add(email); name.setText(person.getName()); email.setText(person.getEmail()); pic.setIcon(person.getPic()); return BorderLayout.center(cnt). add(BorderLayout.EAST, pic); } The problem with this approach becomes obvious when we try to add an event listener…​.\nWe can make name into a Button but then what happens when a user clicks email?\nWe can make all the entries into buttons but that isn’t practical. That’s what lead component is for, we can make one component into a button and it \u0026ldquo;takes the lead\u0026rdquo;. If we make name into a button and set it as the lead of the Container it will handle all the events and state changes for the entire row!\n__ For more information on lead components check out the sidebar in the developer guide. We can change the code above like this and support lead components:\nprivate Container createContactContainer(Contact person) { Button name = new Button(\u0026quot;\u0026quot;, \u0026quot;Label\u0026quot;); name.addActionListener(e -\u0026gt; Log.p(\u0026quot;You clicked: \u0026quot; + person)); // ... Container b = BorderLayout.center(cnt). add(BorderLayout.EAST, pic); b.setLeadComponent(name); return b; } __ | What do you do if you want to exclude an item from the lead component hierarchy (e.g. a delete button)?\nCheck out this blog post. Infinite Scroll One of our earliest demos showed off a million entries running on a 3mb Nokia mobile phone. While that is an impressive feat it isn’t useful.\nMost real world UI’s use pagination to fetch more data when they reach the bottom of the scroll. This is predictable and easy to integrate both in the client and server code.\nTwo classes simplify the process of infinite scrolling list: InfiniteContainer and InfiniteScrollAdapter.\nInfiniteContainer is an easy to use drop-in replacement to Container. InfiniteScrollAdapter is more versatile, you can apply it to any Container including the content pane. We have samples for both InfiniteContainer and InfiniteScrollAdapter in the JavaDocs.\nDon’t Use Lists In closing I’d like to re-iterate our recommendation: \u0026ldquo;Don’t use lists\u0026rdquo;. We didn’t deprecate those API’s because developers rely heavily on them \u0026amp; this might induce \u0026ldquo;panic\u0026rdquo;.\nThere’s no valid reason to use a List as opposed to a Container. List is harder to use, slower \u0026amp; not as flexible.\nWe can’t cover every conceivable use case in this post so if you have a List or code you can’t imagine any other way, post it in the comments below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — August 22, 2016 at 9:14 pm (permalink) bryan says:\nAgree with all this. I originally used Lists with custom cell renderers, and with the deprecation of the old GUI builder, I took the opportunity to refactor my code and change all Lists to Containers. Initially my thoughts were \u0026ldquo;it can’t work as well\u0026rdquo;, but in fact there appears to be zero performance penalty, and as Shai says, you can create a much better UI experience. Don’t use Lists !\nSadart — August 23, 2016 at 4:31 am (permalink) Sadart says:\nTrue. Lists are horrible to deal with. I am still trying to recall when I used them. Stayed away from them years ago because stacking up containers made sense to me.\nJérémy MARQUER — August 23, 2016 at 7:35 am (permalink) Jérémy MARQUER says:\nTotally agree and happy to read this post !! I initially work with complex List but I have refactored it recently. For example, I InfiniteProgress doesn’t animate correctly in items of my List -\u0026gt; I have changed it to InfiniteContainer and it works better !!\nShai Almog — August 24, 2016 at 3:58 am (permalink) Shai Almog says:\nA user posted a question about searching within a list using the filter proxy model. That’s a great question that he seems to have deleted…\nThe Toolbar JavaDoc contains two samples of searching within a container: https://www.codenameone.com…\nWhich also shows off animation within the search and quite a few other nice things. Notice that this isn’t demonstrated with an infinite container because searching thru that would require fetching all the data which might not be what you want to do so you will need to adapt the code to work with fetch logic (e.g. special webservice call for search like we do in property cross).\nCarlos — August 24, 2016 at 8:09 am (permalink) Carlos says:\nI did not delete the post, I have no idea what happened with it. Anyway, this is the code I posted before (thank you for the samples):\ntextoFiltro.addDataChangeListener((int type, int index) -\u0026gt; {\nfiltraProxy(listaRecetas, textoFiltro);\n});\n……..\nprivate void filtraProxy(final List listaRecetas, TextField textoFiltro) {\nForm f = Display.getInstance().getCurrent();\nFilterProxyListModel listaFiltro;\nif (listaRecetas.getModel() instanceof FilterProxyListModel) {\nlistaFiltro = (FilterProxyListModel) listaRecetas.getModel();\n} else {\nif(textoFiltro.getText().length() == 0) {\nreturn;\n}\nlistaFiltro = new FilterProxyListModel(listaRecetas.getModel()) {\n@Override\nprotected boolean check(Object o, String str) {\nHashtable h = (Hashtable) o;\nObject textoHash = h.get(\u0026ldquo;Listado\u0026rdquo;);\nreturn super.check(textoHash, str);\n}\n};\nlistaRecetas.setModel(listaFiltro);\n}\nif (textoFiltro.getText().length() == 0) {\nlistaRecetas.setModel(listaFiltro.getUnderlying());\n} else {\nlistaFiltro.filter(textoFiltro.getText());\n}\nf.revalidate();\n}\nShai Almog — August 25, 2016 at 5:21 am (permalink) Shai Almog says:\nOdd. I’ve seen messages disappear before but I always assumed they were deleted by the asker…\nJeff Crump — September 1, 2016 at 5:44 pm (permalink) Jeff Crump says:\nI would prefer to continue to use the existing List class. When I first started to use Codename One I created an extend List class that utilizes a separate listmodel class, a multi-threaded downloader class, and a renderer class (which generates a prototype). I am able to place buttons, text and other components in the renderer class and have it manage states, mutable backgrounds and pass events to handle unique responses. The downloader class initially pulls two pages of images, then as the list scrolls it downloads additional pages, four at a time, then pauses until the next scroll. The list model class only fires an update when the image is still visible. My ListModel class also implements static filters on the data as the model is instantiated. All of my lists reside on tabs and work/scroll very well. The downloader class uses a two tier thread safe CacheMap. It easily handles 5,000 cells as the cell cache scrolls both directions. It is very fast and doesn’t suffer from pauses or jerky responses.\nShai Almog — September 2, 2016 at 5:16 am (permalink) Shai Almog says:\nThat might be one of the rare use cases for which list is indeed still superior.\nI think it’s pretty rare because navigating 5000 entries on mobile devices is probably too much for users and obviously the effort you had to put to get it going was pretty big… That’s the gist of this post. Yes there are edge cases that list can handle well but they are edge cases.\nJeff Crump — September 2, 2016 at 12:52 pm (permalink) Jeff Crump says:\nI know, I just didn’t want to lose the existing List component. I wrote most of my code during the first few months after I started using Codename One. It was still very new and I had decided to go with it as is. So I added in what I wanted and worked around the rest. There have been many new components and upgrades since then and it has become a very capable platform. While we have tested very large lists, our target is actually about 500, and with the internal filters the length is between 65 and 85.\nkhmaies hassen — April 20, 2017 at 10:32 pm (permalink) khmaies hassen says:\nwhen i reach the end of the list where there are no new pages to show and then i go up and pull the list to refresh, it gives me an empty page. how to reset \u0026ldquo;pageNumber\u0026rdquo; to 1 when i use pull to refresh?\nShai Almog — April 21, 2017 at 4:44 am (permalink) Shai Almog says:\nIn infinite container?\nPlace a breakpoint in your callback code and make sure you return the right value on every call\nkhmaies hassen — April 21, 2017 at 8:58 am (permalink) khmaies hassen says:\nEven in your example the same thing happenes when you reach the end\nShai Almog — April 22, 2017 at 8:24 am (permalink) Shai Almog says:\nWhich example\nkhmaies hassen — April 22, 2017 at 12:22 pm (permalink) khmaies hassen says:\nhttps://www.codenameone.com…\nShai Almog — April 23, 2017 at 5:33 am (permalink) Shai Almog says:\nI think that’s code that originally relied on InfiniteScrollAdapter which has no pull to refresh or index… You need to use the index value to determine the page you are on with InfiniteContainer\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/avoiding-lists/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/avoiding-lists/property-cross-new.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen picking up a new UI API people often start with a list of items. Lists are often used for navigation, logic and data so it’s a natural place to start. Codename One’s List class is a bad place to start though…​ It’s complex and encumbered and has far better alternatives.\u003c/p\u003e\n\u003ch3 id=\"how-did-we-get-here\"\u003eHow did we Get Here?\u003c/h3\u003e\n\u003cp\u003eWhen we initially created the \u003ccode\u003eList\u003c/code\u003e API we were heavily inspired by Swing’s architecture. The ability to create an infinitely sized list without a performance penalty was attractive and seemed like a good direction for our original 2mb RAM target devices (back in 2006-7). We knew the renderer/model approach was hard for developers to perceive but we also assumed a lot of Swing developers would find it instantly familiar.\u003c/p\u003e","title":"Avoiding Lists"},{"content":"\nIt’s cucumber season, there is little going on around here and elsewhere. Stackoverflow mirrors this general trend with seasonal low activity. Our update to the build servers today includes a lot of fixes but is still tame compared to the last update.\nOnwards to the questions on stackoverflow:\nCannot edit new locale in Codename One IntelliJ plugin This is a bug in the current version of the plugins. A workaround is described in the answer…​\nRead on stackoverflow…​\nSome numbers in the application version are not taken into account We simplified version numbers for portability but some edge cases with floating point behavior haunted us in the past\nRead on stackoverflow…​\nBuild Canceled By User on BLE example Sometimes we accidentally commit bad build.xml files from local development. To workaround this we automatically cancel broken builds.\nRead on stackoverflow…​\nHTC Performance Issue with CodeNameOne App? Debugging performance issues is always a pain. We noticed that a lot of times a bug or exception was incorrectly classified as a performance issue. That is why you need to provide as much measurement and information as possible when discussing performance.\nRead on stackoverflow…​\nHow to handle exception java.net.ConnectionException explicitly Error handling in networking isn’t always the most intuitive thing, and although we cover it a lot it’s still confusing.\nRead on stackoverflow…​\nDatabase object was released by the GC without being closed first iOS is sensitive to threading issues within SQL access code.\nRead on stackoverflow…​\nMove the marker to selected location on MapContainer Events in native widgets should be handled by the native widget itself.\nRead on stackoverflow…​\nVirtual keyboard ios \u0026ldquo;done\u0026rdquo; button and toolbar disappears Some of the virtual keyboard flags are a bit unintuitive.\nRead on stackoverflow…​\nHow to add an ArcProgress (lib) to the TitleBar in codename one If you are struggling with an effect please provide code and images to clarify the issue\nRead on stackoverflow…​\nImageViewer isn’t working fine URLImage doesn’t work well with the ImageViewer, there are some conflicting concepts there.\nRead on stackoverflow…​\nHow to get the mobile number of current sim card in real device? This is a pretty common FAQ and the answer is always the same:\nNotice that apps like whatsapp, uber, gettaxi etc. all ask you to type in your phone number then a verification code sent via an SMS…​\nRead on stackoverflow…​\nDifference in GoogleMaps rendering We generally recommend people use native maps as they look much better on the device. Unless there is some restriction or requirement this is probably the best approach.\nRead on stackoverflow…​\nHamburger Icon and Overflow Menu Size Some customizations are harder to figure out without looking at the code, in most cases documentation exists but finding it might be challenging.\nRead on stackoverflow…​\nShow blank google maps The maps situation in Codename One is a bit confusing with native maps, the lightweight maps and even HTML maps which we haven’t promoted as for most purposes the native maps would be better.\nRead on stackoverflow…​\nCodenameOne background task for BluetoothLe connection Background location is pretty difficult to get right in cross platform solutions.\nRead on stackoverflow…​\nGetting Locations Best Practice Under normal circumstances we treat location as hybrid location where available (Android/iOS). In Android there are some nuances with Google play services.\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xix/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xix/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIt’s \u003ca href=\"http://ubiquity.acm.org/article.cfm?id=1088429\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ecucumber season\u003c/a\u003e, there is little going on around here and elsewhere. Stackoverflow mirrors this general trend with seasonal low activity. Our update to the build servers today includes a lot of fixes but is still tame compared to the last update.\u003c/p\u003e\n\u003cp\u003eOnwards to the questions on stackoverflow:\u003c/p\u003e\n\u003ch3 id=\"cannot-edit-new-locale-in-codename-one-intellij-plugin\"\u003eCannot edit new locale in Codename One IntelliJ plugin\u003c/h3\u003e\n\u003cp\u003eThis is a bug in the current version of the plugins. A workaround is described in the answer…​\u003c/p\u003e","title":"Questions of the Week XIX"},{"content":"\nI hoped todays post would cover the new Kitchen Sink demo but due to a couple of bugs we decided to postpone that to next week. In the meantime I’d like to discuss something I did there which is actually pretty cool and most developers have no idea that we can do: Image Overriding.\nThe new kitchen sink renders a set of icons like the old demo. In this version of the demo we wanted to show off graphics drawing which is an important feature missing from the old demo. Steve’s clock demo is a great example of that!\nWhen the time came to create an icon for that demo it dawned on us that it would be cool if the clock icon was actually \u0026ldquo;live\u0026rdquo;. We decided to create an Image in code that draws everything dynamically. Yes, we could have used a Painter but that would have meant reworking a lot of the existing code, the same would have been true if we used another component.\nThis is the code we used to create a clock, I’m redacting the clock drawing code itself for brevity’s sake:\nclass ClockImage extends Image { int w = 250, h = 250; ClockImage() { super(null); } ClockImage(int w, int h) { super(null); this.w = w; this.h = h; } @Override public int getWidth() { return w; } @Override public int getHeight() { return h; } @Override public void scale(int width, int height) { w = width; h = height; } @Override public Image fill(int width, int height) { return new ClockImage(width, height); } @Override public Image applyMask(Object mask) { return new ClockImage(w, h); } @Override public boolean isAnimation() { return true; } @Override public boolean requiresDrawImage() { return true; } @Override protected void drawImage(Graphics g, Object nativeGraphics, int x, int y) { paintClock(g, x, y, w, h, x + g.getTranslateX(), y + g.getTranslateY()); } @Override protected void drawImage(Graphics g, Object nativeGraphics, int x, int y, int w, int h) { paintClock(g, x, y, w, h, x + g.getTranslateX(), y + g.getTranslateY()); } @Override public boolean animate() { if (System.currentTimeMillis() / 1000 != lastRenderedTime / 1000) { currentTime.setTime(System.currentTimeMillis()); return true; } return false; } }; That is it!\nNotice that the image must declare itself as an animation and then override animate() to invoke drawImage. Also notice the method requiresDrawImage which disables some builtin image optimizations that we can perform in the native layer that might break this.\nThis is how we built FontImage within our code and we might do more of this as we move forward to allow more vector graphics primitives.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/image-overriding/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/image-overriding/clock-image.gif\"\u003e\u003c/p\u003e\n\u003cp\u003eI hoped todays post would cover the new Kitchen Sink demo but due to a couple of bugs we decided to postpone that to next week. In the meantime I’d like to discuss something I did there which is actually pretty cool and most developers have no idea that we can do: Image Overriding.\u003c/p\u003e\n\u003cp\u003eThe new kitchen sink renders a set of icons like the old demo. In this version of the demo we wanted to show off graphics drawing which is an important feature missing from the old demo. Steve’s clock demo is a great example of that!\u003c/p\u003e","title":"Image Overriding"},{"content":"\nWe tried migrating to the new iOS build servers before and decided to revert the change due to xcode crashes. After a lot of work we think the new server code is ready for production. We will try to migrate to these new servers again on the 28th of August (Sunday) to minimize impact if something goes horribly wrong.\nIf you read the old post covering the iphone_new build target you can skip the rest of the post as it’s pretty much the same.\nApple allows you to run an older version of xcode, but the newer versions of xcode always require the latest version of Mac OS X. The problem here is that the latest version of Mac OS X doesn’t support older versions of xcode so if we upgrade we won’t be able to support older versions of the build…​\nThis shouldn’t be a problem, we already run fine on the latest version of xcode without a problem. However, you might inadvertently have relied on some behaviors or functionality of the old xcode e.g. thru native code, third party cn1lib or slight behavior variation.\nThis means that once we upgrade there is no way to turn back. We’ll need to update the OS’s of the build servers and do this consistently so you will get consistent build results. This would also mean that some aspects of versioned builds might not handle all cases as the new iOS build servers won’t have the older version\nof xcode in place.\nThe Migration Plan We’ve setup a new build server as a \u0026ldquo;test pilot\u0026rdquo; to see that builds go thru as planned. You can/should test your app to see if it will work, please let us know if there are issues!\n__ If you don’t do this we will not be able to go back! To test your app on the test pilot build server open the build.xml and search for the string \u0026quot;iphone\u0026quot; with the quotes.\nReplace it with \u0026quot;iphone_new\u0026quot; .\nE.g. notice the targetType=\u0026quot;iphone_new\u0026quot; line below:\n\u0026lt;target name=\u0026quot;build-for-ios-device\u0026quot; depends=\u0026quot;clean,copy-ios-override,copy-libs,jar,clean-override\u0026quot;\u0026gt; \u0026lt;codeNameOne jarFile=\u0026quot;${dist.jar}\u0026quot; displayName=\u0026quot;${codename1.displayName}\u0026quot; packageName = \u0026quot;${codename1.packageName}\u0026quot; mainClassName = \u0026quot;${codename1.mainName}\u0026quot; version=\u0026quot;${codename1.version}\u0026quot; icon=\u0026quot;${codename1.icon}\u0026quot; vendor=\u0026quot;${codename1.vendor}\u0026quot; subtitle=\u0026quot;${codename1.secondaryTitle}\u0026quot; targetType=\u0026quot;iphone_new\u0026quot; certificate=\u0026quot;${codename1.ios.debug.certificate}\u0026quot; certPassword=\u0026quot;${codename1.ios.debug.certificatePassword}\u0026quot; provisioningProfile=\u0026quot;${codename1.ios.debug.provision}\u0026quot; appid=\u0026quot;${codename1.ios.appid}\u0026quot; /\u0026gt; \u0026lt;/target\u0026gt; Assuming all goes well we will flip the switch and update some of the build servers to the latest OS. We’ll keep one build server around with the legacy OS and change it so you will need to explicitly send a build to it…​\nThis effectively means you will need to revert this build.xml change to keep building as the new servers will then use the \u0026ldquo;iphone\u0026rdquo; target. To build for the old build target you will need to do the inverse of the current change by sending a build to the \u0026quot;iphone_old\u0026quot; target.\nWe’ll support that for a while until we decide that the migration works at which point we will retire the old servers.\nWe already tried this migration once and decided to walk it back as part of our commitment to stability and seamless migration.\nThe nice thing about this switch is that most developers won’t feel it. Your builds will use newer iOS capabilities without a single change made by you.\nBitcode Probably the biggest issue with the migration is bitcode support which Apple introduced a while back. To understand bitcode you need to understand a bit of the background…​\niOS applications are physically Mac OS app bundles. The natively compiled binary can contain more than one processor architecture and does under normal circumstances. By default when you build an iOS appstore build you are building a 32 bit and 64 bit fat binary. Assuming you want to support the (Apple native) simulator too you will also need x86 binaries (this is a partial list).\nWhen we look into more esoteric devices like the Apple Watch or TV the story becomes more complicated and would become worse as a result.\nThis is the problem bitcode aims to solve. Since Apple already uses LLVM which has an intermediate representation after compilation they might as well use that instead of the native OS executables. This would allow Apples servers to natively compile the app to any future processor platform without you changing your code…​ Effectively this is like a form of bytecode for Apples benefit.\nApple requires bitcode for Apple Watch apps and might require it for all apps in the future so it’s a good idea to turn it on. You can turn it on by setting the ios.bitcode=true build hint.\nThe main challenge with bitcode is 3rd party libraries, if you use any of such libraries they need bitcode support enabled otherwise the compiler will fail. Older libraries don’t have bitcode support so you might need to update native code to include that functionality.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/xcode-migration-revisited-again/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/xcode-migration-revisited-again/xcode-migration.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe tried migrating to the new iOS build servers before and decided to revert the change due to xcode crashes. After \u003ca href=\"/blog/xcode-migration-take-2.html\"\u003ea lot of work\u003c/a\u003e we think the new server code is ready for production. We will try to migrate to these new servers again on the 28th of August (Sunday) to minimize impact if something goes horribly wrong.\u003c/p\u003e\n\u003cp\u003eIf you read the \u003ca href=\"/blog/ios-server-migration-plan.html\"\u003eold post\u003c/a\u003e covering the \u003ccode\u003eiphone_new\u003c/code\u003e build target you can skip the rest of the post as it’s pretty much the same.\u003c/p\u003e","title":"Xcode Migration Revisited Again"},{"content":"\nA couple of years ago at Google IO one of the prominent speakers turned to the audience and asked them: \u0026ldquo;Raise your hands if you understand the activity lifecycle\u0026rdquo;. He then proceeded to call them \u0026ldquo;liars\u0026rdquo;, claiming that after all his years at Google he still doesn’t get it properly…​\nAs a guy who worked on VM’s and understands some of the nuance I totally get his point. Lifecycle is hard. On Android it seems the developers took a difficult subject and made it even harder. With that in mind our implementation of background behavior on Android was lacking in some regards and Steve did a major overhaul of the implementation. Like all overhauls this could trigger some regressions so please keep your eyes open for such cases.\nThis change should be seamless and improve the applications robustness if you use background features.\nMaterial Icons Everywhere This went in a while back, we now use material icons in the MediaPlayer class by default for play/pause/forward \u0026amp; back.\nWe will also default to using material icons to represent tree folders/nodes in the next update to make it better looking and consistent by default.\nWe hope to use material icons by default on all UI elements. Getting to the older pieces of code is sometimes challenging as we don’t always notice them. If you can think of a component that can use a material icon makeover sound off in the comments.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/improved-background-behavior/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/improved-background-behavior/background-fetch.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA couple of years ago at Google IO one of the prominent speakers turned to the audience and asked them: \u0026ldquo;Raise your hands if you understand the activity lifecycle\u0026rdquo;. He then proceeded to call them \u0026ldquo;liars\u0026rdquo;, claiming that after all his years at Google he still doesn’t get it properly…​\u003c/p\u003e\n\u003cp\u003eAs a guy who worked on VM’s and understands some of the nuance I totally get his point. Lifecycle is hard. On Android it seems the developers took a difficult subject and made it even harder. With that in mind our implementation of background behavior on Android was lacking in some regards and Steve did a major overhaul of the implementation. Like all overhauls this could trigger some regressions so please keep your eyes open for such cases.\u003c/p\u003e","title":"Improved Background Behavior"},{"content":"\nStarting with the next Friday release we will migrate to the new peer support.\nThis migration will allow us to focus on a single code base and remove the branch where we are maintaining the old peer support.\nIf you run into issues you can use the android.newPeer=false build hint to see if the issue is due to the new peers.\n__ This is an undocumented temporary flag! We will remove this flag soon! Because of that you MUST report regressions you encounter and MUST NOT set the flag without further action…​\nOnce this is stabler on Android and things cool down with the xcode migration, UWP port etc. we will hopefully implement this on all the other platforms as well bringing our native integration into a new age.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-peers-on-by-default-on-android/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-peers-on-by-default-on-android/native-peer-revisited.png\"\u003e\u003c/p\u003e\n\u003cp\u003eStarting with the next Friday release we will migrate to the \u003ca href=\"/blog/new-android-peer-mode.html\"\u003enew peer support\u003c/a\u003e.\u003cbr\u003e\nThis migration will allow us to focus on a single code base and remove the branch where we are maintaining the old peer support.\u003c/p\u003e\n\u003cp\u003eIf you run into issues you can use the \u003ccode\u003eandroid.newPeer=false\u003c/code\u003e build hint to see if the issue is due to the new peers.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eThis is an \u003cstrong\u003eundocumented\u003c/strong\u003e temporary flag! We will remove this flag soon!\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eBecause of that you \u003cstrong\u003eMUST\u003c/strong\u003e report regressions you encounter and \u003cstrong\u003eMUST NOT\u003c/strong\u003e set the flag without further action…​\u003c/p\u003e","title":"New Peers on by Default on Android"},{"content":"\nThis has been a very busy week with huge changes and new features to the code base. Because of that we will\nshift the Friday release this week to Sunday so we’ll be able to revert the deployment if build issues occur without\naffecting too many people.\nBesides the big changes and new plugin versions we’re also including a major overhaul of the Android background\nprocesses that should improve the behavior of Codename One apps for background tasks. Notice that this is a pretty\nhuge change that might include regressions so be sure to report them as soon as possible.\nOnwards to the questions on stackoverflow:\nUsing gui builder and css This is really a question about layering themes from two different sources\nRead on stackoverflow…​\nNativeInterface – ClassNotFoundException on NativeLookup Native interfaces are sometimes missing the JavaSE impl directory in some cases. This shouldn’t pose a problem though.\nRead on stackoverflow…​\nScheduling local notification for a specific date and repeat yearly We don’t support more complex/long term repeat scheduling because of the complexity with scheduling such\nrepeat activities in a portable way.\nRead on stackoverflow…​\nCodename One Pubnub alternatives CN1lib I really like PubNub and don’t really see the need for an alternative. One of the nice things about PubNub is that\nthe client libraries are open source.\nRead on stackoverflow…​\nGet all file names in src folder, codenameone project \u0026ldquo;Files\u0026rdquo; in the source directory aren’t really \u0026ldquo;files\u0026rdquo; in the typical sense. Sometimes they can be a part of an APK\nwhich isn’t exactly like a jar. Other times they can be a part of an app bundle which is a bit more complex with some\nodd restrictions…​\nRead on stackoverflow…​\nQuery regarding to suspended mode Suspend/resume behavior is pretty tricky on mobile devices. We tried to simplify it as much as reasonably possible.\nRead on stackoverflow…​\nWrite/Read the image from fileSystemStorage and readjust it before saving Manipulating and resizing images is generally pretty simple but there are edge cases that are pretty hard to deal with.\nRead on stackoverflow…​\nGoogle Maps – some markers not appearing Turns out the longitude and latitude values were reversed.\nRead on stackoverflow…​\nWhere exactly are dialog text, OK button, and Cancel buttons defined or inherited from in CodenameOne? When asking a question it’s best to state what you are trying to do. Sometimes the answer is that you are asking\nthe wrong question…​\nRead on stackoverflow…​\nResize the image before uploading images from openGallery method ImageIO allows you to resize an image to arbitrary sizes on the filesystem using low level system API’s without\nphysically opening an image file.\nRead on stackoverflow…​\nHow to check internet connection and suspended mode Internet connectivity is tricky since we might be connected to a router but it might not have further connectivity…​\nRead on stackoverflow…​\nAlert Dialog message You can customize any component within Codename One’s UI\nRead on stackoverflow…​\nHow to make a Line graph in cn1 The charts API in Codename One is pretty darn complex and the demo doesn’t do enough to simplify that, ideally\nwe’ll make simpler chart demos that would be easier to work with. I’d also like a simpler API that would only\nencapsulate the more common use cases.\nRead on stackoverflow…​\nWe want to show the exact seconds of system on each seconds This question should probably have been tagged Java more than Codename One.\nRead on stackoverflow…​\nDisplay date-time details on an image in codenameone Mutable images provide a lot of flexibility to Codename One UI’s\nRead on stackoverflow…​\nBackground fetch in IOS not working On iOS you’ll have less control over background fetch than you do on Android\nRead on stackoverflow…​\nHow to release CODENAMEONE form including all it’s components while navigating one page to other? You don’t release forms. Once they have no more references they get GC’d however even one component in RAM\ncan lead back to the parent form so you need to track the references you keep.\nRead on stackoverflow…​\nHow can I programmatically ‘set’ all parameters of a Dialog, such as ‘dialog title’, ‘ok text’, etc., without having string literals as parameters? Most people use the static Dialog methods without realizing you can create an instance of the Dialog class \u0026amp;\npopulate it with arbitrary data.\nRead on stackoverflow…​\nHow to change the style of a button on release outside of button boundaries The title is misleading, the real issue relates to the different style objects for component states.\nRead on stackoverflow…​\nHow to handle a button pressed when it’s in a list cell The short answer is \u0026ldquo;don’t\u0026rdquo;. Use a Container as we explain in the List JavaDocs…​d\nRead on stackoverflow…​\nCodeName One – Image gets pixelated when scaling Getting smooth images that adapt to the various devices is always challenging. Ideally you want to scale as little\nas possible on the device and as few times as possible.\nRead on stackoverflow…​\nValidator for ComboBox and phone number You can add an arbitrary constraint to anything in the Codename One validation framework\nRead on stackoverflow…​\nMy CodeNameOne-App stoped to work in HTTPS Server certificates for https are always a pain, usually it’s a one time thing though.\nRead on stackoverflow…​\nLocalNotifications Issues in Android tablets and iPad devices On iOS local notifications only get delivered when the app is in the background…​\nRead on stackoverflow…​\nNon-persistence of class variables in StateMachine in CodenameOne Yet another example demonstrating why we are eager to move to the new GUI builder initVars() is a problematic\nhack that confuses many…​\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xviii/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xviii/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis has been a very busy week with huge changes and new features to the code base. Because of that we will\u003cbr\u003e\nshift the Friday release this week to Sunday so we’ll be able to revert the deployment if build issues occur without\u003cbr\u003e\naffecting too many people.\u003c/p\u003e\n\u003cp\u003eBesides the big changes and new plugin versions we’re also including a major overhaul of the Android background\u003cbr\u003e\nprocesses that should improve the behavior of Codename One apps for background tasks. Notice that this is a pretty\u003cbr\u003e\nhuge change that might include regressions so be sure to report them as soon as possible.\u003c/p\u003e","title":"Questions of the Week XVIII"},{"content":"\nWe hoped to get the xcode 7 migration on the build servers out before version 3.5 but the change had problems and we chose to revert. We postponed the change so we can get 3.5 out of the door…​\nThis Sunday we’ll deploy a server update that should be the first step in the migration.\nBecause of this deployment we will skip the Friday release and shift it to Sunday which has lower traffic/builds.\nUpcoming Release This Sunday we’ll release an update that could break the build for existing projects. It’s a major rewrite of our ios build code to use newer API’s when available. During this release our old servers might break which would force us to revert these changes and redeploy at a later date.\nAssuming all goes well we will proceed by flipping the ios build servers in two weeks time (again on a Sunday). We’ll announce that separately based on the results of this deployment.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/xcode-migration-take-2/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/xcode-migration-take-2/xcode-migration.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe hoped to get the \u003ca href=\"/blog/ios-server-migration-plan.html\"\u003excode 7 migration\u003c/a\u003e on the build servers \u003ca href=\"/blog/ios-migration-continued.html\"\u003eout before version 3.5\u003c/a\u003e but the change had problems and we \u003ca href=\"/blog/ios-migration-setback.html\"\u003echose to revert\u003c/a\u003e. We postponed the change so we can get 3.5 out of the door…​\u003cbr\u003e\nThis Sunday we’ll deploy a server update that should be the first step in the migration.\u003c/p\u003e\n\u003cp\u003eBecause of this deployment we will skip the Friday release and shift it to Sunday which has lower traffic/builds.\u003c/p\u003e","title":"XCode Migration Take 2"},{"content":"\nWe finished the final major piece of the offline build offering that we announced in July!\nThis Sunday we will update the plugins to include this ability as an option. Once installed you can use the instructions below to install the offline build service.\nIn this post I’ll explain the process and then follow up with some expected questions/answers. If you have questions/comments about this process please use the comment section below.\nGetting Started We support iOS/Android targets for offline build and we require an Enterprise grade subscription as explained here.\n__ If you signup for Enterprise and cancel you can still do the offline build. You won’t be able to update the builder though Prerequisites for iOS Builds You need the following installed tools/versions for Codename One’s offline build process:\nMac ideally with El Capitan (the current version of Mac OS)\nXcode 7+\nOracle’s JDK 8\nCocoapods – in the terminal type sudo gem install cocoapods --pre.\nxcodeproj – in the terminal type sudo gem install xcodeproj\nPrerequisites for Android Builds Android builds need the following:\nAndroid Studio\nOracle’s JDK 8\nGradle version 2.11 (as of this writing)\nInstallation To build offline you need to install the offline builder code which is a stripped down version of the build servers. When you install a version of the offline builder it maps to the time in which you downloaded it…​\nThat means that features like versioned builds won’t work. You can download/keep multiple offline builders and toggle between them which is similar in scope.\nE.g. if you installed an offline builder then installed a newer version and the newer version has a bug you can revert to the old version. Notice that the older version might not have features that exist in a newer version.\n__ Installation requires an enterprise account, you might need to re-login in the Codename One Settings UI To install an offline builder open the Codename One Preferences (settings) UI by right clicking the project and selecting Codename One → Codname One Settings.\nFigure 1. Open Codename One settings\n__ Even though the settings are a part of a project, the offline build settings are global and apply to all the projects…​ Once the Codename One settings UI launches select the Offline Builds entry:\nFigure 2. Offline build entry\nThis should launch the settings UI which would be blank the first time around:\nFigure 3. Offline builds setting UI\nWhen you ar e in this form you can press the download button to download the current version from the build server. If there is no update nothing will happen. If there is the latest version will download and tag with a version number/date.\nYou can see/change the selected version in this UI. This allows building against an older version. You can also delete older builds to save space.\nBuilding Offline building is almost like building with the cloud. In the right click menu you can select one of the offline build targets as such:\nFigure 4. The offline build targets\nOnce selected build generates a project under the build/and or build/iphone respectively.\nOpen these directories in Android Studio or xcode to run/build in the native IDE to the device or native emulator/simulator.\n__ Build deletes previous offline builds, if you want to keep the sources of a build you need to move it to a different directory! To get this to work with Android Studio you will need one more step. You will need to configure Android studio to use your local version of gradle 2.11 by following these steps:\nOpen the Android Studio preferences Figure 5. Android Studio Preferences\nSelect Build, Execution, Deployment → Build Tools → Gradle\nSelect the Use Local gradle distribution\nPress the …​ and pick your local gradle 2.11 install\nFigure 6. Local gradle config\nFAQ Should I use the Offline Builder? Probably not.\nCloud build is far more convenient, simple. Doesn’t require any installs (other than the plugin) and is much faster.\nWe built this tool for developers who work in situations that prohibit cloud build. E.g. government, banking etc. where regulation is restrictive.\nCan I Move/Backup my Builders? No.\nWe protect all the builders to avoid abuse. If you backup and restore on a new system the builders might stop working even if you are a paying enterprise customer.\nCan I install the builders for all our developers? Our licensing terms require a parallel developer seat for the Codename One developers in your company. If you have 5 Codename One developers they must all have an enterprise developer account to comply.\nE.g. You can’t have one enterprise account and 4 basic accounts.\nThe reason behind this is simple, in the past we saw a lot of funneling from developers who built such a licensing structure.\nWhat Happens if I Cancel? If you cancel your enterprise subscription all your existing installed offline builders should work as before but you won’t be able to update them or get support for this.\nWhen are Versions Released? We will try to keep this in the same release pace as library updates i.e. once a week typically on a Friday.\nAre Version Numbers Sequential? They grow but we sometimes skip versions. Versions map to our cloud deployment versioning scheme and we might skip versions in some cases.\nWhy is this Feature Limited to Enterprise Subscribers? This is a complex tool to support \u0026amp; maintain. SaaS has a well defined business model where we can reduce prices and maintenance costs.\nOffline builds are more like a shrinkwrap business model in which case our pricing needs to align itself to shrinkwrap pricing models for long term sustainability.\nThe main use case this product tries to address is government and highly regulated industries who are in effect enterprise users.\nHow Different is the Code From Cloud Builds? We use the same code as we do in the cloud build process with minor modifications in the process. Since the cloud servers are setup by us they work differently but should align reasonably well. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nSadart — August 10, 2016 at 3:50 pm (permalink) Great work! This one rocks.\nGareth Murfin — August 10, 2016 at 4:14 pm (permalink) Wow!!! This is amazing! One question, and I know the answer I think 🙂 But would it be possible to get this working using a mac in the cloud? I guess it would actually, if you simply install all the stuff on that mac, for building, and code locally then pull the code on the mac. Fantastic idea, also silences a lot of the people who say \u0026ldquo;no way im doing cloud builds\u0026rdquo;.. Can’t wait to try it.\nShai Almog — August 11, 2016 at 4:43 am (permalink) I think it would be painful but we would be oblivious to the fact that a Mac is in the cloud. Notice that you won’t be able to use a guest account as this is bound to a machine.\nDiamond — August 30, 2016 at 8:40 am (permalink) Instead of going through the Mac-in-cloud installation process pains, why not just send a normal CN1 cloud build. Both will require internet connectivity and Mac-in-cloud build will be more difficult to execute. Also, Mac-in-cloud will require an additional space to install necessary pre-requisites and this won’t be free.\nGareth Murfin — January 16, 2017 at 2:05 pm (permalink) Also, if you are building offline does that mean you can use cn1 for free?\nShai Almog — January 17, 2017 at 5:26 am (permalink) Yes and No.\nJust like you can use the source for free the enterprise offline build is free once you have it installed. Updates however, aren’t. So if you don’t need to update cn1 or get bug fixes/support then yes it’s free.\nKhoi Minh Vo — October 31, 2019 at 10:38 am (permalink) Khoi Minh Vo says:\nCan UWP get offline build?\nShai Almog — November 1, 2019 at 4:18 am (permalink) Shai Almog says:\nYes. If an enterprise customer asks for it we’ll do it.\nJulio Valeriron Ochoa — September 30, 2022 at 4:48 pm (permalink) Julio Valeriron Ochoa says:\nCan I use offline build with your source code cn1 locally fro free?\nShai Almog — October 1, 2022 at 2:06 am (permalink) Shai Almog says:\nNo. But you can build offline for free with the maven build now: \u0026lt;/blog/moving-to-maven/\u0026gt;\nJulio Valeriron Ochoa — September 30, 2022 at 4:51 pm (permalink) Julio Valeriron Ochoa says:\nFor example imagine that I found a bug in your source code an I want to fix. I’t possible locally with your source code in my pc to modify and compile my cn1 source code?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/offline-build/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/offline-build/phone-espresso.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe finished the final major piece of the offline build offering that we \u003ca href=\"/blog/preparing-for-3.5-offline-builds.html\"\u003eannounced in July\u003c/a\u003e!\u003cbr\u003e\nThis Sunday we will update the plugins to include this ability as an option. Once installed you can use the instructions below to install the offline build service.\u003c/p\u003e\n\u003cp\u003eIn this post I’ll explain the process and then follow up with some expected questions/answers. If you have questions/comments about this process please use the comment section below.\u003c/p\u003e","title":"Offline Build"},{"content":"\nYou probably recently received the \u0026ldquo;Next Steps from the Parse Team\u0026rdquo; newsletter in your inbox in which you were urged to take immediate action as it pertains to migrating your Parse.com-hosted apps. Or at least, you’re aware of the ultimate January 28, 2017 deadline for migrating your apps. While you should take such reminders seriously, there’s no need to panic. In this article, I share my experience with different Parse Server hosting backends and my choice after applying the principles outlined in Part 1 of this series. Read on!\nApplying the principles As I mentioned in Part 1, at the time that the imminent shutdown of Parse.com was announced, I had a few apps on Parse.com:\nParse4cn1 which is actually a Codename One wrapper for the Parse REST API but was hosted on Parse.com in order to test the library.\nTwo prototypes both in development at the time Parse.com’s shutdown was announced. (These apps still need to be migrated and this post is an extended version of my input to my clients as I help them choose a new backend.)\nLet’s begin by applying the principles outlined in Part 1 to parse4cn1. (Feel free to jump to the next section if you’re itching to see the backends I investigated.)\nSelf-hosting vs. Parse Server hosting providers: For parse4cn1, I considered both self-hosting and Parse Server hosting providers. In fact, I’m actually using both options, given the fact that I need parse4cn1 to work properly with various Parse Server-based backends. More on the backends shortly.\nVendor lock-in: This was not an issue for parse4cn1. The goal of parse4cn1 is to provide a wrapper for Parse Server so vendor-specific features are not quite interesting in this context. And like I suggested in Part 1, the chance of vendor lock-in is directly proportional to the amount of vendor-specific features used (none in the case of parse4cn1 so no risk of vendor lock-in).\nFreemium: Contrary to the general principle about being wary of overly generous freemium packages, I want to be able to maintain parse4cn1 for free. So in this case, freemium is a plus. However, that does not detract from the fact that you should beware of overly generous freemium models.\nParse Server is not a clone of Parse.com: The main implication of this for me was the need to have a stable test environment in which I could easily switch Parse Server versions and debug issues. OpenShift turned out to be a great solution for this as I explain later in the article.\nMaking parse4cn1 future proof and migration-friendly: For parse4cn1, this means that it needs to keep working with Parse.com (until January 28, 2017) and also work with as many Parse Server providers as possible. To achieve that, I migrated parse4n1 to and tested it on multiple Parse Server backends. Let’s now look at those backends.\nTest driving various Parse Server backends OpenShift: Great for development but not yet production ready OpenShift is a PaaS on which you can run various applications. Building up the work of Ionut-Cristian Florescu (alias \u0026ldquo;icflorescu\u0026rdquo;), OpenShift expert (at least in my eyes) Anatoly Tokalov (alias \u0026ldquo;antt\u0026rdquo;) has created a one-click solution to setup a Parse Server on OpenShift. I collaborated with him to integrate Parse Dashboard into this solution. So, with a few easy steps, it is now possible to set your own Parse Server backend for free on OpenShift! You can read more about the steps on Anatoly’s blog.\nHaving your own Parse Server sandbox can be tremendously useful as you migrate. You can easily switch between different Parse Server versions e.g. to track down bugs (that’s how I found this one, for instance). You can try different configurations out and get an initial feeling as to whether Parse Server is mature enough for your app. Regardless of what Parse Server backend you choose, I highly recommend an OpenShift sandbox.\nBe careful though! As pointed out by Anatoly in the same blog post (see Update 1 and Update 2 as well as the comments on the post), Parse Server on OpenShift is not yet production ready!\nMoreover, at the time of writing, it is not (yet) possible to use the migration tool provided by Parse.com to migrate your apps to OpenShift because the mongodb instance in OpenShift is not accessible externally.\nSo to summarize: OpenShift is a good place to test things out and arguably faster to set up than on your local machine. And it is free. However, at the time of writing, it is not production ready. I’m currently using OpenShift for parse4cn1 maintenance. The automated regression tests currently run against OpenShift and against Parse.com (for compatibility checks). I also manually tested parse4cn1 against two Parse Server hosting providers – back4app and sashido.io. Let’s have a look at them.\nback{4}app: An attractive solution Back4app is one of the Parse Server hosting providers looking to fill the void created by Parse.com. They use the Open Source Parse Server and Parse Dashboard as core and provide free and paid services around it with a pricing model quite comparable to Parse.com. The last part of the previous sentence caught your attention, didn’t’ it? Perhaps you’re thinking, \u0026ldquo;Parse.com shut down probably in part due to financial reasons and back4app has a similar freemium-based model yet you say it could be interesting?\u0026rdquo; Hang on, let me explain. And by the way, I have no affiliation with back4app, sashido.io, OpenShift or any other backend provider; all I’m going to say next is completely my personal opinion.\nYes, I think back4app is promising and here’s why:\nThey seem to understand very well that former Parse.com users are disgruntled and sceptical. They are open about this; see, for example, these back4app blog posts: (i)(ii). Moreover, their comparisons of different Parse alternatives (e.g. this one on Parse Server vs. Firebase) seem quite balanced which again is a sign to me that they understand the situation and are not just reacting to the opportunity offered by Parse.com’s shutdown without thinking things through.\nThey also are clear about your data: It’s yours and you can have it anytime according to back4app this FAQ answer. I’ve not tried exporting my data yet though so I’m only working with what is said. Check it out for yourself!\nThey stick quite closely to the Parse Server offering – you can see the Parse Server and Dashboard version your app is running on and they clearly state what services they’ve added that are not yet supported (e.g. background jobs). This helps reduce the chance of vendor-lock in.\nThey’ve made some improvements that could make life easier, for example, the option to upload cloud code via a Web interface. I really hated that CLI tool from Parse.com and the fact that I had to push all my changes to test them. With back4app, you still have to \u0026ldquo;push\u0026rdquo; your changes to test them but you can simply upload your .js file via a web interface. I find that a good step in the right direction.\nTheir customer service is friendly and supportive. At least that was my experience when I contacted them about this bug. I encountered it for the first time when testing parse4cn1 against back4app and I thought it was in their system. But they confirmed that they use the Parse Server code as-is so I looked further and found that the bug was actually in Parse Server. During the process of debugging, they were supportive and very responsive via live chat and email.\nThe big question mark for me is back4app’s freemium offering. Not as generous as Parse.com’s but in my opinion still somewhat too generous for comfort. As at the time of writing back4app offers 10 Requests/s, 50 K Requests/mo, 5 GB File Storage, 1 GB Database Storage, 1 cloud code job (read: background job) for free. Note though that the pricing page gets updated (read: tightened) from time to time so it could be that things have changed by the time you read this.\nI still find the current freemium package too generous as a lot of apps can run comfortably without ever needing to upgrade to a paid subscription which is not a good foundation for continuity in my opinion. Of course, I don’t know their business model. It could be that they want to use a decent freemium offer to attract as many users as possible and then \u0026ldquo;raise the heat\u0026rdquo;. That won’t be such a bad idea. Recall that there’s no free lunch. It’s better you pay a little and have a service that stays alive than to get a lot for free and face another shutdown!\nSashido.io: An interesting alternative In many ways, Sashido.io (previously Parseground) is similar to back4app. However, there are a few significant differences:\nUnlike back4app, Sashido touts the \u0026ldquo;freemium is bad\u0026rdquo; slogan. At the time of writing, their home page has the following (emphasis added): \u0026ldquo;No limit of monthly requests \u0026amp; req. per second, storage, database and file transfer. And the best part? It starts from $4.95/mo. Better than free.\u0026rdquo;\nThey even wrote an article on why freemium is bad. While that article makes sense, their approach of simply a 14-day trial and no freemium package is somewhat extreme in my opinion. By the way, I got a 2-month free trial due to early subscription. Often mobile projects start off as modest ideas and I don’t know many people who would be willing to incur monthly costs for a backend when they are not sure if their MVP would see the light of day. In that sense, I’m as opposed to overly generous freemiums as I am to no freemiums.\nSashido uses a custom dashboard instead of Parse Dashboard. While their dashboard is as intuitive as the Parse Dashboard and is designed very much to look like the Parse.com dashboard, this could be an issue in the future. As the open source Parse Dashboard gets enriched with new functionality, there is no guarantee that sashido will keep up or make the same choices with their dashboard. Something to definitely consider carefully if you choose sashido.\nSashido does use the open source Parse Server though. At least that’s what they told us. However, it’s useful to note that their dashboard does not (yet) mention what version of Parse Server they are running. I find that useful information and I hope they’ll add it soon. (Note that the Parse Server and dashboard version are present in the open source Parse Dashboard and by extension in back4app as well.)\nAs at the time of writing, there is no terms of service link on sashido.io’s homepage or any mention of what happens with your data if you opt-out. They don’t seem to be very open about the whole vendor lock-in fear. It might be a small omission on the website or it could be that the information is hidden somewhere and I didn’t look properly. But in any case, I expect this information to be prominent and easily accessible because it is at the center of the discussion and should not be relegated to the background.\nSashido does offer some features that might be interesting to you such as deploying cloud code via a private Github repo and a file migration tool from Parse.com to AWS (available to all Parse.com users but only useful if you want to store your files in Amazon S3).\nMoving forward There are a bunch of other services like back4app and sashido each having their pros and cons. I’ve not investigated all of them and honestly have no immediate plans to. parse4cn1 has successfully been tested against back4app and sashido as stated in this article. so they are both potential options. If I have to choose though, based on the current state of affairs, I’d go for back4app because I find their service overall more appealing and the risk of lock-in less than with sashido. I think this holds in general for small and medium-sized apps. In any case, I’ll always maintain an OpenShift sandbox in parallel for development and debugging.\nOne thing that both back4app and sashido are missing at the moment is the option to switch versions of Parse Server per app. The way it works now is that they decide at some point to upgrade to a particular Parse Server version and developers have no say in that. It would be super cool if one could choose the Parse Server version to run a specific app on and/or decide when to upgrade…​ And this is not an unrealistic dream! In a sense, the fall of Parse.com has opened the door to many new opportunities…​\nThe future is brighter with Parse Server Beyond the shock and fury at the shutdown of Parse.com, there is a silver lining and a bright future. The decision by Facebook to open source Parse Server and Dashboard might prove to be a game changer in the MBaaS space. It offers developers a decent backend out of the box and endless possibilities to customize and improve it. MBaaS is still somewhat of a gamble and skeptics suggest that an in-house solution is always the best. With Parse Server, you can get the best of both worlds! For instance, you can start off out with a Parse Server hosting provider and if your app becomes a hit and your needs necessitate an in-house solution, you can then smoothly migrate your Parse Server. If you app is one of the thousands that doesn’t see the light of day, you won’t have lost much in backend investment (especially if you chose a provider with a freemium model).\nOf course, the main thrust of this two part series has been to help you make a wise choice now and avoid another shutdown. But the truth is, even if you face another shutdown, the impact will be way less than Parse.com’s shutdown because you’ll have good alternatives and if you followed my advice, your app users won’t even notice that you switched backends again. That is the power of the open source solution offered by Parse Server!\nFinal word In this article, I’ve presented three Parse Server solutions, outlining their main pros and cons and clearly indicating my preferences. Note that I’ve deliberately not addressed \u0026ldquo;how to migrate\u0026rdquo; as there is a lot of useful information on that subject in the Parse.com migration guide as well as on the website of each Parse Server hosting provider. As such, there is no point in repeating what you can readily find yourself\nOf course, your app might differ in scope and purpose from the example that I’ve used in this article. Nevertheless, I’m pretty sure that if you follow my line of thought and apply the guidelines I’ve outlined in this series thoughtfully, you’d find a good replacement for your apps as well. I’ve shared the facts as well as my opinions with you; it’s now up to you to double-check and make your own choice; in that sense you have the final word!\nIf you know of other attractive solutions, have success stories/useful tips to share and/or disagree with my reasoning/opinion, do not hesitate to leave a comment! Should the information in these articles and complementary ones on the Internet not suffice, feel free to get in touch with us at SMash ICT for personalised consultation or contact me personally at chidi [dot] okwudire [at] smash-ict [dot] com. I wish you the very best with choosing your own replacement for Parse.com and would be glad to assist you in any way possible!\nReferences and interesting reads [1] Anatoly Tokalov (February 19, 2016). How to install your own Parse Server on OpenShift. Retrieved from http://www.anttdev.com/2016/02/how-to-install-your-own-parse-server-on-openshift/\n[2] Marian Ignev (April 28, 2016). Dangers and benefits of the freemium model — What did we learn out of Parse’s shutdown? Retrieved from https://medium.com/@sashidoio/dangers-and-benefits-of-the-freemium-model-what-did-we-learn-out-of-parses-shutdown-79becb215c84#.ggsb3gf6l\n[3] Alysson Melo (July 7, 2016). Challenges and Opportunities in the BaaS Market. Retrieved from http://blog.back4app.com/2016/07/07/baas-market/ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMarian Ignev — September 25, 2016 at 4:31 am (permalink) Marian Ignev says:\nHi Chidiebere Okwudire, very interesting article, great job, But … let me introduce myself. I’m part of the SashiDo team, so I want to share some thoughts with you … if you allow me of course 🙂\nThe things about SashiDo are wrong! Sorry … but they just are not true.\n– SashiDo Dashboard is 100% based on the OpenSource Parse Dashboard (I mean fork) and it’s improved by SashiDo. You had only to say that you write an article about SashiDo and we would love to tell you all the details 😉\n– About my article for the Freemium business model please correct me but the title I think is \u0026ldquo;Dangers and benefits of the freemium model \u0026quot; … not Freemium is bad thing … is that correct? 🙂 The only place that I used the word BAD was the there I told that …. Shutting down of good services like Parse is a bad thing … and yes I’m sure that a lot of Parse customers will agree with me now 🙂\nIn other hand as an entrepreneur I think that danger is a good thing … it’s exciting and keeps you focused, all the time.\nThe last thing I want to share with you is that the free trial is not freemium 🙂 Just an example … You can do a Test Drive before you buy a car, right? To understand what’s the difference between the freemium and the free trial I have a challenge for you: Please thing about implementing a freemium model for the auto motor industry 🙂\nI just wanted to share the true — no hard feelings here.\nAll best,\nMarian\nChidiebere Okwudire — September 29, 2016 at 11:00 am (permalink) Chidiebere Okwudire says:\nHi Marian,\nThanks for your response. Great to see that you’ve taken the time to point out some things that you consider incorrect in my analysis! Let me respond:\nYou suggest that what I say about Sashido is wrong and you go ahead to point out a few issues like the dashboard and freemium model. I’ll respond to those shortly but just to be clear, I mentioned other things about Sashido and I assume that since you didn’t say anything about those, they are correct. If not, please feel free to refute anything else that you feel is wrong in my article. My goal with these articles is to help developers make a right choice so I’m 100% in favor of accurate and correct information and input from folks like you is very much appreciated.\nNow to your remarks:\n1. In the article, I state that \u0026ldquo;Sashido uses a custom dashboard instead of Parse Dashboard\u0026rdquo;. This is based on an inspection of the Sashido dashboard when I still had a free trial account a few months ago. I don’t know how it looks now but at the time I wrote the article, the differences from the default Parse Dashboard were impossible to miss (I might even have a screenshot somewhere) – Parse Server and dashboard versions were not reported, the menu items were somewhat different, etc.\nYou’ve clarified that your version is forked from the open source Parse Dashboard and that’s nice to know. However, my point was (and remains) that with such a highly customized dashboard (albeit based on Parse Dashboard), there’s still a risk of lock in. Would you disagree? For example, a user wanting to switch from Sashido to say back4app would have to (at least) deal with a different looking dashboard with different options, etc. And I have a strong feeling there’s more that’s different than just the look-and-feel. Maybe you’d like to comment on that so readers can have a more balanced picture. Like I said, my free trial of Sashido has ended and I don’t plan to make another trial account to point out all the differences. The interested reader can do this for themselves 🙂\n2. About the Freemium model, you’re right that my wording in the article might incorrectly give the impression that the author is completely against Freemium whereas the article does try to compare both sides. I emphasize \u0026ldquo;try\u0026rdquo; here because in my opinion, the article is baised in favor of the dangers of freemium than the benefits. Again, let the interested reader be the judge. Let’s not get too distracted by the article though because I think the more important point in this context is: Is Sashido a freemium service or not? What’s your take on that? Note that http://www.sashido.io/#Pricing still include the line that I quoted in my article: \u0026ldquo;It starts from $4.95/mo. Better than free.\u0026rdquo;\nI look forward to your response and once again thanks for taking your time to engage in this conversation.\nMarian Ignev — September 30, 2016 at 2:38 am (permalink) Marian Ignev says:\nHi Chidiebere,\nThank you for your detailed answer. I appreciate it and I’m totally agree with you … let the interested reader be the judge I think that’s fair 🙂\nAnd yes … SashiDo is not a free service, but everybody can try it 14 days for free 🙂\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/how-i-chose-my-replacement-for-parse-com-part-2/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/how-i-chose-my-replacement-for-parse-com-part-2/parse.com-post-header.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eYou probably recently received the \u0026ldquo;Next Steps from the Parse Team\u0026rdquo; newsletter in your inbox in which you were urged to take immediate action as it pertains to migrating your Parse.com-hosted apps. Or at least, you’re aware of the ultimate January 28, 2017 deadline for migrating your apps. While you should take such reminders seriously, there’s no need to panic. In this article, I share my experience with different Parse Server hosting backends and my choice after applying the principles outlined in \u003ca href=\"/blog/how-i-chose-my-replacement-for-parse-com.html\"\u003ePart 1\u003c/a\u003e of this series. Read on!\u003c/p\u003e","title":"How I Chose my Replacement for Parse.com Part 2"},{"content":"\nOne of our enterprise customers needed help with file upload from the desktop. E.g. in his Codename One app running in the browser or desktop he wanted the ability to drag a file. Somewhat like we can drag a file into gmails compose window.\nThis doesn’t make sense within Codename One as something like that doesn’t exist on mobile devices or even tablets. Creating a cn1lib that implements this functionality does make sense, so Steve did just that.\nYou can get started by installing the library using our extension manager tool.\nCheck out the live demo here on the right side, drag an image into the phone simulator to add it to the form.\n__ I chose to use a phone skin out of habit but this obviously isn’t useful for actual devices…​ This is the code that makes it all happen:\nForm hi = new Form(\u0026quot;Drag and Drop Demo\u0026quot;); if (DropTarget.isSupported()) { DropTarget dnd = DropTarget.create((evt)-\u0026gt;{ String srcFile = (String)evt.getSource(); System.out.println(\u0026quot;Src file is \u0026quot;+srcFile); System.out.println(\u0026quot;Location: \u0026quot;+evt.getX()+\u0026quot;, \u0026quot;+evt.getY()); if (srcFile != null) { try { Image img = Image.createImage(FileSystemStorage.getInstance().openInputStream(srcFile)); hi.add(img); hi.revalidate(); } catch (IOException ex) { Log.e(ex); } } }, Display.GALLERY_IMAGE); } hi.setLayout(new BoxLayout(BoxLayout.Y_AXIS)); hi.setScrollableY(true); hi.addComponent(new SpanLabel(\u0026quot;Drag photos from your desktop into this app\u0026quot;)); hi.show(); Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/drag-and-drop-uploader/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/drag-and-drop-uploader/generic-java-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of our enterprise customers needed help with file upload from the desktop. E.g. in his Codename One app running in the browser or desktop he wanted the ability to drag a file. Somewhat like we can drag a file into gmails compose window.\u003c/p\u003e\n\u003cp\u003eThis doesn’t make sense within Codename One as something like that doesn’t exist on mobile devices or even tablets. Creating a \u003ca href=\"https://github.com/shannah/cn1-native-data-transfer\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ecn1lib that implements this functionality\u003c/a\u003e does make sense, so \u003ca href=\"https://github.com/shannah/cn1-native-data-transfer\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eSteve did just that\u003c/a\u003e.\u003c/p\u003e","title":"Drag and Drop Uploader"},{"content":"\nWe just flipped the switch on InfiniteContainer which is now more\nsynchronous and complies with the EDT policy by default. We are already back to committing changes and\nhave been busy updating with all of the things that didn’t make it into 3.5.\nA lot of those changes are a part of the release we made today \u0026amp; we have quite a few other things in the pipeline.\nOnwards to the questions on stackoverflow:\nSpanLabel in Codename one with BoxLayout along the y axis does not span If you invoke setScrollable(true) you are effectively allowing scroll on the X axis too which is probably not what you want…​\nRead on stackoverflow…​\nIs there a way to specify the size of an image in the resource file? Dealing with the amount of densities and the related complexities is one of the hardest problems of mobile development\nRead on stackoverflow…​\nPicker object Pickers have a lot of limits to allow more flexibility on the native layer. A lowest common denominator approach\nthat’s enforced due to the usage of native peers.\nRead on stackoverflow…​\nHow do I set the color of the radio button’s control? We made radio buttons use icon fonts in recent versions which we tend to prefer over setting their icons in the\ntheme constants but that too can be done.\nRead on stackoverflow…​\nCodenameone:Unable to set floating hint to textfield FloatingHint hides the TextField within it so you shouldn’t add the TextField again.\nRead on stackoverflow…​\nImage selected from Camera Roll shows up as black screen Not sure why this is happening to her so if other people are seeing similar issues please let us know…​\nRead on stackoverflow…​\nPassing array of strings containing float values to POST method This is clearly a problem in the PHP server code but since there is no code and I have no PHP experience I can’t\nhelp much…​\nRead on stackoverflow…​\nUnable to call service from simulator Could we have phrased the https warning using clearer syntax?\nRead on stackoverflow…​\nFly over animation Animating between 2 disconnected containers is challenging in Codename One\nRead on stackoverflow…​\nCannot override dragfinished method I have no idea why this is happening to this guy…​\nRead on stackoverflow…​\nHow to hash data with custom key using SHA1Digest algorithm Encryption is such a painful subject and the bouncy castle cn1lib is really under-documented. We’d love to have\na cn1lib section in the developer guide that covers all the big cn1lib’s and their use cases but the effort is huge\nand we don’t have the resources…​\nRead on stackoverflow…​\nWhy is my Codename One Project \u0026ldquo;not a visual project type\u0026rdquo;? These are some of the reasons we are migrating to the new GUI builder. The old GUI builder was very confusing\nto developers that are new to Codename One.\nRead on stackoverflow…​\nHow do I control the width of the overflow menu? The overflow menu is a bit confusing as it uses the old List based menu behavior and that’s much harder to theme\nor customize than the buttons we use elsewhere.\nRead on stackoverflow…​\nSetting colors for the overflow menu Another example of the problematic nature of the overflow menu list…​\nRead on stackoverflow…​\nAnnotation Processing I think we need a better \u0026ldquo;unified\u0026rdquo; approach for what is typically handled via reflection/bytecode manipulation\netc.\nRead on stackoverflow…​\nSharing vs. Copying Copy/Paste hasn’t been so much in demand on mobiles since the advent of share capabilities which answer\nmost of the use cases for copying.\nRead on stackoverflow…​\nWhy isn’t my generated keystore file showing up? We have seamless tools to generate keystores within the settings UI.\nRead on stackoverflow…​\nCodenameone: Unable to find packages during build This is one of the first things people run into when working with Codename One, some things just don’t work\nbecause a specific Java feature is missing.\nRead on stackoverflow…​\nCan I turn off banner ads in code? No. We are moving away from the way in which we implemented banner ads to using cn1libs as much as possible.\nThis gives the developers more flexibility both in using the code and working with the ad provider.\nRead on stackoverflow…​\nCodenameone IOS app is crashing randomly These things are painfully hard to track down and debug…​ There are many reasons for a potential crash and\nin most cases it’s just an out of memory crash. Those usually appear within the crash log.\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xvii/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xvii/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe just flipped the switch on \u003ca href=\"/blog/synchronous-inifinitecontainer.html\"\u003eInfiniteContainer\u003c/a\u003e which is now more\u003cbr\u003e\nsynchronous and complies with the EDT policy by default. We are already back to committing changes and\u003cbr\u003e\nhave been busy updating with all of the things that didn’t make it into 3.5.\u003c/p\u003e\n\u003cp\u003eA lot of those changes are a part of the release we made today \u0026amp; we have quite a few other things in the pipeline.\u003c/p\u003e\n\u003cp\u003eOnwards to the questions on stackoverflow:\u003c/p\u003e","title":"Questions of the Week XVII"},{"content":"\nThis is a feature Steve added way back in June but I didn’t get around to documenting it. Build hints can sometimes get \u0026ldquo;unwieldy\u0026rdquo; e.g. in the case of ios.plistInject or android.xapplication we sometimes have pretty verbose values.\nWe now have a way to define a \u0026ldquo;build hint variable\u0026rdquo; which the build server substitutes seamlessly. This is useful for \u0026ldquo;key\u0026rdquo; values required by API’s that sometimes require boilerplate e.g. the Google Maps support has this:\nandroid.xapplication=\u0026lt;meta-data android_name=\u0026quot;com.google.android.maps.v2.API_KEY\u0026quot; android_value=\u0026quot;YOUR_ANDROID_API_KEY\u0026quot;/\u0026gt; Notice that the one thing that actually matters here is YOUR_ANDROID_API_KEY which makes this problematic. We can’t add this string to the build hints automatically because this is a value you need to set…​\nThe variables allow us to do this instead:\nvar.androidAPIKey=YOUR_ANDROID_API_KEY android.xapplication=\u0026lt;meta-data android_name=\u0026quot;com.google.android.maps.v2.API_KEY\u0026quot; android_value=\u0026quot;${var.androidAPIKey}\u0026quot;/\u0026gt; This might seem more verbose but notice that the cn1lib can now inject the second line automatically and you will need to add this single line: var.androidAPIKey=YOUR_ANDROID_API_KEY\nThat is far simpler than before and less error prone.\nMost cn1libs still don’t take advantage of this syntax but hopefully we’ll move them in that direction as we move forward. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nGareth Murfin — August 5, 2016 at 12:35 pm (permalink) Gareth Murfin says:\nHad not even considered this, very useful indeed!\nTorjmen Hamza — April 30, 2017 at 12:28 pm (permalink) Torjmen Hamza says:\nHello,\nI have problems with Google Maps in Codename One, I tried to make a useful path like DirectionRoute in javascript but it is always a black line, it’s like that i have airlines, could some one help me with that ?\nShai Almog — May 1, 2017 at 3:52 am (permalink) Shai Almog says:\nHi,\nwhy not ask that in the maps post https://www.codenameone.com…\nI suggest asking there and mentioning what you did.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/build-hint-variables/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/build-hint-variables/build-hints.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is a feature Steve added way back in June but I didn’t get around to documenting it. Build hints can sometimes get \u0026ldquo;unwieldy\u0026rdquo; e.g. in the case of \u003ccode\u003eios.plistInject\u003c/code\u003e or \u003ccode\u003eandroid.xapplication\u003c/code\u003e we sometimes have pretty verbose values.\u003c/p\u003e\n\u003cp\u003eWe now have a way to define a \u0026ldquo;build hint variable\u0026rdquo; which the build server substitutes seamlessly. This is useful for \u0026ldquo;key\u0026rdquo; values required by API’s that sometimes require boilerplate e.g. the \u003ca href=\"https://github.com/codenameone/codenameone-google-maps/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGoogle Maps support\u003c/a\u003e has this:\u003c/p\u003e","title":"Build Hint Variables"},{"content":"\nWhen we initially designed the cn1lib file format we looked at jar files as a starting point. We wanted a way to distribute binary libraries that support the native code access, restrictions and ideally code completion.\nOne of the big failures of Jar files as a standard is bad support for code completion. This requires IDE’s to specify a JavaDoc (or source) directory so the completion logic can refer to that for hints. However, we wanted to keep the \u0026ldquo;binary\u0026rdquo; aspects of jars…​\nOur solution was simple, we used a special \u0026ldquo;doclet\u0026rdquo; to generate stub files representing the source files in the cn1lib thus providing a source classpath that included all the javadoc comments. Since these sources are stubs you can distribute binary cn1libs without too much of an IP concern (no more than typical Java jars).\nAt this time, all (or almost all?) cn1libs are open source. This makes that effort somewhat redundant for those libraries where the advantage of peeking at the source code can be preserved…​\nYou can do this by editing the cn1lib’s build.xml file and modifying the stubs target which should look like this:\n\u0026lt;target name=\u0026quot;Stubs\u0026quot;\u0026gt; \u0026lt;delete dir=\u0026quot;build/stubs\u0026quot;/\u0026gt; \u0026lt;javadoc sourcepath=\u0026quot;src\u0026quot; classpath=\u0026quot;lib/CodenameOne.jar:lib/CLDC11.jar\u0026quot; docletpath=\u0026quot;Stubber.jar\u0026quot; doclet=\u0026quot;com.codename1.build.client.StubGenerator\u0026quot;\u0026gt; \u0026lt;fileset dir=\u0026quot;${src.dir}\u0026quot; excludes=\u0026quot;*.java,${excludes}\u0026quot; includes=\u0026quot;${includes}\u0026quot;\u0026gt; \u0026lt;filename name=\u0026quot;**/*.java\u0026quot;/\u0026gt; \u0026lt;/fileset\u0026gt; \u0026lt;/javadoc\u0026gt; \u0026lt;/target\u0026gt; To look like this, it’s essentially a copy task instead of the doclet code:\n\u0026lt;target name=\u0026quot;Stubs\u0026quot;\u0026gt; \u0026lt;delete dir=\u0026quot;build/stubs\u0026quot;/\u0026gt; \u0026lt;mkdir dir=\u0026quot;build/stubs\u0026quot; /\u0026gt; \u0026lt;copy todir=\u0026quot;build/stubs\u0026quot;\u0026gt; \u0026lt;fileset dir=\u0026quot;${src.dir}\u0026quot;\u0026gt; \u0026lt;filename name=\u0026quot;**/*.java\u0026quot;/\u0026gt; \u0026lt;/fileset\u0026gt; \u0026lt;/copy\u0026gt; \u0026lt;/target\u0026gt; Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/open-source-cn1libs/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/open-source-cn1libs/extensions.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen we initially designed the cn1lib file format we looked at jar files as a starting point. We wanted a way to distribute binary libraries that support the native code access, restrictions and ideally code completion.\u003c/p\u003e\n\u003cp\u003eOne of the big failures of Jar files as a standard is bad support for code completion. This requires IDE’s to specify a JavaDoc (or source) directory so the completion logic can refer to that for hints. However, we wanted to keep the \u0026ldquo;binary\u0026rdquo; aspects of jars…​\u003c/p\u003e","title":"Open Source cn1libs"},{"content":"\nWe are thrilled to announce the immediate availability of Codename One 3.5!\nVersion 3.5 is a huge release that includes the long awaited Windows Universal Platform (UWP) support and brings the new GUI builder out of beta.\nHighlights of this Release Beta version of the UWP (Universal Windows Platform) Port – Codename One supports native Windows 10 universal apps that you can sell thru the Windows Store\nNew GUI Builder Release – We released the new GUI builder. It still has rough edges but is improving at a rapid pace\nNew Settings UI featuring the Extensions Library – This is a complete redesign of the core settings/preferences within Codename One. It started as the settings UI for IntelliJ/IDEA and we liked it so much we decided to make it the default for all IDE’s. This tool makes the process of installing/discovering cn1libs (libraries/extensions/plugins) trivial!\nExperimental New Peer Component Mode – We now allow more elaborate lightweight heavyweight mixing mode on the Android port and soon on other ports\nSeamless support for Android Marshmallow permissions – This requires no code changes for most applications. We also support this in the simulator \u0026amp; native code.\nRemoved Skins from Simulator – We moved skins to the more menu where you can be download them dynamically. We also added new skins and a skin designer tool…​\nThis reduced the size of our distribution by almost 30MB!\nAdded Background Fetch Support – This allows downloading in the background in iOS/Android\nNew Accordion Component – Allows folding/expanding UI elements\nNew ComponentAnimation methods for Compound Animations – allow more elaborate animation effects\nMaterial Icons Enhancements – used thru the code and map to different component selection states seamlessly\nSearch Command in the Toolbar – It’s now trivial to add search into the title area\nProxy Support – for simulator \u0026amp; build process\nDemos Rewritten – we rewrote/revisited the following demos: Property Cross, Charts, Social Boo, Dr. Sbaitso, Chrome,\nClock \u0026amp; Camera. They are now all Java 8 based, they use the newer API’s such Toolbar and proper fonts.\nSimplified ToastBar – Added simple error message handling, regular messages and download progress indication\nFinished migration to the new push servers – the last few users are leaving and soon the old servers will be retired\nLowlights Xcode 7 migration – this is something we tried to do and had to walk back. It’s more challenging to get this right but we hope to do this in the 3.6 cycle.\nDemos – we didn’t finish all the demos and didn’t finish the most important one (Kitchen Sink). There isn’t much left there though…​\nPeer Component Support – we didn’t switch this on by default. We weren’t able to do this for other OS’s either in time for the release.\nWhile we produced videos we didn’t produce more of them. The production of higher quality videos is more intense and hard to fit into our schedules\nOnwards to 3.6 With 3.6 we are aiming to introduce an offline build option for enterprise developers. We also have some other plans but they might stretch to 3.7.\nThe lowlight issues above are important to us for the 3.6 release and we’d like to improve on them.\nSchedule Version 3.6 is scheduled for December of 2016. 3.7 is scheduled for April 4th 2017. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nNigel Chomba — August 5, 2016 at 3:04 pm (permalink) Nigel Chomba says:\nhow can i get access to the updated kitchenSink Demo?.Cheers\nShai Almog — August 6, 2016 at 4:54 am (permalink) Shai Almog says:\nWe’d like to publish it in the next couple of weeks. It’s not ready yet…\nHristo Vrigazov — August 13, 2016 at 4:58 am (permalink) Hristo Vrigazov says:\nPure awesomeness! Way to go guys! Thanks for the amazing product!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-3-5-now-live/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-3-5-now-live/codenameone35.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are thrilled to announce the immediate availability of Codename One 3.5!\u003c/p\u003e\n\u003cp\u003eVersion 3.5 is a \u003cstrong\u003ehuge\u003c/strong\u003e release that includes the long awaited Windows Universal Platform (UWP) support and brings the new GUI builder out of beta.\u003c/p\u003e\n\u003ch3 id=\"highlights-of-this-release\"\u003eHighlights of this Release\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eBeta version of the UWP (Universal Windows Platform) Port\u003c/strong\u003e – Codename One \u003ca href=\"/manual/appendix-uwp/\"\u003esupports native Windows 10 universal apps\u003c/a\u003e that you can sell thru the Windows Store\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eNew GUI Builder Release\u003c/strong\u003e – We released the \u003ca href=\"/blog/using-the-new-gui-builder/\"\u003enew GUI builder\u003c/a\u003e. It still has rough edges but is improving at a rapid pace\u003c/p\u003e","title":"Codename One 3.5 Now Live"},{"content":"\nWhen we announced Codename One 3.4 we also announced a major animation overhaul. This was an important milestone that we didn’t fully actualize until this past week…​\nUp until now animations in Codename One consisted of a fixed set of animations you could perform, e.g. if I want to move a Component from one place to another I could do an animateLayout.\nWhen I want to do multiple animations in a sequence I can chain them using the AndWait version or thru callbacks etc.\nThis seems like it should be enough but it sometimes isn’t, e.g. if I have two or more containers and I want them to animate layout together, or if I want an animation to both animate the position and style of a component!\nTo solve this we introduced the ComponentAnimation class way back in 3.4. We now have new API’s that return ComponentAnimation instances that we can subsequently chain together e.g. this code is from the upcoming kitchen sink demo:\nComponentAnimation cn2 = createStyleAnimation(newUIID, 1000); ComponentAnimation cn1 = createAnimateLayout(1000); return ComponentAnimation.compoundAnimation(cn1, cn2); This code is within a subclass of Container so both methods are a part of Container. This code will result in an animation that both changes the style of the container as well as its layout!\nWe’ve added five methods that create this type to container:\npublic ComponentAnimation createAnimateLayout(int duration); public ComponentAnimation createReplaceTransition(Component current, Component next, Transition t); public ComponentAnimation createAnimateHierarchy(int duration); public ComponentAnimation createAnimateHierarchyFade(int duration, int startingOpacity); public ComponentAnimation createAnimateLayoutFade(int duration, int startingOpacity); __ createStyleAnimation has been around since 3.4 so it isn’t listed, but we fixed a some bugs there…​ You will notice that there are no AndWait version since you add these animations to the animation queue thru the AnimationManager API which has both addAnimation \u0026amp; addAnimationAndBlock allowing both use cases.\nThe code above uses the compoundAnimation static method to merge together animations (you can merge any number of animations not just two). You can also use the sequentialAnimation method to merge an animation sequence which might be more convenient than AndWait or AndBlock.\nPublished Developer Guide On Amazon On an unrelated subject we published the developer guide thru the Kindle book store\nhere. It’s the\nsame as the free PDF developer guide but it seems we can’t publish for free on Amazon.\nWe’d appreciate customer reviews though and if you can help us promote it to drive awareness of Codename One.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/composite-animations/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/composite-animations/title-area-animation.gif\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen we announced Codename One 3.4 we also announced a major animation overhaul. This was an important milestone that we didn’t fully actualize until this past week…​\u003c/p\u003e\n\u003cp\u003eUp until now animations in Codename One consisted of a fixed set of animations you could perform, e.g. if I want to move a \u003ccode\u003eComponent\u003c/code\u003e from one place to another I could do an \u003ccode\u003eanimateLayout\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eWhen I want to do multiple animations in a sequence I can chain them using the \u003ccode\u003eAndWait\u003c/code\u003e version or thru callbacks etc.\u003c/p\u003e","title":"Composite Animations"},{"content":"\nWe are deep within the 3.5 code freeze and this adds up to a remarkably busy week, we’ve got an even\nbusier week with the release itself. Because of the code freeze there is no need for a Friday release today\nso we are skipping it this week.\nSo lets get right down to the questions from stackoverflow…​\nCodenameOne ImageViewer blocks scroll Scrolling and ImageViewer don’t mix as the scrolling might collide with the panning/swiping.\nRead on stackoverflow…​\nHow to automatically reload a screen(form) after a given period of inactivity Chen recommended using the UITimer, there are quite a few other approaches but this is probably the simplest…​\nRead on stackoverflow…​\nSend HTTP query with verb different from GET / POST We should possibly make these more intuitive for common REST commands…​\nRead on stackoverflow…​\nHow to detect device back button event setBackCommand is a really complex API that behaves differently in many situations…​.\nRead on stackoverflow…​\nhow to insert break line for long text on button in codenameone using gui builder You can use the SpanButton class.\nRead on stackoverflow…​\n===How to use Sensors in Codename one\nhttp://stackoverflow.com/questions/38598478/how-to-use-sensors-in-codename-oneThe question is in relation to side swipe not so much sensors…​\nHow do I scroll down a scrollable container We have MANY scroll related methods and it can be a bit confusing sometimes.\nRead on stackoverflow…​\nWhy does the android button have a different appearance than the IOS button Steve explains the CSS answer, in general it’s because the button has a \u0026ldquo;Border\u0026rdquo; which takes precedence over color…​\nRead on stackoverflow…​\nCan’t Get Android Native Access Mistyping a build hint name is often painful to detect…​.\nRead on stackoverflow…​\nKeystore not generating Generating keys/certificates for Android should be really simple so I don’t quite get that issue.\nRead on stackoverflow…​\nHow to center input text in textfields? Centered text fields are nice for some UI designs but in terms of native editing…​\nRead on stackoverflow…​\nApp update Notifications in Codename One Generally push is the best approach to provide update notifications but notifications and toast can also work well…​\nRead on stackoverflow…​\nDynamic AutoComplete Luckily our demo shows exactly how this functionality is supposed to work…​\nRead on stackoverflow…​\nHello world application build fail (CodenameOne in Eclipse Juno) Apparently Eclipse Juno has issues with Java 8 support, not being an Eclipse guy I might have gotten this wrong…​\nRead on stackoverflow…​\nIs hint like feature available in pickers? No, however there are other ways to work/indicate with pickers\nRead on stackoverflow…​\nparse4cn1 callback usage example It’s good to see developers still picking parse4cn1 in the \u0026ldquo;post parse\u0026rdquo; era…​\nRead on stackoverflow…​\nDate comparison fails d1.compareTo(d2) compareTo isn’t available in Date in this particular case the substitution is relatively simple though…​\nRead on stackoverflow…​\nCodenameOne MapContainer Zoom Level Maybe we should deprecate MapComponent as so many developers get it wrong…​\nRead on stackoverflow…​\nData not block size aligned in codenameone BouncyCastle (No Padding) Don’t use String for binary data, this is a source of huge/painful bugs. It works on Java SE but then you run into\nreally complex edge cases on the devices…​\nRead on stackoverflow…​\nHow to make circle shape buttons in codenameone with GUI builder We really need to make it clear to developers that 9-piece borders can’t be used with circles…​ Maybe an AI of sort…​\nRead on stackoverflow…​\nNotification service Codename One This isn’t so much about notification as much as about the location API but it’s really unclear from the question…​\nRead on stackoverflow…​\n\u0026ldquo;Bluetooth failes to initialize\u0026rdquo; when automating Bluetooth steps One of the drawbacks of picking up the pre-existing BluetoothLE support is that we get this support \u0026ldquo;as is\u0026rdquo; and\nonly enhanced it slightly.\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xvi/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xvi/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are deep within the 3.5 code freeze and this adds up to a remarkably busy week, we’ve got an even\u003cbr\u003e\nbusier week with the release itself. Because of the code freeze there is no need for a Friday release today\u003cbr\u003e\nso we are skipping it this week.\u003c/p\u003e\n\u003cp\u003eSo lets get right down to the questions from stackoverflow…​\u003c/p\u003e\n\u003ch3 id=\"codenameone-imageviewer-blocks-scroll\"\u003eCodenameOne ImageViewer blocks scroll\u003c/h3\u003e\n\u003cp\u003eScrolling and \u003ccode\u003eImageViewer\u003c/code\u003e don’t mix as the scrolling might collide with the panning/swiping.\u003c/p\u003e","title":"Questions of the Week XVI"},{"content":"\nI wanted to write about the new kitchen sink demo which I’m trying to finish…​\nBut I haven’t finished it yet as it’s such a major undertaking. As part of that work I wanted to show some code that downloads themes and didn’t want to use the venerable infinite progress indicator which I generally dislike…​\nOver these past few months I’ve enjoyed the ToastBar tremendously and I think it’s probably far better suited for such a use case than the infinite progress. The ToastBar has rudimentary progress indication capabilities that are perfect for such a use case.\nI added a relatively simple method to ToastBar but I’m guessing we will add more elaborate versions of this code:\npublic static void showConnectionProgress(String message, final ConnectionRequest cr, SuccessCallback\u0026lt;NetworkEvent\u0026gt; onSuccess, FailureCallback\u0026lt;NetworkEvent\u0026gt; onError) This method shows a progress indicator ToastBar with a progress value for the connection request. On completion it will invoke the onSuccess/onError callbacks both of which may be null. E.g. for the case of theme download in the new KitchenSink demo I use the following code:\nConnectionRequest cr = new ConnectionRequest(BASE_URL + currentThemeFile); cr.setDestinationStorage(currentThemeFile); ToastBar.showConnectionProgress(\u0026quot;Downloading theme\u0026quot;, cr, ee -\u0026gt; { setTheme(parentForm, currentThemeFile); theme.putClientProperty(\u0026quot;downloading\u0026quot;, null); }, (sender, err, errorCode, errorMessage) -\u0026gt; { ToastBar.showErrorMessage(\u0026quot;There was an error downloading the file: \u0026quot; + err); Log.e(err); }); cr.setFailSilently(true); NetworkManager.getInstance().addToQueue(cr); Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/toast-downloads/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/toast-downloads/toastbar-downloads.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI wanted to write about the new kitchen sink demo which I’m trying to finish…​\u003cbr\u003e\nBut I haven’t finished it yet as it’s such a major undertaking. As part of that work I wanted to show some code that downloads themes and didn’t want to use the venerable infinite progress indicator which \u003ca href=\"/blog/dont-block-the-ui.html\"\u003eI generally dislike\u003c/a\u003e…​\u003c/p\u003e\n\u003cp\u003eOver these past few months I’ve enjoyed the \u003ccode\u003eToastBar\u003c/code\u003e tremendously and I think it’s probably far better suited for such a use case than the infinite progress. The \u003ccode\u003eToastBar\u003c/code\u003e has rudimentary progress indication capabilities that are perfect for such a use case.\u003c/p\u003e","title":"Toast Downloads"},{"content":"\nIt’s tough to pick up a new toolchain like Codename One. There’s so much to learn…​\nA lot of our developers come from the Android world and even though Codename One is much simpler than Android porting the first app to Codename One is still painful.\nWe wanted to simplify this process since the day we launched Codename One but as we explained before, this isn’t simple and the results would \u0026ldquo;underwhelm\u0026rdquo;.\nWe decided that \u0026ldquo;underwhelming\u0026rdquo; isn’t always a bad place to start when you are doing open source work. With that in mind Steve created an open source project to scaffold a new Codename One project from an existing Android native project.\nNotice my choice of words, I chose scaffold instead of migrate. This will not turn an Android project into a Codename One project but rather make the process of getting started slightly easier. It migrates the images \u0026amp; strings.\nIt creates GUI builder files (using the new GUI builder) for every layout XML file. Notice that the layout isn’t replicated properly and neither is the proper styling.\nThese differ a lot between Android and Codename One and would require at least 6 months of intense work to get right.\nCopying the layout seems deceptively easy on the surface but Android layouts differ considerably. We’d love to simplify that but the level of effort required is beyond our limited resources. We can’t justify the effort without a sense of demand…​\nIn the current version we don’t touch the source or the manifest at all but we could address both of these to some degree as part of the work.\nMoving This Forward That’s where you come in. File issues, RFE’s and let us know that you want progress on this.\nFork and contribute to Steve’s project and provide samples that we should improve.\nLet your friends know about this project and raise community awareness around it!\nWe don’t want to invest significant developer resources on something that won’t gain developer traction so we need your help to get this project off the ground. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nGareth Murfin — July 27, 2016 at 3:09 pm (permalink) Gareth Murfin says:\nWhat a great idea, many Android devs looking to produce iOS ports end up thinking about using Codename One. As you say resources are so very different, I found learning Android GUI dev much harder than learning CN1 GUI dev (but previously I was into Swing, J2ME, LWUIT etc). I think one of the main paradigm shifts that is hard to learn is the lack of \u0026ldquo;activities\u0026rdquo;. That is in Android each screen has its own class and it starts to feel nice and correct (more OO/modular or something :)) – and when you go to CN1 it is very strange to have everything more \u0026ldquo;old school\u0026rdquo; in one or 2 classes. If it were possible it would be good if each screen in cn1 could actually be a separate class, so when you create an event for postShow or something it doesnt go into statemachine but a class called for example Splash(), and with a method postMain() in there. This would make it far easier to navigate projects and understand them (new coders have been scared of even looking at my gargantuan statemachines, preferring to do a rewrite(!)). Just a suggestion of course, and we could easily do this ourself by simply making calls from StateMachine to custom classes we can make for each screen, which is actually what I am planing on doing in my next cn1 app. Current I mostly have one large statemachine, another class holding the business logic that is called on from statemachine, and then a pile of POJOs.\nbryan — July 27, 2016 at 9:08 pm (permalink) bryan says:\nA class per screen/form is the \u0026ldquo;new\u0026rdquo; way to do CN1, and the way the new GUI builder works, so this porting tool would do that.\nShai Almog — July 28, 2016 at 4:18 am (permalink) Shai Almog says:\nYep. I mentioned this uses the new GUI builder so it’s one form class per layout.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/android-migration-tool/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/android-migration-tool/profiling-in-android-ios.png\"\u003e\u003c/p\u003e\n\u003cp\u003eIt’s tough to pick up a new toolchain like Codename One. There’s so much to learn…​\u003cbr\u003e\nA lot of our developers come from the Android world and even though Codename One is much simpler than Android porting the first app to Codename One is still painful.\u003c/p\u003e\n\u003cp\u003eWe wanted to simplify this process since the day we launched Codename One but as we \u003ca href=\"/blog/why-we-dont-import-android-native-code.html\"\u003eexplained before\u003c/a\u003e, this isn’t simple and the results would \u0026ldquo;underwhelm\u0026rdquo;.\u003c/p\u003e","title":"Android Migration Tool"},{"content":"\nToday we are going into code freeze for Codename One 3.5 which is due one week from now, because of the fast release cycle we don’t need more than a week of code freeze to stabilize our current release.\nThe code freeze applies to the Codename One libraries and ports as those are the parts that are inherent to the release.\nWhat Didn’t Make the Release We have many new features and great capabilities that we were able to introduce for 3.5. We will go into those with our release announcement.\nThe biggest \u0026ldquo;miss\u0026rdquo; we have in this release is the new iOS build servers with xcode 7+. We wanted to get them out before the release but this requires more work than we initially expected to get right. We remain committed to going thru with this process and will do so after the 3.5 release.\nWe didn’t finish modernizing and updating all the demos with this release. It’s disappointing but not crucial as most of the big ones are already done and the process is half way thru.\nThe new peer components implementation isn’t yet ready for primetime and isn’t the default (yet). It’s still not implemented on iOS where the implementation seems to be more challenging in some regards.\nHow does the Code Freeze Work? The pieces of Codename One that we freeze are effectively the entire github repository except for the Codename One designer and JavaDoc comments. That means that we will avoid any non-critical commits to that change anything other than the designer or docs until next Tuesday.\nNotice that plugins etc. move at their own pace and are a separate entity from the release cycle.\nWe introduce a 3.5 branch into the git repository so you can reference the 3.5 version in the future. We review commits related to critical issues and merge them into the 3.5 branch. Commits will not go directly into the 3.5 branch and will instead go into the trunk where we cherry pick them into the branch.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/code-freeze-for-3-5/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/code-freeze-for-3-5/codenameone35.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eToday we are going into code freeze for Codename One 3.5 which is due one week from now, because of the fast release cycle we don’t need more than a week of code freeze to stabilize our current release.\u003c/p\u003e\n\u003cp\u003eThe code freeze applies to the Codename One libraries and ports as those are the parts that are inherent to the release.\u003c/p\u003e\n\u003ch3 id=\"what-didnt-make-the-release\"\u003eWhat Didn’t Make the Release\u003c/h3\u003e\n\u003cp\u003eWe have many new features and great capabilities that we were able to introduce for 3.5. We will go into those with our release announcement.\u003c/p\u003e","title":"Code Freeze for 3.5"},{"content":"\nWhen we get a crash report one of our first questions is \u0026ldquo;when did you build this?\u0026rdquo;.\nThe answer is often too vague to trace the specific version, so we end up with a mixture of guessing.\nThe main issue is that there are different version values. They conflict with one another. They can be confusing and they can be inaccurate.\nStarting with the latest update we now have a file in the root of Codename One called cn1-version-numbers and it includes two numbers that might not be accurate but will give us a general ballpark of the relevant version. The latter number is our internal SVN version number but the former can be interesting to you too. These numbers will appear as below when you make your first Log.p(String) call:\n[EDT] 0:0:0,0 - Codename One revisions: 4ee2778c79ad5eaadd2344bc0f215a82483421cb 1955 The former is a GIT version, this can help you browse the git repository at that specific version by using a UWL like this:\n[version](https://github.com/codenameone/CodenameOne/tree/)\nE.g. the URL matching the version above would look like that:\nhttps://github.com/codenameone/CodenameOne/tree/4ee2778c79ad5eaadd2344bc0f215a82483421cb Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nadalbert — February 10, 2018 at 10:41 am (permalink) adalbert says:\nWhy in e.g. url in file cn1-version-numbers there is 83179fd0246f2f2114eded43beffb51c5c7aa4d6 not 4ee2778c79ad5eaadd2344bc0f215a82483421cb?\nhttps://github.com/codename…\nShai Almog — February 11, 2018 at 7:26 am (permalink) Shai Almog says:\nBecause when we do a build it generates a new key matching the current tree which is slightly newer. Both should be roughly from the same time frame.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/logged-versions/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/logged-versions/generic-java-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen we get a crash report one of our first questions is \u0026ldquo;when did you build this?\u0026rdquo;.\u003cbr\u003e\nThe answer is often too vague to trace the specific version, so we end up with a mixture of guessing.\u003c/p\u003e\n\u003cp\u003eThe main issue is that there are different version values. They conflict with one another. They can be confusing and they can be inaccurate.\u003c/p\u003e\n\u003cp\u003eStarting with the latest update we now have a file in the root of Codename One called \u003ccode\u003ecn1-version-numbers\u003c/code\u003e and it includes two numbers that might not be accurate but will give us a general ballpark of the relevant version. The latter number is our internal SVN version number but the former can be interesting to you too. These numbers will appear as below when you make your first \u003ccode\u003eLog.p(String)\u003c/code\u003e call:\u003c/p\u003e","title":"Logged Versions"},{"content":"\nWe are on the final stretch of 3.5 getting ready for the codefreeze that will go into effect in the middle of next week. With that in mind we have last minute features we are trying to get out of the door and unfortunately had to skip some big tasks. One of the big problems is the iOS server migration which we couldn’t fit into the schedule. The peer component changes made it to Android but aren’t set as the default, this makes the most sense in the current state. We’ll probably flip the switch to the new peer components after the release.\nThere are other issues that didn’t make it but we are still rather please with this release and we think it follows\nthe trends we set before of refinement, stability \u0026amp; ease of use. We’ll write more about those as when we make the\nfinal announcement.\nIn other news Stackoverflow introduced a new documentation feature which looks interesting…​\nWe already setup a Codename One section\nalthough it’s hard to tell how this will play with our existing docs. I’ve tried it a bit and I think it still needs\na bit of work although I love some of the interface interface elements. If we get community involvement\nthere we might migrate our documentation effort.\nHow to make use of keep-alive in ConnectionRequest in Codename One? We have an undocumented way to do keep alive, but we have some better options. My favorite is the websockets\nwhich seem to be the direction where everyone is heading.\nRead on stackoverflow…​\nHow do I maintain my app’s background while a website is being displayed? Peer components are challenging, but our latest set of improvements probably won’t make much of a difference\nin this question. It’s hard to tell though since no code or screenshot was provided.\nRead on stackoverflow…​\nIntegrating Android Code in Codenamone Native code support is pretty easy but sometimes you need more control over Android native code e.g. thru\nresource files, c files etc.\nRead on stackoverflow…​\nNetwork request timeout or network lost or slow network not getting handle properly in codenameone Currently Codename One has a connection timeout but not a read timeout value which is a bit more \u0026ldquo;challenging\u0026rdquo;\nacross platforms. This is something we should probably address.\nRead on stackoverflow…​\nScrollvisible is not working in barebone code Scrollability is a really difficult concept especially in Codename One where touch scrolling is pretty challenging\nas it doesn’t allow nesting etc.\nRead on stackoverflow…​\nCodenameOne IOS app crashing due to null threadsToDelete This looks like a very interesting crash but those things are really hard to debug/track without a reasonable test case.\nRead on stackoverflow…​\nHow to access the source directory in codename one Two of the biggest complexities in Codename One are the missing java.new.URL and java.io.File. We might need\nto just add these API’s as stub calls to the \u0026ldquo;real\u0026rdquo; implementations.\nRead on stackoverflow…​\nform.addOrientationListener(new ActionListener() not being called on keyboard open Here is an example of a change in the API behavior that effectively fixed a bug serving as the basis of a different bug.\nRead on stackoverflow…​\nBuild iOS failed after changing back to the old xCode build servers This is actually because of the Google+ support changes even on iOS Google’s incompatible changes are a pain.\nRead on stackoverflow…​\nHow to install skins in NetBeans codename one plugin This should work out of the box, if any of you guys are running into issues here we’d appreciate some help in\ntracking those issues.\nRead on stackoverflow…​\nUsing Native Android Bluetooth Support for Codename Our newly announced bluetooth support is really bluetoothle which most of the industry is focusing around.\nHowever, there is still usage of the older bluetooth standard in quite a lot of devices.\nRead on stackoverflow…​\nWhat is the format of an AARRGGBB array? Some things are pretty obvious to us as guys who have done mobile Java UI’s for over a dozen years, but they\nare not always clear and it’s often hard for us to see the complexities.\nRead on stackoverflow…​\nHow to make JSON PUT request through Codename one API Posting a custom body isn’t hard but we’d like to make it easier as we move forward, this will allow us to create\nterse webservice usage.\nRead on stackoverflow…​\nIOS Debug Build without Developer Account This was something we supported in the early days of Codename One, but it created a lot of problems so we decided\nto discontinue this functionality.\nRead on stackoverflow…​\nIs it possible with Codename One to take a temporary photo? We try to make photos consistent between platforms but they are pretty different. Ideally we’d like to provide better\ncamera controls but those API’s are very low level and thus fragmented.\nRead on stackoverflow…​ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nEric — July 22, 2016 at 1:38 pm (permalink) Eric says:\nHello,\nI think there is a regression with today’s update. I can’t open my Accordion menu anymore to see his content. Can you check it please ? Thanks!\nShai Almog — July 22, 2016 at 1:55 pm (permalink) Shai Almog says:\nThanks for the headsup. I committed a fix that broke some of the core animations, we’re putting out a fix that should be up in an hour or so.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xv/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xv/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are on the final stretch of 3.5 getting ready for the codefreeze that will go into effect in the middle of next week. With that in mind we have last minute features we are trying to get out of the door and unfortunately had to skip some big tasks. One of the big problems is the iOS server migration which we couldn’t fit into the schedule. The peer component changes made it to Android but aren’t set as the default, this makes the most sense in the current state. We’ll probably flip the switch to the new peer components after the release.\u003c/p\u003e","title":"Questions of the Week XV"},{"content":"\nMillions of Codename One apps are installed on devices every month. Most of them aren’t in the gallery\nand are never featured in this recurring segment. We are looking for something exceptional in apps that\nwe feature here and Ana Paltel fits that bill. It has a polished UI and it’s\nshipped by a major operator. It uses some unique Codename One features to boot making it even more interesting.\nWe liked the usage of the native Google Maps integration that provides\ninformation about service points and directions. The UI as you can see from the screenshots above is\nrich, it provides gauge charts and other visual niceties that are builtin directly into Codename One.\nSince the app is localized in Arabic and English it makes use of Codename One’s native bidi/RTL support\nwhich is essential for middle eastern languages. It also makes use of push notification and a few other\ndevice capabilities.\nThe app is shipping both on iOS \u0026amp; on\nAndroid and as of this time\nit’s open to users in other regions so I was able to install it and take it to a spin. Even thought I couldn’t\nphysically login there is a lot of functionality that’s exposed on the guest account.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/featured-app-ana-paltel/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/featured-app-ana-paltel/ana-paltel.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eMillions of Codename One apps are installed on devices every month. Most of them aren’t in the gallery\u003cbr\u003e\nand are never featured in this recurring segment. We are looking for something exceptional in apps that\u003cbr\u003e\nwe feature here and \u003ca href=\"/blog/featured-app-ana-paltel/\"\u003eAna Paltel\u003c/a\u003e fits that bill. It has a polished UI and it’s\u003cbr\u003e\nshipped by a major operator. It uses some unique Codename One features to boot making it even more interesting.\u003c/p\u003e","title":"Featured App – Ana Paltel"},{"content":"\nWhen I first read the announcement that Parse.com would shut down on January 28th 2017, I went from\ndisbelief (it’s probably an early April fool’s joke) to rage (how could they do that?!) to sadness (oh no! it was a\ngreat service) and finally to utter confusion (where do I go from here and what do I do with my apps –\nparse4cn1, two MVPs for clients\nand an upcoming rewrite of\nMedex for which I was planning to use\nParse.com as backend?). A few months down the line, a lot has happened such as the release of the open source\nParse Server (yay!) and subsequently the Parse Dashboard. However, I still had to decide what do with my apps\nand I guess you have to as well.\nBy now, the imminent shutdown of Parse.com must have hit home for you as well: You wish it was merely a bad dream but unfortunately it’s a stark reality. You’ve got just a few months left to migrate your existing apps and obviously do not want to face another shutdown. Nearly every major MBaaS vendor is brandishing a banner that directly or indirect says \u0026ldquo;Parse.com let you down but you’re safe with us\u0026rdquo;. However, whom can you trust? Or maybe you should just host your own Parse Server? How about migrating away from anything Parse-like and settling for a completely different MBaaS.\nIn this post, I share some important points to consider while deciding on your replacement for Parse.com. In Part 2, I’ll share how I applied these guidelines while migrating my own apps. This article is highly recommended for anyone who still has their apps on Parse.com or is contemplating using a Parse.com-like solution as backend for their (new) apps.\nThere Are Basically 3 Options Don’t be intimidated by the long lists of Parse.com alternatives that you may have seen (for example, this one). Broadly speaking, all Parse.com alternatives fit into one of the following three categories:\nSelf-hosting\nParse Server hosting provider\nOther MBaaS (unrelated to Parse)\nLet’s briefly consider these categories and give some examples.\nSelf-hosting Self-hosting comes in two flavors:\nRunning Parse Server on a PaaS infrastructure such as Heroku, AWS, Microsoft Azure or Google App Engine. The Parse Server wiki provides links to installation guides for these services and more.\nRunning Parse Server on your own infrastructure. This could be attractive if you already have your own platform and/or if you require on-premises hosting.\nParse Server hosting provider These are BaaS providers who have leveraged the open-source Parse Server to create Parse.com-like services. Some of the providers in this category are back4app, ParseGround (now called SashiDo) and Oursky Parse Hosting to mention just a few.\n__ | A more comprehensive list can be found here.\nNote that I cannot ascertain how up-to-date it is…​ Undoubtedly, this category of Parse.com alternatives will be attractive to most of the users who chose Parse.com in the first place because of its ease of use, rich feature set and/or intuitive dashboard. Although Parse Server is not a clone of Parse.com, it is quite similar in terms of features and even has some new features like live queries which were not present in Parse.com. As such Parse Server is definitely an alternative worth considering!\nAs already mentioned above, there are several providers in this category. If you take this route, you’ll need to choose one of them. While there is no silver bullet or crystal ball to help you make that choice, I’ll highlight important aspect that you must take into consideration while choosing your Parse.com replacement. But first, let’s consider the third category of Parse.com alternatives.\nOther MBaaS solutions Shortly after Parse.com announced the imminent shutdown, various lists of alternatives appeared on the Internet.\nConsider, for example, this list of 100 or more alternatives to Parse.com. (Note that the list also includes alternatives from the other two categories.)\nWhile Parse.com offered a rich feature set, it was not ideal for all use cases. For example, Parse.com was (and by extension Parse Server is) not suited for real-time messaging. If you’re one of those who found Parse’s offering insufficient for your use case, then this is a good time to consider other MBaaS options that could better meet your needs including the possibility of an in-house custom solution. While you’re at it though, watch out for signs of vendor lock-in and do not be fooled by false assurances that a particular MBaaS is reliable simply because it is backed up by a big company. If Facebook pulled the plugs on Parse, any of those big-company-backed solutions can face the same fate! That’s the reality.\nThe rest of this article will focus on the first two categories (i.e. self-hosting and Parse Server hosting providers).\n5 Things to Bear in Mind Now that you have a better idea of what the options are, here are some things you must bear in mind while making your choice for your Parse.com replacement.\nSelf-hosting is more than merely clicking a \u0026ldquo;Deploy on X\u0026rdquo; button Most self-hosting Parse migration guides display a \u0026ldquo;Deploy on \u0026lt;PaaS\u0026gt;\u0026rdquo; button. While this might help you through the initial migration, it is only the tip of the iceberg! Self-hosting requires non-trivial investment of time and resources; it requires a certain degree of technical competence and could be quite expensive in the long run.\nOn the other hand, self-hosting offers you maximum flexibility from choice of database to Parse server version (remember that Parse Server is still in active development so there are regular updates, bug fixes, etc.). Furthermore, you can add new functionality that is not (yet) available in Parse Server.\nIf you’re considering self-hosting, be sure to give yourself convincing answers to questions like:\nDo I have the technical skills to maintain my own Parse Server? In addition to supporting your apps, you’re suddenly going to also be responsible for several quality aspects like scalability, security, redundancy and reliability. Can you cope with that especially if your app has a significant user base?\nIs self-hosting financially viable for me? It might look cheap at the beginning but as your app’s audience grows, you’ll probably need to scale. While it is out of the scope of this article to go into detailed cost calculations, I’d like to point you to this article on how much self-hosting using AWS could cost as well as this discussion thread by other Parse Server enthusiasts on cost considerations. The main message here is: Do not underestimate the costs!\nDo I have sufficient time to set up my Parse Server and migrate all my apps? You have till January 28, 2017 to get done with migration and that’s not so much time. In fact, according to the migration guide provided by Parse.com, you should already have finished setting up your Parse Server by July 28, 2016. While that’s not a firm deadline, if you’re reading this article now and still haven’t chosen your self-hosting PaaS, you’re kind of running late…​\nIf you cannot provide satisfactory answers to questions like the ones above, self-hosting is likely not for you. Instead, consider a Parse Server hosting provider that will handle the hosting for you, allowing you to focus on making great apps. That was the power of Parse.com – \u0026ldquo;focus on your apps and we’ll take care of the rest\u0026rdquo;. And it remains a strong value proposition.\nBeware of vendor lock-in This is particularly relevant if you choose for the Parse Server hosting category. Parse Server and Parse Dashboard are open source so you might be wondering why vendor lock-in is a potential issue. Let me explain.\nParse Server was open sourced with a BSD license model. While I’m not a software licensing expert, my understanding of this license is that it allows users to modify the source without releasing such modifications. Sooner or later, Parse Server hosting providers will begin to add their own features and I can bet you that not all of them will be willing to contribute back to the open source Parse Server. Every feature from a Parse Server hosting provider that is not present in the open source Parse Server is a potential lock-in! Think of what will happen if your new provider shuts down. Obviously, Parse Server will remain open source so there will be alternative providers. However, you’ll be stuck with those custom features that are no longer supported.\nOther possible symptoms of potential vendor lock-in are unclear terms and conditions with regard to your data and migration in the event of a shutdown. Let’s be frank: Parse.com has provided a decent migration plan and, as far as I can tell, they’re doing their best to support us through the process. Your next provider should be able to commit upfront to something similar or better in case the undesirable happens.\nMoreover, you’d be much better off with a Parse Server hosting provider that is actively involved in adding features and fixing bugs in the open source Parse Server repository over one that just promises to occasionally give back with no evidence whatsoever.\nBeware of elaborate Freemium offers As the adage goes \u0026ldquo;Once bitten, twice shy!\u0026rdquo; With the unprecedented shutdown of Parse.com, you definitely do\nnot want to migrate your apps only to face another shutdown. So be careful with very attractive freemium offers.\nOne of my college professors often reminded us that \u0026ldquo;there’s no such thing as a free lunch\u0026rdquo; and I think he was right.\nAlthough the announcement of Parse.com’s shutdown didn’t\nprovide details of why Facebook pulled the plugs, the main reason is apparently $$$ as explained in\nthis New York Times article\nwhich, remarkably, was termed by Parse.com’s CEO, as\n\u0026ldquo;pretty accurate\u0026rdquo;.\nYou might also find\nthis article\non the dangers and benefits of the freemium model interesting.\nParse Server is not a clone of Parse.com With the release of the open source Parse Server, one would expect that the Parse.com code was cleaned up\nand open sourced. However, that is definitely not the case. While Parse Server has strong similarities to Parse.com,\nit is only a look-alike and not a clone as clearly indicated in\nthis discussion involving Parse.com engineers.\nSo bear in mind that there are difference some of which are listed on the Parse Server\nwiki. If your app relies\nheavily on any of those features (e.g. background jobs or push notification support for Windows Phone), then Parse Server as-is does not (yet) meet your needs. The good news is that, now that it’s open source, you can (and should) contribute to making Parse Server better. You don’t have to wait until someone else builds it; you can make Parse Server richer by contributing new features! Alternatively, you could look for other ways to realize the missing functionality. Going back to the background jobs example, you could find other means to schedule background jobs or use a Parse Server provider like back4app which already implements that feature. Similarly, you could consider a separate service for multi-platform push notifications which can later be integrated with Parse Server via the\nPushAdapter mechanism.\nAnother implication of the fact that Parse Server is not a clone of Parse.com is that there could be bugs and other issues that make it unfit for production especially for more complex apps, at least for the time being. While it is difficult to assess how production-ready Parse Server currently is, this\nsomewhat outdated discussion might provide some insights.\nMake your app as future-proof as possible With the migration from Parse.com to Parse Server, you have to release a new version of your apps with at least the Parse endpoint changed from api.parse.com to whatever endpoint you’ll be using. While you’re at it, make sure to enrich your app with the intelligence of being able to dynamically switch to a new backend should the need ever arise in the future. In that way, you’ll have one thing less to worry about if the undesirable happens with your next provider. This is just one way you can make your apps future-proof.\nHow I chose my replacement for Parse.com In Part 2, I will explain how I applied the above guidelines in choosing a replacement for Parse.com. Watch out for the follow up post!\nConclusion In this article, I’ve given you some food for thought as you decide where to migrate your Parse.com-hosted apps to.\nI’ve deliberately not recommended any particular self-hosting service or Parse Server hosting provider as there is\nno one-size-fits-all solution. You’ll need to make that choice based on your app needs and your answers to the\n(difficult?) questions posed in the article. In a sequel blog post, I will explain how I decided on my replacement for\nParse.com, highlighting strong and weak points of the Parse Server providers that I tested. If you still can’t make\nany headway, feel free to get in touch or leave a comment. Also do not hesitate to share your thoughts on the subject!\nReferences and interesting reads Radek Zaleski (February 2016). Parse Is Done. What Now? 5 Tips How to Proceed with Migration. Retrieved from https://www.netguru.co/blog/parse-is-done.-what-now-5-tips-how-to-proceed-with-migration\nRon Palmeri (January 30, 2016). Why Facebook’s Parse shutdown is good news for all of us. Retrieved from http://venturebeat.com/2016/01/30/why-facebooks-parse-shutdown-is-good-news-for-all-of-us/\nMarian Ignev (April 28, 2016). Dangers and benefits of the freemium model — What did we learn out of Parse’s shutdown? Retrieved from https://medium.com/@sashidoio/dangers-and-benefits-of-the-freemium-model-what-did-we-learn-out-of-parses-shutdown-79becb215c84#.ggsb3gf6l\nAlysson Melo (May 3, 2016). Parse alternative: Self-hosting or Parse hosting provider? Retrieved from http://blog.back4app.com/2016/05/03/parse-alternative/\nAlysson Melo (June 15, 2016). Firebase vs. Parse Server. Retrieved from http://blog.back4app.com/2016/06/15/firebase-parse\nAlysson Melo (June 21, 2016). How much cost Parse self-hosting? Retrieved from http://blog.back4app.com/2016/06/21/parse-aws\nMike Isaac and Quentin Hardy (January 28, 2016). Facebook to Shut Down Parse, Its Platform for Mobile Developers. Retrieved from http://bits.blogs.nytimes.com/2016/01/28/facebook-to-shut-down-parse-its-platform-for-mobile-developers/?_r=1\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/how-i-chose-my-replacement-for-parse-com/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/how-i-chose-my-replacement-for-parse-com/parse.com-post-header.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen I first read the announcement that Parse.com would shut down on January 28th 2017, I went from\u003cbr\u003e\ndisbelief (it’s probably an early April fool’s joke) to rage (how could they do that?!) to sadness (oh no! it was a\u003cbr\u003e\ngreat service) and finally to utter confusion (where do I go from here and what do I do with my apps –\u003cbr\u003e\n\u003ca href=\"https://github.com/sidiabale/parse4cn1\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eparse4cn1\u003c/a\u003e, two \u003ca href=\"https://www.smash-ict.com/#projects\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eMVPs\u003c/a\u003e for clients\u003cbr\u003e\nand an upcoming rewrite of\u003cbr\u003e\n\u003ca href=\"https://play.google.com/store/apps/details?id=com.mosync.app_Medex\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eMedex\u003c/a\u003e for which I was planning to use\u003cbr\u003e\nParse.com as backend?). A few months down the line, a lot has happened such as the release of the open source\u003cbr\u003e\nParse Server (yay!) and subsequently the Parse Dashboard. However, I still had to decide what do with my apps\u003cbr\u003e\nand I guess you have to as well.\u003c/p\u003e","title":"How I Chose my Replacement for Parse.com"},{"content":"\nOne of the big decisions we made a while back was to build the new GUI builder on top of Codename One itself,\nwe extended that decision three months ago with the decision to build the Codename One settings in Codename One\nand then deciding to make it the default preferences UI for all IDE’s…​\nThose were great decisions in retrospect, they helped us consolidate code across the different IDE’s.\nFurthermore using Codename One is far simpler than Swing/SWT or FX. At least for us…​\nThe look of these new UI’s is far more modern than the Swing alternative. Unlike these other API’s we\ndesigned Codename One for mobile and not for desktop so basic desktop staples like scrollbars, tooltips, menubars etc.\nweren’t available.\nWe worked around the menu bar functionality using native code and we added scrolling based on the logic\nhere (this isn’t yet in the current shipping version).\nWe made slight improvements to that code that also recalculate the height and allow for arrows. One of the improvements\nthat did make the current version is support for tooltips which are convenient for desktop applications.\nWe added some initial work around tooltips based on the pointerHover callbacks which now have a mapping\nin desktop apps but this isn’t turned on by default. We chose to use the glasspane for the tooltips instead of the\nlayered pane which might have an issue when displaying a tooltip on the toolbar.\nSince we are pretty late in the 3.5 release cycle we chose not to expose any of this in the API. Our\ncurrent line of thinking is to create an overarching com.codename1.ui.desktop package that will include\ntools for desktop API’s such as the ability to define a menu bar, tooltips, scrollbars and other desktop oriented\ncapabilities.\nIf this is something you find interesting please let us know in the comments, we’d like feedback about the type\nof features/functionality you would expect in such an API. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nUlises Escobar — July 19, 2016 at 5:13 pm (permalink) Ulises Escobar says:\nI wish I could move from one text field to another with Tab\nShai Almog — July 20, 2016 at 4:27 am (permalink) Shai Almog says:\nThis should already work in the current versions and even in the simulator.\nbeck — July 20, 2016 at 6:47 am (permalink) beck says:\nI dont know it is related or not but It’d be really really cool if we can see the component highlighted by border or smth when it is selected in component inspector. Sometime it takes much time to search the component in component inspector\nShai Almog — July 21, 2016 at 3:49 am (permalink) Shai Almog says:\nProbably not related but yes I’d like that too. But we’re not doing this for the current code as it’s a bit limited.\nWe have some very interesting ideas moving forward with the simulator and the component inspector.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/scrollbars-tooltips/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/scrollbars-tooltips/scrollbar.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the big decisions we made a while back was to build the new GUI builder on top of Codename One itself,\u003cbr\u003e\nwe extended that decision three months ago with the decision to build the Codename One settings in Codename One\u003cbr\u003e\nand then deciding to make it the default preferences UI for all IDE’s…​\u003c/p\u003e\n\u003cp\u003eThose were great decisions in retrospect, they helped us consolidate code across the different IDE’s.\u003cbr\u003e\nFurthermore using Codename One is far simpler than Swing/SWT or FX. At least for us…​\u003c/p\u003e","title":"Scrollbars \u0026 Tooltips"},{"content":"\nWe got a lot of requests from developers over the years to do an iOS style alphabet side scroll. Some developers\nimplements such scrolling but no one made it generic or contributed it back. So a recent stack overflow question\ngot me thinking about how easy it would be to actually implement something like that and I decided to try…​\nI ended up building this in 10 minutes and the concept is remarkably simple. I have two containers, one contains\nthe list of the people and the other one contains the letters used for these people. Notice that I chose to only use\nletters that used in the names, I could have just hardcoded the English alphabet but chose to avoid that as this\nwould break for internationalization and include letters that might not be common in such cases such as ‘Z’.\nThanks to the usage of layered layout the containers just appear on top of one another, notice that in the sample\ncode below I had to cancel the default scrollability of the form to allow the two containers to have their own\nscrollability. The scrolling isn’t nested in this case since these are two separate containers that just happen\nto be one on top of the other.\nWe scroll to the selected component by finding it as we loop over the components in the actual container and\nusing scrollComponentToVisible which is pretty convenient for this case.\nCheck out the live demo on the right side thanks to the JavaScript port\nYou can also check out the full project on github here and see\nthe relevant code below:\nString[] characters = { \u0026quot;Tyrion Lannister\u0026quot;, \u0026quot;Jaime Lannister\u0026quot;, \u0026quot;Cersei Lannister\u0026quot;, \u0026quot;Daenerys Targaryen\u0026quot;, \u0026quot;Jon Snow\u0026quot;, \u0026quot;Petyr Baelish\u0026quot;, \u0026quot;Jorah Mormont\u0026quot;, \u0026quot;Sansa Stark\u0026quot;, \u0026quot;Arya Stark\u0026quot;, \u0026quot;Theon Greyjoy\u0026quot;, \u0026quot;Bran Stark\u0026quot;, \u0026quot;Sandor Clegane\u0026quot;, \u0026quot;Joffrey Baratheon\u0026quot;, \u0026quot;Catelyn Stark\u0026quot;, \u0026quot;Robb Stark\u0026quot;, \u0026quot;Ned Stark\u0026quot;, \u0026quot;Robert Baratheon\u0026quot;, \u0026quot;Viserys Targaryen\u0026quot;, \u0026quot;Varys\u0026quot;, \u0026quot;Samwell Tarly\u0026quot;, \u0026quot;Bronn\u0026quot;,\u0026quot;Tywin Lannister\u0026quot;, \u0026quot;Shae\u0026quot;, \u0026quot;Jeor Mormont\u0026quot;,\u0026quot;Gendry\u0026quot;,\u0026quot;Tommen Baratheon\u0026quot;,\u0026quot;Jaqen H'ghar\u0026quot;,\u0026quot;Khal Drogo\u0026quot;,\u0026quot;Davos Seaworth\u0026quot;, \u0026quot;Melisandre\u0026quot;,\u0026quot;Margaery Tyrell\u0026quot;,\u0026quot;Stannis Baratheon\u0026quot;,\u0026quot;Ygritte\u0026quot;,\u0026quot;Talisa Stark\u0026quot;,\u0026quot;Brienne of Tarth\u0026quot;,\u0026quot;Gilly\u0026quot;, \u0026quot;Roose Bolton\u0026quot;,\u0026quot;Tormund Giantsbane\u0026quot;,\u0026quot;Ramsay Bolton\u0026quot;,\u0026quot;Daario Naharis\u0026quot;,\u0026quot;Missandei\u0026quot;,\u0026quot;Ellaria Sand\u0026quot;, \u0026quot;The High Sparrow\u0026quot;,\u0026quot;Grand Maester Pycelle\u0026quot;,\u0026quot;Loras Tyrell\u0026quot;,\u0026quot;Hodor\u0026quot;,\u0026quot;Gregor Clegane\u0026quot;,\u0026quot;Meryn Trant\u0026quot;, \u0026quot;Alliser Thorne\u0026quot;,\u0026quot;Othell Yarwyck\u0026quot;,\u0026quot;Kevan Lannister\u0026quot;,\u0026quot;Lancel Lannister\u0026quot;,\u0026quot;Myrcella Baratheon\u0026quot;, \u0026quot;Rickon Stark\u0026quot;,\u0026quot;Osha\u0026quot;,\u0026quot;Janos Slynt\u0026quot;,\u0026quot;Barristan Selmy\u0026quot;,\u0026quot;Maester Aemon\u0026quot;,\u0026quot;Grenn\u0026quot;,\u0026quot;Hot Pie\u0026quot;, \u0026quot;Pypar\u0026quot;,\u0026quot;Rast\u0026quot;,\u0026quot;Ros\u0026quot;,\u0026quot;Rodrik Cassel\u0026quot;,\u0026quot;Maester Luwin\u0026quot;,\u0026quot;Irri\u0026quot;,\u0026quot;Doreah\u0026quot;,\u0026quot;Eddison Tollett\u0026quot;,\u0026quot;Podrick Payne\u0026quot;, \u0026quot;Yara Greyjoy\u0026quot;,\u0026quot;Selyse Baratheon\u0026quot;,\u0026quot;Olenna Tyrell\u0026quot;,\u0026quot;Qyburn\u0026quot;,\u0026quot;Grey Worm\u0026quot;,\u0026quot;Meera Reed\u0026quot;,\u0026quot;Shireen Baratheon\u0026quot;, \u0026quot;Jojen Reed\u0026quot;,\u0026quot;Mace Tyrell\u0026quot;,\u0026quot;Olly\u0026quot;,\u0026quot;The Waif\u0026quot;,\u0026quot;Bowen Marsh\u0026quot; }; Toolbar.setGlobalToolbar(true); Form f = new Form(\u0026quot;Letter Scroll\u0026quot;, new LayeredLayout()); f.setScrollable(false); Container characterContainer = new Container(BoxLayout.y()); Container lettersContainer = new Container(BoxLayout.y()); characterContainer.setScrollableY(true); lettersContainer.setScrollableY(true); char lastLetter = 0; Arrays.sort(characters, new CaseInsensitiveOrder()); for(String character : characters) { MultiButton mb = new MultiButton(character); characterContainer.add(mb); char c = Character.toUpperCase(character.charAt(0)); if(c != lastLetter) { lastLetter = c; Button btn = new Button(\u0026quot;\u0026quot; + lastLetter); lettersContainer.add(btn); btn.getAllStyles().setPadding(0, 0, 0, 0); btn.getAllStyles().setMargin(0, 0, 0, 0); btn.addActionListener(e -\u0026gt; { for(Component cmp : characterContainer) { MultiButton m = (MultiButton)cmp; if(Character.toUpperCase(m.getTextLine1().charAt(0)) == c) { characterContainer.scrollComponentToVisible(m); return; } } }); } } f.add(characterContainer). add(BorderLayout.east(lettersContainer)); f.show(); Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — July 19, 2016 at 7:39 am (permalink) Chidiebere Okwudire says:\nNice and short! Would it be possible to animate the alphabet list as happens on some phones. So pressing down on the list and scrolling causes the list to kind of bump out around the position?\nRoss Taylor — July 19, 2016 at 8:56 am (permalink) Ross Taylor says:\nNeat. However when I scroll the list, the title bar disappears and is turned into a blank space. Is this suppose to happen?\nChidiebere Okwudire — July 19, 2016 at 1:29 pm (permalink) Chidiebere Okwudire says:\nOne more thing: Is there a catalog of these handy features? Something as simple as an appendix in the user manual, for example, that refers to the corresponding blog posts. I don’t know about others but it happens quite often that I want to do something and I remember once reading about it but I’m not sure where and how to find the post quickly. It would be nice if there’s an overview and also make these handy utilties more visible to newcomers.\nShai Almog — July 20, 2016 at 4:20 am (permalink) Shai Almog says:\nYou can just set the UIID of one of them to selected or even just increase the font or padding so this would be easy and should \u0026ldquo;just work\u0026rdquo;. The main challenge is detecting where you are in the scroll. When a user scrolls by pressing a button this should be pretty easy but when the user scrolls via touch this might be more challenging. You can use the scroll listener which should be pretty easy to work with and then hack something with getComponentAt(x, y) to find the location you are currently in.\nAnother approach which I haven’t tested but might be more elegant is this:\nAfter constructing and initializing the layout loop over the component and assign a Y range to every alphabet letter. getY() of a specific component should return the right scroll offset and this should work nicely with the scroll listener.\nShai Almog — July 20, 2016 at 4:20 am (permalink) Shai Almog says:\nThat’s a bug in the JavaScript port, Steve just committed a fix for this.\nShai Almog — July 20, 2016 at 4:23 am (permalink) Shai Almog says:\nThe problem with that is that someone needs to maintain it and if something doesn’t make it there then people assume it doesn’t exist. Sometimes it’s better off to have nothing than to have something that’s half done.\nThe thing I’d really like to add to the developer guide is a big section on cn1libs covering usage of the top cn1libs e.g. parse, maps, bouncy castle etc. but I can’t seem to find the time/person to do that.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/alphabet-scroll/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/alphabet-scroll/alphabet-scroll.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe got a lot of requests from developers over the years to do an iOS style alphabet side scroll. Some developers\u003cbr\u003e\nimplements such scrolling but no one made it generic or contributed it back. So a recent stack overflow question\u003cbr\u003e\ngot me thinking about how easy it would be to actually implement something like that and I decided to try…​\u003c/p\u003e\n\u003cp\u003eI ended up building this in 10 minutes and the concept is remarkably simple. I have two containers, one contains\u003cbr\u003e\nthe list of the people and the other one contains the letters used for these people. Notice that I chose to only use\u003cbr\u003e\nletters that used in the names, I could have just hardcoded the English alphabet but chose to avoid that as this\u003cbr\u003e\nwould break for internationalization and include letters that might not be common in such cases such as ‘Z’.\u003c/p\u003e","title":"Alphabet Scroll"},{"content":"\nWith the pending release and some important issues we decide to make a minor update to the plugin today\nto introduce some improvements. We want the GUI builder to stabilize so we can finally crown it as \u0026ldquo;the\u0026rdquo; GUI\nbuilder rather than as \u0026ldquo;the new\u0026rdquo; GUI builder. To do that we need you guys to use it and submit issues, we also\nneed you to use the latest version…​\nWith this release we added a lot of bug fixes and a few minor cosmetic improvements that should help narrow\nthe gap with the old GUI builder. We are in the final stretch for 3.5 which means this is the time where features\nmight be dropped. The biggest risk right now is the new build servers, we really want to do this before the 3.5\nrelease but with our current workload this might get delayed to September.\nOn stackoverflow things have been going on as usual:\nHow to add Google Map Container to GUI builder on Codename One? When asking about the gui builder you need to be very clear about which version you are using, the old or the new GUI builder.\nRead on stackoverflow…​\nHow do I get my button to redirect to a web page within the app? Generally you need to use the BrowserComponent but obviously there is more nuance than that…​\nRead on stackoverflow…​\nDatabases in Codename One Storage on mobile is quite different to desktop/server so tools such as MySQL are just not available to developers…​\nRead on stackoverflow…​\nUWP issue UWP still has a lot of bugs, it will be at alpha/beta grade for the 3.5 release as it’s still a completely new port.\nIt’s even new for Microsoft with whom we are experiencing a long conversation trying to get apps thru the store\napproval process.\nRead on stackoverflow…​\nHow Do I override button appearance in Codename One? You need to override every element you want to control, the biggest pitfall for most developers is overriding border.\nYou need to set it to empty if you don’t want a border…​\nRead on stackoverflow…​\nMath class functionality in cn1 A lot of the Codename One functionality is within com.codename1 packages to avoid the complexity of re-implementing/testing\nfor every VM we support.\nRead on stackoverflow…​\nHow to integrate ads to android app in codename one Providing a link to the specific ad library you used when you ask the original question often helps…​\nRead on stackoverflow…​\nOpen dialog disappears after screen turns off Suspend/Resume behavior when the screensaver kicks in is really difficult to understand and follow sometimes.\nRead on stackoverflow…​\niOS build failure upon using CN1Bluetooth Here is another reason to speed up the migration to xcode 7.x…​\nRead on stackoverflow…​\nHow do I apply multiple layouts in Codename One? Nesting of containers is a concept that’s pretty hard to understand in all frameworks and not just Codename One…​\nRead on stackoverflow…​\nActionlistener in the command of the side menu opens blank form but the same in the button action listener opens the form normally Sometimes layouts act out in odd ways, 9 times out of 10 it’s an EDT violation but there are odd edge cases where it’s not.\nRead on stackoverflow…​\nToolbar search customization We didn’t expose ways to customize the search functionality too much but because the toolbar is so darn\nflexible you can easily customize it yourself and we still have the sample that predated the builtin search.\nRead on stackoverflow…​\nHow do I avoid Android always for Bluetooth permission when running BTDemo Bluetooth prompts are shown based on specific calls into the library…​\nRead on stackoverflow…​\nsetPreferredSize alernative calling for TextBox widths and heights not working When you need to position/size a component think layout first and component size last. Once you get the layout right\neverything else should be trivial.\nRead on stackoverflow…​\nIssue on setting shadow in the container using nine piece border wizard Cutting 9-piece images and understanding how to map the design to the actual component hierarchy is something\nwe still debate after 10 years of working with this API…​\nRead on stackoverflow…​\nHow do I create an action for a button that I created in the GUI Builder on CodenameOne? Hopefully the migration to the new GUI builder will make this process simpler.\nRead on stackoverflow…​\nMacros dont working with POJOs The JSON/POJO mapping thru mirah is a one of those tools I’m totally unfamiliar with…​\nRead on stackoverflow…​\nChanging the width of hamburger menu Theme constants are a great tool that you can also use within your own code to control dynamic application functionality.\nRead on stackoverflow…​\nList scroll to the selected item A picture is worth a thousand words, had I had a picture in that question when it was initially asked this would have\nbeen much easier…​\nRead on stackoverflow…​\nOpen picture on iOS with execute() In retrospect the canExecute() method states is too confusing to most developers who often misinterpret the null\nvalue returned.\nRead on stackoverflow…​\nText not showing using Roboto or Keep Calm Medium font on iOS Fonts work very differently between Android/iOS and we make a great deal of effort trying to make them behave\n\u0026ldquo;seamlessly\u0026rdquo;. This seamlessness works when we have control (e.g. the theme) but is somewhat broken in the lower\nlevel API’s.\nRead on stackoverflow…​\nDate gives different results on iOS and Android You shouldn’t normally rely on the toString() method semantics. To be fair we should try and make them identical to other\nJava platforms but it is still not the right way to work with dates…​\nRead on stackoverflow…​\nApp logs on production I’m not 100% sure I get the question but generally you can listen to exceptions on the event dispatch thread which\nis a feature many developers aren’t aware of…​\nRead on stackoverflow…​\nCan swift code be used in Codename One native code instead of Objective-C There is a long answer with quite a lot of detail but the bottom line is: probably. But there is no reason to do that…​\nRead on stackoverflow…​\nCan the arguments be named as desired when using native code? Yes for platforms other than iOS. Objective-C considers argument names to be a part of the method signature so if\nyou change the names everything will fail. That’s why we named them in this particular way.\nRead on stackoverflow…​\nHow do you show a video in it’s correct dimensions? Sizing peer and native components especially ones that require loading such as video or html is really problematic.\nThat’s why we always recommend placing them in the center of the border layout (with the default setting). This\nstretches them over the entire available space so their preferred size will be irrelevant.\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xiv/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xiv/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWith the pending release and some important issues we decide to make a minor update to the plugin today\u003cbr\u003e\nto introduce some improvements. We want the GUI builder to stabilize so we can finally crown it as \u0026ldquo;the\u0026rdquo; GUI\u003cbr\u003e\nbuilder rather than as \u0026ldquo;the new\u0026rdquo; GUI builder. To do that we need you guys to use it and submit issues, we also\u003cbr\u003e\nneed you to use the latest version…​\u003c/p\u003e","title":"Questions of the Week XIV"},{"content":"\nWith the fix for issue #1694 we can now have\na moderately simple method of creating an\nAutoCompleteTextField\nthat works with a webservice. This has been requested quite often and was quite frustrating to implement in the past\nit is now relatively simple with just a few lines of code.\nCheck out the live demo using the JavaScript port on the right side here\nYou can see the full working sample of this project in this\ngithub repository notice that you will need to fill\nin a google web API key for the webservice to work as explained\nhere.\nThe sample works relatively simply, instead of passing a fixed list of elements we pass a model to the auto\ncomplete and then just modify the model. The auto complete updates itself based on the modification to the\nmodel which is completely asynchronous.\nThe main thing we need to do is override the filter method and mutate the model there.\nCheck out the main code of this app below:\nForm hi = new Form(\u0026quot;AutoComplete\u0026quot;, new BoxLayout(BoxLayout.Y_AXIS)); if(apiKey == null) { hi.add(new SpanLabel(\u0026quot;This demo requires a valid google API key to be set in the constant apiKey, \u0026quot; + \u0026quot;you can get this key for the webservice (not the native key) by following the instructions here: \u0026quot; + \u0026quot;https://developers.google.com/places/web-service/get-api-key\u0026quot;)); hi.getToolbar().addCommandToRightBar(\u0026quot;Get Key\u0026quot;, null, e -\u0026gt; Display.getInstance().execute(\u0026quot;https://developers.google.com/places/web-service/get-api-key\u0026quot;)); hi.show(); return; } final DefaultListModel\u0026lt;String\u0026gt; options = new DefaultListModel\u0026lt;\u0026gt;(); AutoCompleteTextField ac = new AutoCompleteTextField(options) { @Override protected boolean filter(String text) { if(text.length() == 0) { return false; } String[] l = searchLocations(text); if(l == null || l.length == 0) { return false; } options.removeAll(); for(String s : l) { options.addItem(s); } return true; } }; ac.setMinimumElementsShownInPopup(5); hi.add(ac); hi.show(); Notice that it relies on a call to the Google webservice as such:\nString[] searchLocations(String text) { try { if(text.length() \u0026gt; 0) { ConnectionRequest r = new ConnectionRequest(); r.setPost(false); r.setUrl(\u0026quot;https://maps.googleapis.com/maps/api/place/autocomplete/json\u0026quot;); r.addArgument(\u0026quot;key\u0026quot;, apiKey); r.addArgument(\u0026quot;input\u0026quot;, text); NetworkManager.getInstance().addToQueueAndWait(r); Map\u0026lt;String,Object\u0026gt; result = new JSONParser().parseJSON(new InputStreamReader(new ByteArrayInputStream(r.getResponseData()), \u0026quot;UTF-8\u0026quot;)); String[] res = Result.fromContent(result).getAsStringArray(\u0026quot;//description\u0026quot;); return res; } } catch(Exception err) { Log.e(err); } return null; } Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nCarlos — July 14, 2016 at 3:46 pm (permalink) Carlos says:\nAwesome, thank you, but I would take\noptions.removeAll();\nright before:\nif (text.length() == 0)\nSo if the user erase to empty the textfield, the combo with the completions disappears.\nShai Almog — July 15, 2016 at 4:01 am (permalink) Shai Almog says:\nMakes sense, thanks!\nDiamond — July 15, 2016 at 9:03 am (permalink) Diamond says:\nHi Shai,\nHow do I style the AutoCompleteTextField List selected item? The default color is orange on my theme and I will like to change it to blue. I’ve tried styling \u0026ldquo;AutoCompleteList\u0026rdquo;, but it doesn’t help… the whole list got changed to blue and I want only one item to change. I also tried AutoCompleteListRenderer and AutoCompleteListRendererFocus, not helping either.\nShai Almog — July 16, 2016 at 4:30 am (permalink) Shai Almog says:\nHi Diamond,\nyou can use setCompletionRenderer() to set a custom renderer. It uses the standard list renderer with ListRendererFocus and ListRenderer UIID’s.\nDiamond — July 19, 2016 at 8:07 pm (permalink) Diamond says:\nHi Shai,\nIs it possible to change the AutoComplete popup to have an icon and text?\nAlso, is it possible to clear the text input if user didn’t choose from the popup? This is to force only suggested values in the TextField.\nLastly, Can I make the popup list break line for long text?\nIf any of these are possible, can you please guide on how to achieve this.\nThank you.\nShai Almog — July 20, 2016 at 4:26 am (permalink) Shai Almog says:\nHi Diamond,\nIt’s a renderer so you can do everything a renderer can do with its standard limitations.\nSo icon should be easy just use your data model when you fetch the information to render the icon and potentially more than one row.\nHowever, dynamic line breaking is problematic with renderers so that won’t work.\nI’d love to have a way to use components in box Y instead of list+renderer for this component and the original issue actually suggested going in that direction.\nDiamond — July 22, 2016 at 10:57 am (permalink) Diamond says:\nac.getHintLabel().setUIID(\u0026ldquo;CustomHintUIID\u0026rdquo;); is throwing a nullPointer exception, is there a way to fix this?\nShai Almog — July 23, 2016 at 4:44 am (permalink) Shai Almog says:\nThat’s standard behavior in a text area/field as well… If you didn’t call setHint(…) first the label wasn’t created so it will be null.\nemaalam — April 27, 2017 at 12:56 pm (permalink) emaalam says:\nHi Shai\ni have two problems first i want to add a map in AutoCompleteTextField exactlly in DefaultListModel and after i want to add the the listmodel in my autocompletetextField second : how can i get the text when i select an element in the AutoCompleteTextField\nemaalam — April 27, 2017 at 3:33 pm (permalink) emaalam says:\nhi Shai\nplease answer me here http://stackoverflow.com/qu…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/dynamic-autocomplete/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/dynamic-autocomplete/dynamic-autocomplete.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWith the fix for \u003ca href=\"https://github.com/codenameone/CodenameOne/issues/1694\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eissue #1694\u003c/a\u003e we can now have\u003cbr\u003e\na moderately simple method of creating an\u003cbr\u003e\n\u003ca href=\"/javadoc/com/codename1/ui/AutoCompleteTextField/\"\u003eAutoCompleteTextField\u003c/a\u003e\u003cbr\u003e\nthat works with a webservice. This has been requested quite often and was quite frustrating to implement in the past\u003cbr\u003e\nit is now relatively simple with just a few lines of code.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eCheck out the live demo using the JavaScript port on the right side here\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eYou can see the full working sample of this project in this\u003cbr\u003e\n\u003ca href=\"https://github.com/codenameone/AutoCompleteWebservice\" target=\"_blank\" rel=\"noopener noreferrer\"\u003egithub repository\u003c/a\u003e notice that you will need to fill\u003cbr\u003e\nin a google web API key for the webservice to work as explained\u003cbr\u003e\n\u003ca href=\"https://developers.google.com/places/web-service/get-api-key\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere\u003c/a\u003e.\u003c/p\u003e","title":"Dynamic AutoComplete"},{"content":"\nOver the weekend LokeHansen posted a\nnew series of youtube videos covering the process of creating a game in Codename One. I really enjoyed watching\nthem as his teaching style is far more accessible than mine (I tend to be overly technical without noticing).\nI’m guessing the videos below might be a bit too simple for some of our typical readers but if you have friends or\nkids who like games and didn’t connect to coding this might be a great tool to get them started, I’ve embedded\nthe first 3 videos in the series below. Check them out and\nsubscribe to his channel for more.\nIf you are doing such tutorials/guides that are relevant to Codename One just drop us a line and we’d be happy\nto help you spread the word.\nIntroduction Part II Part III Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/how-to-build-a-clicking-tapping-game-tutorial/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/how-to-build-a-clicking-tapping-game-tutorial/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOver the weekend \u003ca href=\"https://www.youtube.com/channel/UCULoPvQDYiLy0yAnHXy50Eg\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eLokeHansen\u003c/a\u003e posted a\u003cbr\u003e\nnew series of youtube videos covering the process of creating a game in Codename One. I really enjoyed watching\u003cbr\u003e\nthem as his teaching style is far more accessible than mine (I tend to be overly technical without noticing).\u003c/p\u003e\n\u003cp\u003eI’m guessing the videos below might be a bit too simple for some of our typical readers but if you have friends or\u003cbr\u003e\nkids who like games and didn’t connect to coding this might be a great tool to get them started, I’ve embedded\u003cbr\u003e\nthe first 3 videos in the series below. Check them out and\u003cbr\u003e\n\u003ca href=\"https://www.youtube.com/channel/UCULoPvQDYiLy0yAnHXy50Eg\" target=\"_blank\" rel=\"noopener noreferrer\"\u003esubscribe to his channel\u003c/a\u003e for more.\u003c/p\u003e","title":"How to Build a Clicking (Tapping) Game Tutorial"},{"content":"\nWe had a couple of posts in the past about the new GUI builder but we didn’t have a \u0026ldquo;how to\u0026rdquo; guide yet. In this\npost we’ll try to go step by step over the process of using the GUI builder and understanding its inner workings.\nWe’ll also try to clarify conclusively the role the new GUI builder plays in the toolchain and the migrations process\nfrom the old GUI builder.\nHow do I Know if I’m Using the new GUI Builder? The old GUI builder is in the designer tool, it’s a Swing application that includes the theme design etc.\nIt generates a Statemachine class that contains all the main user GUI interaction code.\nThe new GUI builder is a standalone application that you launch from the right click menu by selecting a form\nas explained below. Here are screenshots of both to help you differentiate:\nFigure 1. The old GUI builder\nFigure 2. The same UI in the new GUI builder\nWhy two GUI Builders?\nThe original old GUI builder has it’s roots in our work at Sun Microsystems. We developed it as part of the\ndesigner tool and we store it’s data in the resource file. When creating an application for the old GUI\nbuilder you must define it as a \u0026ldquo;visual application\u0026rdquo; which will make it use the old GUI builder.\nThe roots of this GUI builder are pretty old. When we initially built it we still had to support feature phones with\n2mb of RAM and the iPad wasn’t announced yet. Due to that we picked an architecture that made sense for those\nphones with a greater focus on navigation and resource usage. Newer mobile applications are rivaling desktop\napplications in complexity and in those situations the old GUI builder doesn’t make as much sense\nHello World Creating a hello world app in the new GUI builder is actually pretty trivial, you need to start with a regular handcoded\napplication. Not a GUI builder application as it refers to the old GUI builder!\nCreating a new hello world is similar for all IDE’s. We cover this process in the getting started tutorials for all the\nIDE’s:\nNetBeans,\nIntelliJ \u0026amp;\nEclipse.\n__ The new GUI builder requires Java 8. This means the IDE itself needs to run on top of Java 8! Following are the instructions for creating a form and launching the GUI builder. While they are similar there\nare minor IDE differences. Usage of the GUI builder is identical in all IDE’s as the GUI builder is a separate\napplication.\nNetBeans In NetBeans you need to follow these 4 steps:\nFigure 3. Right click the package select New → Other\nFigure 4. In the Codename One section select the GUI builder form\nFigure 5. Type in the name of the form and click finish, you can change the type to be a Container or Dialog\nFigure 6. Launch the GUI builder thru the right click menu on the newly created file\nIntelliJ/IDEA In IntelliJ you need to follow these 3 steps:\nFigure 7. Right click the package select New → Codename One Form (or Dialog/Container)\nFigure 8. Type in a name for the new form\nFigure 9. Launch the GUI builder thru the right click menu on the newly created file\nEclipse In Eclipse you need to follow these 4 steps:\nFigure 10. Right click the package select New → Other\nFigure 11. In the Codename One section select the GUI builder option\nFigure 12. Type in the name of the form and click finish, you can change the type to be a Container or Dialog\nFigure 13. Launch the GUI builder thru the right click menu on the newly created file\nBasic Usage Notice that the UI of the new GUIBuilder might change in the future but the basic concepts should remain the same.\nWe control the GUI builder via it’s main toolbar, notice that your changes will apply only when you click\nthe Save button on the right:\nFigure 14. The features of the main toolbar\nThe sidebar includes the functionality we will be working with most of the time:\nFigure 15. The sidebar options\nWe’ll start by selecting the Component Palette and dragging a button into the UI:\nFigure 16. You can drag any component you want from the sidebar to the main UI\nYou can then re-arrange the order of the components but since they use the default FlowLayout you can’t\nposition them anywhere you want. We’ll discuss arrangement and layout managers in the GUI builder below.\nYou should have a UI that looks like this when you select the button you placed, it shows the properties that you\ncan modify and the events that you can bind:\nFigure 17. Properties allow you to customize everything about a component\nYou can edit any property by clicking it, this launches the appropriate UI. E.g. for image properties you\nare presented with an image dialog that allows you to pick an image from the resource file:\nFigure 18. You can edit properties such as the icon property by clicking it, this opens the image selection dialog\n__ | You can add an image to the resource file using the designer tool as covered in\nthis video For things like setting the text on the component we can use a convenient \u0026ldquo;long click\u0026rdquo; on the component to\nedit the text in place as such:\nFigure 19. Use the long click to edit the text \u0026ldquo;in place\u0026rdquo;\nEvents When a component supports broadcasting events you can bind such events by selecting it, then selecting\nthe events tab and clicking the button matching the event type\nFigure 20. The events tab is listed below supported event types can be bound above\nOnce an event is bound the IDE will open to the event code e.g.:\npublic void onButton_1ActionEvent(com.codename1.ui.events.ActionEvent ev) { } __ | Some IDE’s only generate the project source code after you explicitly build the project so if your code needs\nto access variables etc. try building first Within the code you can access all the GUI components you defined with the gui_ prefix e.g. Button_1 from the\nUI is represented as:\nprivate com.codename1.ui.Button gui_Button_1 = new com.codename1.ui.Button(); Layouts In this section we won’t try to discuss layouts in depth as this is a deep and complex subject. You can read\nmore about the properties of the Codename One layouts in\nthe developer guide.\nIn general layouts define the mathematical logic for component positions that we can then apply to the\nresolutions supported by the devices. If we didn’t have layouts the UI wouldn’t fit on the multitude of devices\nwhere it should work. You can nest layouts by placing containers within the UI and giving any container a\ndifferent layout manager, this allows you to construct very elaborate layouts.\nYou can pick a layout manager using this UI:\nFigure 21. Layouts can be picked via the GUI builder UI\nMost layouts support settings that allow you to configure their behavior, e.g. FlowLayout supports\nsettings such as these that allow you to align the components within it to your locations of choice:\nFigure 22. FlowLayout settings\nBorderLayout \u0026amp; TableLayout support constraints that allow you to provide additional hints about the components\nwithin the layout:\nFigure 23. Border layout constraints\nMixing these layouts in a hierarchy allows you to produce most UI’s.\nE.g. one of the most powerful tricks in the new GUI builder is the multi selection mode:\nFigure 24. Multi selection icon\nWhen this mode is turned on the icon turns into a cancel icon to cancel that mode. When it’s turned on you can\nselect multiple components and perform operations on all of them such as changing a property on multiple\ncomponents or enclosing them in a container e.g.:\nFigure 25. When we toggle on multi-select mode and select several components we can then enclose them in a Container\nUnderlying XML Saving the project generates an XML file representing the UI into the res directory in the project, the GUI file\nis created in a matching hierarchy in the project under the res/guibuilder directory:\nFigure 26. The java and GUI files in the hierarchy\n__ | If you refactor (rename or move) the java file it’s connection with the GUI file will break. You need\nto move/rename both You can edit the GUI file directly but changes won’t map into the GUI builder unless you reopen it. These files\nshould be under version control as they are the main files that change. The GUI builder file for the button and\nlabel code looks like this:\n\u0026lt;?xml version=\u0026quot;1.0\u0026quot; encoding=\u0026quot;UTF-8\u0026quot;?\u0026gt; \u0026lt;component type=\u0026quot;Form\u0026quot; layout=\u0026quot;FlowLayout\u0026quot; flowLayoutFillRows=\u0026quot;false\u0026quot; flowLayoutAlign=\u0026quot;1\u0026quot; flowLayoutValign=\u0026quot;0\u0026quot; title=\u0026quot;My new title\u0026quot; name=\u0026quot;MyForm\u0026quot;\u0026gt; \u0026lt;component type=\u0026quot;Button\u0026quot; text=\u0026quot;Button\u0026quot; name=\u0026quot;Button_1\u0026quot; actionEvent=\u0026quot;true\u0026quot;\u0026gt; \u0026lt;/component\u0026gt; \u0026lt;component type=\u0026quot;Label\u0026quot; text=\u0026quot;Hi World\u0026quot; name=\u0026quot;Label_1\u0026quot;\u0026gt; \u0026lt;/component\u0026gt; \u0026lt;/component\u0026gt; This format is relatively simple and is roughly the same format used by the old GUI builder which makes the migration\nto the new GUI builder possible. This file triggers the following Java source file:\npackage com.mycompany.myapp; /** * GUI builder created Form * * @author shai */ public class MyForm extends com.codename1.ui.Form { public MyForm() { this(com.codename1.ui.util.Resources.getGlobalResources()); } public MyForm(com.codename1.ui.util.Resources resourceObjectInstance) { initGuiBuilderComponents(resourceObjectInstance); } //-- DON'T EDIT BELOW THIS LINE!!! private com.codename1.ui.Label gui_Label_1 = new com.codename1.ui.Label(); private com.codename1.ui.Button gui_Button_1 = new com.codename1.ui.Button(); // \u0026lt;editor-fold defaultstate=\u0026quot;collapsed\u0026quot; desc=\u0026quot;Generated Code\u0026quot;\u0026gt; private void guiBuilderBindComponentListeners() { EventCallbackClass callback = new EventCallbackClass(); gui_Button_1.addActionListener(callback); } class EventCallbackClass implements com.codename1.ui.events.ActionListener, com.codename1.ui.events.DataChangedListener { private com.codename1.ui.Component cmp; public EventCallbackClass(com.codename1.ui.Component cmp) { this.cmp = cmp; } public EventCallbackClass() { } public void actionPerformed(com.codename1.ui.events.ActionEvent ev) { com.codename1.ui.Component sourceComponent = ev.getComponent(); if(sourceComponent.getParent().getLeadParent() != null) { sourceComponent = sourceComponent.getParent().getLeadParent(); } if(sourceComponent == gui_Button_1) { onButton_1ActionEvent(ev); } } public void dataChanged(int type, int index) { } } private void initGuiBuilderComponents(com.codename1.ui.util.Resources resourceObjectInstance) { guiBuilderBindComponentListeners(); setLayout(new com.codename1.ui.layouts.FlowLayout()); setTitle(\u0026quot;My new title\u0026quot;); setName(\u0026quot;MyForm\u0026quot;); addComponent(gui_Label_1); addComponent(gui_Button_1); gui_Label_1.setText(\u0026quot;Hi World\u0026quot;); gui_Label_1.setName(\u0026quot;Label_1\u0026quot;); gui_Button_1.setText(\u0026quot;Click Me\u0026quot;); gui_Button_1.setName(\u0026quot;Button_1\u0026quot;); }// \u0026lt;/editor-fold\u0026gt; //-- DON'T EDIT ABOVE THIS LINE!!! public void onButton_1ActionEvent(com.codename1.ui.events.ActionEvent ev) { } } __ Don’t touch the code within the DON’T EDIT comments…​ The GUI builder uses the \u0026ldquo;magic comments\u0026rdquo; approach where code is generated into those areas to match the\nXML defined in the GUI builder. The IDE’s generate that code at different times. Some IDE’s will generate it when you\nrun the app while others will generate it as you save the GUI in the builder.\nYou can write code freely within the class both by using the event mechanism, by writing code in the\nconstructors or thru overriding functionality in the base class.\nShould I Switch Yes if you want to move forward.\nIf your app is in maintenence mode then no. We have no plans to remove support for the old GUI builder although\nwe will de-emphasize it slowly.\nWhile we still aren’t ready to crown the GUI builder as fully production grade we do think the XML based file format\nis very stable (since we inherited it from the old GUI builder) and should thus work rather well. So even if you\nrun into issues in the tool itself you can probably workaround most of them thru the XML code which is already\neasier to work with than it was with the old GUI builder.\nCurrently, NetBeans and Eclipse have a migration wizard from the old GUI builder. It is flaky as it tries to \u0026ldquo;fake\u0026rdquo;\nthe \u0026ldquo;statemachine navigation\u0026rdquo; and does it rather badly. So the assumption is that you would need to use that\nas a starting point and adapt the logic of the application.\nIf your app is very complex it might be a difficult task so we would suggest dedicating some time to evaluating this\nbefore jumping in head first.\nFinal Word We’ve spent a lot of time building up the new GUI builder and it is still not as refined as the old one. However,\nwe think that once you guys start reporting bugs \u0026amp; requesting enhancements it will quickly mature into an\namazing tool.\nTake the time to work with it and let us know what you think. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nYaakov Gesher — August 31, 2016 at 5:19 am (permalink) How do we handle localization in the new GUI builder? What’s the equivalent to StaeMachine’s findMyComponent() methods?\nYngve Moe — August 31, 2016 at 10:38 pm (permalink) I can’t scroll the advanced properties list for a MultiButton, so a number of properties can’t be accessed. This is on a Windows 10 PC.\nIf this is an error, I might try to edit the XML file manually. Is its format documented somewhere?\nShai Almog — September 1, 2016 at 5:42 am (permalink) Because the GUI builder is decoupled from the resource file at the moment the only solution is to add a string to the localization bundle in the resource file matching a string in the GUI builder. Ideally we’d like to rework localization and themeing in the same way we reworked the GUI workflow and remove the need for the old resource editor completely.\nYaakov Gesher — September 1, 2016 at 6:01 am (permalink) What about getting a handle on components?\nShai Almog — September 2, 2016 at 5:13 am (permalink) In the new GUI builder all components are just class fields e.g. gui_MyComponent. To get them just compile the project and the source will be generated.\nAdebisi Oladipupo — September 2, 2016 at 5:59 pm (permalink) I have followed the new GUI builder overview and tried using it but it seems not matured. I am unable to attach background image to a form and/or container as it is possible with the old guy builder by creating new UIID. The property list for for components seem to be abbreviated (not enough) as compared to the old builder.\nUsing the old builder also presents a problem with asking for a filename when saving the design; instead of creating a nd inserting the GUI form as part of the package. What am I missing?\nI have also bought a copy of the Developer guide for codename one from Amazon but the coverage on the GUI builder from Aug 2016 is very scanty. I will appreciate your guidance. I know you all prefer hand coding but some of us, visual developers like gui builders to alleviate design task. If GUI designer/builder is going to be part of Codenameone, then let’s make it usable and the best it can be just as the main program. Thanks\nShai Almog — September 3, 2016 at 4:31 am (permalink) The old GUI builder is 6+ years old so undoubtedly it’s more mature. For styling you need to launch the designer (old UI) and create the style, you don’t have the shortcuts we used to have because the tools are now completely separate.\nI didn’t understand the second issue.\nWe’ll try to improve the GUI builder documentation further as we move forward, the focus is on handcoding as it’s much harder to document (drag this here etc.).\nShai Almog — September 3, 2016 at 4:36 am (permalink) Thanks, we’ll fix it for the next GUI builder update!\nYngve Moe — September 3, 2016 at 6:56 am (permalink) A very nice feature would have been if the GUI builder were able to see your CSS files and render the GUI accordingly. I suppose one would have to load the CSS file manually into the builder environment.\nShai Almog — September 4, 2016 at 5:43 am (permalink) On the very right side of the toolbar (top) you will see 3 vertical dots (overflow) pressing that will allow you to change the theme.\nCSS is a plugin and not a part of Codename One \u0026ldquo;proper\u0026rdquo; this works with the res files which CSS is supposed to generate.\nYngve Moe — September 4, 2016 at 3:29 pm (permalink) Ok, that sound reasonable. However I can’t find the vertical dots. The rightmost items on my toolbar are \u0026ldquo;Save\u0026rdquo; and \u0026ldquo;Preview Design\u0026rdquo;. Am I looking in the wrong place? I can’t find that button anywhere on this page, either.\nShai Almog — September 5, 2016 at 4:29 am (permalink) If the overflow menu is missing that means the GUI builder found one theme only and is using that.\nI’m guessing Steve generated the res file as part of the CSS build process which makes some sense but it’s obviously problematic for use cases like this.\nA workaround would be to copy the res file from the build into the src directory where it should be detected. The problem with this though is that you would need to remember to remove it.\nAdebisi Oladipupo — September 5, 2016 at 6:28 pm (permalink) Thanks Shai and sorry for not being clear. I am trying to adopt the new GUI builder since that’s the future. I am having difficult time nesting containers as you showed in the calculator example. I am not asking to be told \u0026ldquo;drag this here and there\u0026rdquo;.\nIt would be great if one can drag components in the component tree to structure the layout rather than dragging elements into their outlines on the right side of the screen (an action that is more of a trial and error). Doing so has actually resulted in deleting or making components disappear from the tree. I applaud you and your team for a great product. I am not being critical but rather providing input for making it better.\nA quick refinement could be having the component tree visible while dragging new components into the project.\nI have tried for a week to duplicate your example of the calculator in the new GUI builder but no luck. I just can’t get the nesting to happen for the containers. It was much easier doing it in the old GUI since I could just drag the elements into the component tree rather than trying to do it in the graphic panel where things just jump around without guidance.\nI think the process will be helped along if the UI construction process is further enhanced with the new GUI builder rather than creating UI forms via hardcoding alone; just my two cents.\nThanks for any and all assistance you can provide the growing visual developers who also code to make the forms functional.\nAdebisi Oladipupo — September 5, 2016 at 6:31 pm (permalink) See a sample frustrated attempt to nest containers. All subsequent containers on the form are supposed to be nested under the first one …\nAdebisi Oladipupo — September 6, 2016 at 1:15 am (permalink) To understand my last post, here’s the login form I am trying to reproduce. I got the free PSD files from one of codenameone tutorial links. I have retrieved and added all the relevant images into the res editor as instructed. Any help with advice on layout structures to use will be greatly appreciated. Thanks. P.S. I have the png file that makes the background translucent under the content pane.\nAdebisi Oladipupo — September 6, 2016 at 1:21 am (permalink) This is how far I got. May get further if only I can nest containers easily and reliably in the new GUI builder (at least that is what I think, but could be wrong).\nShai Almog — September 6, 2016 at 4:01 am (permalink) Thanks. We are aware of some issues related to nesting that trigger exceptions. These exceptions are hard to recover from…\nWe had such issues in the old GUI builder as well and we worked around them over time. The problem with fixing these is in producing reliable test cases as it’s pretty hard to do this for GUI builder where the test case consists of \u0026ldquo;drag this here\u0026rdquo; then \u0026ldquo;that here\u0026rdquo; etc. making the effort pretty big.\nIf you have such a test case that would be helpful. Regardless we have some ideas on improving the robustness of the GUI builder so it acts in a more reliable way. If you used the old GUI builder extensively you might recall that when it failed it presented an error then would \u0026ldquo;undo\u0026rdquo; that error essentially stabilizing the development process. We’ll try to introduce similar behavior to the new GUI builder with this or the next update.\nAdebisi Oladipupo — September 8, 2016 at 1:01 am (permalink) Thanks again Shai. One more question.\nCan a form designed in JFormdesigner be used in a codenameone application? If so, how? I know I can start a form so designed from the main class with: \u0026quot; new LoginForm().show()\u0026quot; ; but not sure if the generated codes by JFormdesigner can be used and work with codenaeone.\nShai Almog — September 8, 2016 at 4:40 am (permalink) JFormDesigner is for Swing code and not Codename One API. You might be able to edit the code it generates for Codename One compatibility but it will stop working as a visual tool once you do that…\nAdebisi Oladipupo — September 8, 2016 at 11:49 pm (permalink) It may not b worth the effort to use JFormdesigner in that respect. I will stick with Codenameone GUI knowing better days are ahead. Patience is a virtue. Thanks\nAkinniranye James — September 9, 2016 at 12:30 am (permalink) I share your pain. Trying to create this layout for almost a day. The GUI Builder is far from okay. I just resolved to editing xml by hand (not as difficult as it sounds).\nYngve Moe — September 13, 2016 at 6:56 pm (permalink) Found a bug: if I try to add a \u0026ldquo;DataChange Event\u0026rdquo; to a Slider, the emitted Java code calls \u0026ldquo;addDataChangeListener(…)\u0026rdquo;, which is a syntax error (should be \u0026ldquo;addDataChangedListener(…)\u0026rdquo;).\nShai Almog — September 14, 2016 at 4:51 am (permalink) Ugh. This was actually something we changed in reverse without noticing: https://github.com/codename…\nTurns out that this method was named inconsistently across the code with half of the cases using Change and half going with changed. Autocomplete hid this for what must have been 8 years or so… I’ve fixed it to use Changed as this makes more sense.\nPhil ip — March 29, 2017 at 4:25 pm (permalink) Tried the new gui builder. Promissing, but not easy to handle at this state. I am wondering about using FXML like JavaFX2? Are there any plans in this direction?\nShai Almog — March 30, 2017 at 6:09 am (permalink) No. JavaFX hasn’t picked industry traction and since it’s remarkably heavy supporting it would cripple any mobile app. FXML is tied up too deep into FX and isn’t useful without it.\nWe’d rather focus our efforts on helping Android developers since there are about 10000 of those compared to one FX developer…\nMichael du Plessis — April 6, 2017 at 3:03 pm (permalink) Hi! I’m really keen on using CodeNameOne, I’ve got Java down fine, I’m just needing to get used to the GUI Builder. The code you mentioned for the GUI elements being generated within the \u0026ldquo;magical comments\u0026rdquo; aren’t generating. I notice this is post is about 9 months old and have seen there are updates to the new GUI Builder, it looks slightly different to the above screenshots.\nI followed the instructions but like I said, even created a complete new project to make sure, but the code isn’t generating on it’s own within the .java file. The XML file is fine though. Any advice forward would be majorly appreciated, I’m very excited since I discovered this and wouldn’t want my excitement and motivation to wane because of a slight mishap.\nShai Almog — April 7, 2017 at 5:50 am (permalink) Shai Almog says:\nOn which IDE/OS configuration are you experiencing this?\nMichael du Plessis — April 7, 2017 at 6:28 am (permalink) Michael du Plessis says:\nI’m working in Netbeans on Windows\nShai Almog — April 8, 2017 at 11:44 am (permalink) Shai Almog says:\nTry running from command line by going to your user home directory and under the .codenameone directory you should see a file called guibuilder_1.jar try running it using:\njava -jar guibuilder_1.jar and see how that works. It should print out error messages with more details on the failure\nMichael du Plessis — April 8, 2017 at 9:35 pm (permalink) Michael du Plessis says:\nI’ve figured out the issue. Netbeans requires me to manually right-click on the .java file for the GuiBuilder class and click on \u0026ldquo;Compile File\u0026rdquo;. Might be worth adding to the above instructions. 🙂\nI’m so glad it works now, and thank you for your responses! 🙂\nI also noted during my trial and error, when I tried checking to see if my plugin tool was maybe out of date, that it said the following:\n\u0026ldquo;Unable to connect to the CodenameOnePlugin Update Center because of\nhttps://codenameone.googlec… \u0026quot;\nThought I’d just query about it anyway.\nShai Almog — April 9, 2017 at 4:06 am (permalink) Shai Almog says:\nThe source is only generated on build you can build/run the project to see it.\nThe update center problem is something we’ll fix in the next plugin update.\nJean Naude — May 6, 2017 at 3:35 pm (permalink) Jean Naude says:\nHi, I am trying to follow this tutorial (using IntelliJ Idea on a MacBook) but when I open the GUI Builder I get the following message after a few moments, before I do anything in the GUI. https://uploads.disquscdn.c…\nShai Almog — May 7, 2017 at 3:55 am (permalink) Shai Almog says:\nCan you try this: https://www.codenameone.com…\nLet me know what’s printed in the prompt when you get this crash.\nJean Naude — May 7, 2017 at 9:32 pm (permalink) Jean Naude says:\nThis is what I get:\nJeans-MacBook-Pro:~ Jean$ cd .codenameone\nJeans-MacBook-Pro:.codenameone Jean$ java -jar guibuilder.jar\nConnector: file:/Users/Jean/.guiBuilder/guibuilder.input\n[EDT] 0:0:0,1 – Codename One revisions: 1933c5f6f587753f0b5a1eac2a0548bddc6ff41a\n2355\n[EDT] 0:0:0,1 – Trying to load the Codename One GUI builder file: file:/Users/Jean/IdeaProjects/TryAgain/res/guibuilder/com/mycompany/myapp/SecondForm.gui\n[EDT] 0:0:0,1 – Successfully loaded the form XML:\n[EDT] 0:0:0,63 – createComponent for element: dyld: lazy symbol binding failed: Symbol not found: ___sincos_stret\nReferenced from: /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/libjfxwebkit.dylib\nExpected in: /usr/lib/libSystem.B.dylib\ndyld: Symbol not found: ___sincos_stret\nReferenced from: /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/libjfxwebkit.dylib\nExpected in: /usr/lib/libSystem.B.dylib\nTrace/BPT trap: 5\nJeans-MacBook-Pro:.codenameone Jean$\nShai Almog — May 8, 2017 at 5:18 am (permalink) Shai Almog says:\nThat’s a JDK bug it seems Oracle compiled the JDK’s webkit support incorrectly. I have the same JDK version on a Mac but I’m on El Capitan what’s your OS version?\nThis might be resolved by changing OS/JDK versions (reverting to 1.8.9x or something).\nJean Naude — May 8, 2017 at 7:39 am (permalink) Jean Naude says:\nI have OS X 10.8.5 (Mountain Lion). I have not upgraded to Sierra yet because I have burnt my fingers badly in the past with upgrades (Windows) and because I have limited bandwidth. Sierra does not seem to offer anything that I need. What is your advice?\nI see I have an old jdk 1.6 in the following directory: /System/Library/Java/JavaVirtualMachines\nand jdk 1.8.0_91 and 1.8.0_131 in /Library/Java/JavaVirtualMachines. The Home Alias in /Library/Java points to jdk 1.6. I think the problem lies here but I don’t know how to fix it (new to OS X, have always used Windows).\nFollowing internet searches I tried\nexport JAVA_HOME=/Library/Java/Home\nand then tried to run the GUI Builder again:\nJeans-MacBook-Pro:.codenameone Jean$ java -jar guibuilder.jar\nException in thread \u0026ldquo;main\u0026rdquo; java.lang.UnsupportedClassVersionError: com/codename1/apps/guibuilder/desktop/GUIBuilderMain : Unsupported major.minor version 52.0\nat java.lang.ClassLoader.defineClass1(Native Method)\nat java.lang.ClassLoader.defineClassCond(ClassLoader.java:637)\nat java.lang.ClassLoader.defineClass(ClassLoader.java:621)\nat java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)\nat java.net.URLClassLoader.defineClass(URLClassLoader.java:283)\nat java.net.URLClassLoader.access$000(URLClassLoader.java:58)\nat java.net.URLClassLoader$[1.run](http://1.run)([URLClassLoader.java](http://URLClassLoader.java):197)\nat java.security.AccessController.doPrivileged(Native Method)\nat java.net.URLClassLoader.findClass(URLClassLoader.java:190)\nat java.lang.ClassLoader.loadClass(ClassLoader.java:306)\nat sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)\nat java.lang.ClassLoader.loadClass(ClassLoader.java:247)\nHelp, please.\nShai Almog — May 9, 2017 at 5:54 am (permalink) Shai Almog says:\n1.6.x won’t work because it’s an old JDK we need 1.8.x. Mountain Lion is really old by now so it’s possible Oracle doesn’t test some functionality well enough on it. I’m on El Capitan and can’t reproduce this issue.\nTo check which Java is running just use java -version\nYou can try using an explicit version of Java by using a full path e.g.:\n/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/bin/java\nor\n/Library/Java/JavaVirtualMachines/jdk1.8.0_91.jdk/Contents/Home/bin/java\nJean Naude — May 9, 2017 at 7:11 am (permalink) Jean Naude says:\nUsing the explicit version jdk 1.8.0_91 works form the command line, but gives me the same error (dialog in first post) when I try to run the guibuilder from the IDE.\nShai Almog — May 10, 2017 at 5:44 am (permalink) Shai Almog says:\nThis seems to be a regression in the new JDK. Try setting the JDK of the netbeans project to point at the older 91 version as a workaround. If this fails try changing the JDK netbeans itself runs on to the older one. Alternatively updating the OS should also resolve this.\nCh Hjelm — July 7, 2017 at 8:29 pm (permalink) Ch Hjelm says:\nHow do you remove/delete a GUI Builder file from a Netbeans project? I tried creating one to try out the new GUI Builder but it has compilation errors (\u0026ldquo;error: illegal character: ‘u00b4′\u0026rdquo; which I cannot see in the GUI builder) and when I delete the generated Java file it just gets recreated every time I build the application.\nShai Almog — July 8, 2017 at 5:31 am (permalink) Shai Almog says:\nUnder the res/guibuilder directory you should see a hierarchy containing a .gui file. Which version of the GUI builder did you use (it’s in the about screen) and how did you create that file? The .gui and Java file would be helpful in an issue assuming it’s 3.7+.\nThanks.\nCh Hjelm — July 8, 2017 at 6:21 am (permalink) Ch Hjelm says:\nThanks, I wasn’t aware of the res/guibuilder directory. I used 3.7.1, but the file was created a few weeks ago, using Netbeans New -\u0026gt; Codename One -\u0026gt; Gui Builder Form. Since this was blocking compilation, and was just an experimental file, I simply deleted the content in the Gui Builder so I could compile. Maybe not a realistic option, but if you could store the .gui file’s XML content directly in the Java file, it would be simpler/more intuitive to delete. Alternatively, add a Delete file button in the Gui Builder?\nShawn Ikope — August 22, 2017 at 11:57 pm (permalink) Shawn Ikope says:\nmy gui builder keeps telling me that I cannot change the layout. How do I remove the Auto layout?\nShai Almog — August 23, 2017 at 6:13 am (permalink) Shai Almog says:\nI suggest you check out this post, the new mode is far superior: https://www.codenameone.com…\nYou can just create a new GUI builder file and uncheck autolayout if you want.\nJill M — February 13, 2018 at 5:07 am (permalink) Jill M says:\nI would like to change my layout; however, when I try to click on another layout I get an error message that says \u0026ldquo;Auto layout mode currently on. The root layout manager must be Layered Layout.\u0026rdquo; How can I remove auto layout without having to start all over. I read the article below, but I did not find the answer I was looking for. Please help 🙂\nShai Almog — February 13, 2018 at 5:20 am (permalink) Shai Almog says:\nIn version 3.8 we added a new auto layout mode which is now the default. It should make it much easier to build a UI without changing the layout. Steve discussed this in depth here: https://www.codenameone.com…\nlinnet maruve — June 18, 2018 at 12:09 pm (permalink) linnet maruve says:\nOn Gui builder when l want to pick an icon there are no images from res files as well as the google and facebook links for buttons how do l add them. on res file there is no codenameone logo at all. l am using netbeans on windows 10 please help\nShai Almog — June 19, 2018 at 5:13 am (permalink) Shai Almog says:\nDoes the project itself have the Codename One logo?\nIs the plugin installed? What do you see when you right click the project/file? Can you post screenshots?\nlinnet maruve — June 19, 2018 at 9:41 am (permalink) linnet maruve says:\nyes it has a logo.the plugin is installed l downloaded it from netbeans org and installed it. when l right click it gives me many options there one to access codename one build… and settings\nlinnet maruve — June 19, 2018 at 10:01 am (permalink) linnet maruve says:\nhttps://uploads.disquscdn.c… https://uploads.disquscdn.c…\nShai Almog — June 20, 2018 at 4:13 am (permalink) Shai Almog says:\nThere is a logo on the theme.res where you can add images using the resource editor tool\nlinnet maruve — June 20, 2018 at 6:59 am (permalink) linnet maruve says:\ncan l have the procedure of doing that\nShai Almog — June 21, 2018 at 6:07 am (permalink) Shai Almog says:\nSure, it’s in the developer guide: https://www.codenameone.com… just open it Images -\u0026gt; Add\nlinnet maruve — June 21, 2018 at 2:21 pm (permalink) linnet maruve says:\nok let me work on it will come back to you\nJack Dore — August 22, 2018 at 1:25 pm (permalink) Jack Dore says:\nHow do I connect two GUIs with a button.\nShai Almog — August 23, 2018 at 5:25 am (permalink) Shai Almog says:\nPress the action listener button in the events tab. Then go to the code. In the code you should have a new callback call for the action event. Just write something like new OtherGUIBuilderForm().show();\nMedo Boui — September 12, 2018 at 3:59 pm (permalink) Medo Boui says:\nimagine that i have a form and a container withing it; the container is created using the New Gui Builder,and there are some components on it, is there a way to call these components like do some sort of getButtonX() for example or findButtonX()? because i tried to define getters and setters and whenever i try to run it, the code i added is deleted automatically\nShai Almog — September 13, 2018 at 10:45 am (permalink) Shai Almog says:\nWhen you build the project the content within the comment block is regenerated. You can write getters and setters just don’t place them between these two comments… Make sure to save before compiling.\nMedo Boui — September 13, 2018 at 3:58 pm (permalink) Medo Boui says:\nThank you so much\ntobi adegoroye — October 26, 2019 at 6:49 pm (permalink) tobi adegoroye says:\nHi it would be helpful if you could add a video showing how to use the constraints in the new gui builder\nShai Almog — October 27, 2019 at 2:19 am (permalink) Shai Almog says:\nHi,\nsee \u0026lt;/blog/tutorial-gui-builder-autolayout-signin-form-responsive/\u0026gt;\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/using-the-new-gui-builder/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/using-the-new-gui-builder/gui-builder-chrome.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe had a couple of posts in the past about the new GUI builder but we didn’t have a \u0026ldquo;how to\u0026rdquo; guide yet. In this\u003cbr\u003e\npost we’ll try to go step by step over the process of using the GUI builder and understanding its inner workings.\u003cbr\u003e\nWe’ll also try to clarify conclusively the role the new GUI builder plays in the toolchain and the migrations process\u003cbr\u003e\nfrom the old GUI builder.\u003c/p\u003e","title":"Using the new GUI Builder"},{"content":"\nAs we mentioned recently we have a new idea on how peering can be improved\nand we just deployed a this into our build servers in the weekend update. This is highly experimental and might\ncrash instantly which is why we hope you give it a test drive and see how it feels before we switch it on by default.\nTo recap: Peers (or heavyweight components) are OS native widgets. E.g. when you use the BrowserComponent\nwe effectively load the OS’s native webkit renderer and use that instead of showing HTML ourselves. This is good\nas it allows us to use OS native functionality, however it’s bad because peers have a lot of limitations\nwhich we covered in depth here.\nOne of the biggest limitations has been that peers are always drawn on top of the UI as they are drawn separately\nfrom Codename One. With the original implementation of Codename One which was double buffered this made\na lot of sense, you can’t conceivably implement peers in any other way. However, newer implementations moved\nto a more dynamic architecture so we can take better advantage of hardware acceleration…​\nWith that we can also use this architecture to draw peers directly into the rendering graph which is exactly what\nwe do in the new Android pipeline changes. Since this is such a huge change we left it off by default and you will\nneed to set the build hint: android.newPeer=true.\n__ | We will remove that build hint in the future so it is undocumented in the developer guide, it’s hard to maintain\nthat peer due to the complexity of the fork Please try your apps with the new flag and let us know about crashes, memory leaks or problematic functionality\nthat didn’t exist before.\nThis should allow a lot of very exciting functionality, e.g. features like ToastBar, glasspane, layered layout etc.\nwill work with peer components and will allow you things like drawing on top of a map, video, browser etc.\nNotice that this isn’t available on the simulator/iOS at this time so you can only see this working on Android devices.\nWe plan to add something similar to iOS and the simulator as we move forward. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFabrizio Grassi — July 11, 2016 at 2:11 pm (permalink) Fabrizio Grassi says:\nCould this affect also the text editing?\nDiamond — July 11, 2016 at 8:44 pm (permalink) Diamond says:\nHi Shai,\nI tested this feature on Samsung S5 mini. App crashes when I tried to open web browser. Some transparency on components overlaid on Google Maps and Google Maps requires touching to get refreshed before it shows, while the overlaid component is already shown. These are the issues I found so far, I will keep testing.\nShai Almog — July 12, 2016 at 3:19 am (permalink) Shai Almog says:\nRight now we didn’t touch the text editing code which is a bit of a special case. We might change it in the future.\nShai Almog — July 12, 2016 at 3:21 am (permalink) Shai Almog says:\nThanks. Can you try and get a stack trace from the crash?\nI’m not sure how well transparency will work in these situations. Transparency requires the underlying component to paint itself and we don’t always have a way to force that.\nJonathan — August 3, 2016 at 6:14 am (permalink) Jonathan says:\nCan you use it on the camera live mode ( Capture.capturePhoto()) ?\nShai Almog — August 4, 2016 at 4:25 am (permalink) Shai Almog says:\nCapture doesn’t use peer components. It’s a monolithic API.\nOne could use a peer component to map to low lever camera native API’s in a cn1lib in a similar way to the native maps implementation. We might do this ourselves at some point but right now our task list is so full I just don’t see this happening.\nLukman Javalove Idealist Jaji — August 16, 2016 at 7:09 am (permalink) Lukman Javalove Idealist Jaji says:\nHi Diamond,\nCould you help with how you laid components on a Map? I’ve been wanting to do that\nDiamond — August 16, 2016 at 10:35 am (permalink) Diamond says:\nHi Lukman, It’s as simple as placing the component in your LayeredPane after adding your map to the form center layout position. remember to add Build Hint \u0026ldquo;android.newPeer=true\u0026rdquo; until it’s true by default.\nIt’s advisable to do this in postFormShow(), if hand-coded form, do it in the addShowListener() and inside CallSerially. Example 1 – Hand-Coded form:\nform.addShowListener((evt) -\u0026gt; {\nremoveAllShowListeners();\nDisplay.getInstance().callSerially(new Runnable() {\n@Override\npublic void run() {\nMapContainer mc = new MapContainer();\nform.add(BorderLayout.CENTER, mc);\nform.getLayeredPane().add(FlowLayout.encloseCenterMiddle(myTestingLabel));\nform.revalidate();\nform.getLayeredPane().revalidate();\n}\n});\n});\nExample 2 – GUI form:\n@Override\nprotected void postMyForm(final Form f) {\nDisplay.getInstance().callSerially(new Runnable() {\n@Override\npublic void run() {\nMapContainer mc = new MapContainer();\nf.add(BorderLayout.CENTER, mc);\nf.getLayeredPane().add(FlowLayout.encloseCenterMiddle(myTestingLabel));\nf.revalidate();\nf.getLayeredPane().revalidate();\n}\n});\n}\nTHIS code is written here and was not tested.\nLukman Javalove Idealist Jaji — August 16, 2016 at 10:47 am (permalink) Lukman Javalove Idealist Jaji says:\nNgiyabonga Diamond ..it worked … 🙂 Thanks for your help once again….\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-android-peer-mode/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-android-peer-mode/native-peer-revisited.png\"\u003e\u003c/p\u003e\n\u003cp\u003eAs \u003ca href=\"/blog/peering-revisited.html\"\u003ewe mentioned recently\u003c/a\u003e we have a new idea on how peering can be improved\u003cbr\u003e\nand we just deployed a this into our build servers in the weekend update. This is highly experimental and might\u003cbr\u003e\ncrash instantly which is why we hope you give it a test drive and see how it feels before we switch it on by default.\u003c/p\u003e\n\u003cp\u003eTo recap: Peers (or heavyweight components) are OS native widgets. E.g. when you use the \u003ccode\u003eBrowserComponent\u003c/code\u003e\u003cbr\u003e\nwe effectively load the OS’s native webkit renderer and use that instead of showing HTML ourselves. This is good\u003cbr\u003e\nas it allows us to use OS native functionality, however it’s bad because peers have a lot of limitations\u003cbr\u003e\nwhich we covered in depth \u003ca href=\"/blog/understanding-peer-native-components-why-codename-one-is-so-portable.html\"\u003ehere\u003c/a\u003e.\u003c/p\u003e","title":"New Android Peer Mode"},{"content":"\nThis has been a remarkably busy week for us trying to get the final bugs and features ready for the 3.5 code\nfreeze and the work we are doing on peer components etc. All the while the summer vacation is on it’s way\nand it’s already pretty hard to get any work done.\nThis weeks release doesn’t contain any major changes, it’s mostly a bug fix release update.\nThis doesn’t seem to affect stack overflow which had a busy week as usual despite the heat:\nCodenameone Bluetooth APIs not working on android That’s why we recommend using the new extension install UI where it checks dependencies…​.\nRead on stackoverflow…​\nAdding device-specific files as a codenameone native lib I like it when users give a better answer on stack overflow…​ Makes me proud!\nRead on stackoverflow…​\nEOFException when reading file from storage (cn1) This is such a common mistake when working with DataInputStream that it’s trivial for me to spot it by now.\nRead on stackoverflow…​\nSqllite database location We need a better SQL demo that will also demonstrate this, I started working on something but anything that\nis non-trivial (thus interesting) takes a bit too long…​\nRead on stackoverflow…​\nDisplaying form on condition I’m guessing everyone reading this post knows the answer to this one…​\nRead on stackoverflow…​\nAndroid phone will not show map (only blank map) Google Maps are always a pain to get going the first time around with the API key and SHA nonsense.\nRead on stackoverflow…​\nApp can neither be installed on android nor IOS Pretty much every mobile OS out there fails at some point in app installation and gives zero help as to why which\nis very annoying.\nRead on stackoverflow…​\nError using codenameone bluetooth support Bluetooth is pretty new so there isn’t much in the form of documentation or anything to fallback to\nRead on stackoverflow…​\nCodenameone LocalNotification in android api \u0026lt; 16 and when the app is removed from recent Some background behaviors that are device specific are pretty darn hard to replicate and figure out sometimes\nRead on stackoverflow…​\nGoogle Maps project in Codename One will not build Changing package names in Codename One is sometimes painful even for us\nRead on stackoverflow…​\nCodename one set remove Accordion border This is a pretty simple question with a pretty good answer\nRead on stackoverflow…​\niOS code to generate video thumbnail returning 0 byte[] Native interfaces are always hard to debug without a native environment…​\nRead on stackoverflow…​\nDoes TextField fireDoneEvent() to call stopEditing() in order to close the virtual keyyboard? With issues like this a test case is essential…​\nRead on stackoverflow…​\nHow to disable Textfield from using the auto-suggestion on IOS This is pretty easy albeit not necessarily intuitive for someone who is new to Codename One…​\nRead on stackoverflow…​\nStorage behavior on Samsung Galaxy S4 On device behavior can be pretty weird sometimes and object serialization is often a pain…​\nRead on stackoverflow…​\nCan I construct dynamically detail content in UI-Accordion-Component at Touch moment? No. But since stackoverflow has a minimum answer length I had to elaborate on that…​\nRead on stackoverflow…​\nCodename one Windows UWP Shop Build Fail The process of uploading/building for the Universal Windows Platform (UWP) is a bit tedious, it’s not really our\nfault as much as the guys from Redmond…​\nRead on stackoverflow…​\nCodename one Windows UWP build in compliance test on windows store This is as far as we know the first time a Codename One UWP app is going thru the store upload process, hopefully\nthese questions pave the way to a smoother overall process…​\nRead on stackoverflow…​\nGetting an OOM when rendering Bitmap for videoPlayer Peer components are a pain, it’s a good thing we are looking into a major ovehaul for them…​\nRead on stackoverflow…​\nGridlayout textfield search issue Searching in GridLayout is somewhat problematic as hidden elements don’t quite disappear which is why we now\nhave a special mode that allows hiding those elements. This was something we added to support narrowing\nthe option set in the new Codename One settings UI\nRead on stackoverflow…​\nVideo having problems on my phone You can’t play a video twice when playing it from a stream, you need to restart it since the stream can’t be rewinded.\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xiii/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xiii/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis has been a remarkably busy week for us trying to get the final bugs and features ready for the 3.5 code\u003cbr\u003e\nfreeze and the work we are doing on peer components etc. All the while the summer vacation is on it’s way\u003cbr\u003e\nand it’s already pretty hard to get any work done.\u003c/p\u003e\n\u003cp\u003eThis weeks release doesn’t contain any major changes, it’s mostly a bug fix release update.\u003c/p\u003e","title":"Questions of the Week XIII"},{"content":"\nWe are preparing for the 3.5 code freeze which should go into effect on July 26th. We are still not sure about the\nfull set of features that will make it into 3.5 as the release is pretty close by now. However, we already have some cool\ntentative plans for 3.6 and beyond that we are already sketching out.\nUnless there are major regressions we’ll deliver 3.5 on August 2nd and 3.6 on December 5th. At this time version\n3.7 is planned for April 4th 2017 and 3.8 for August 1st 2017.\nYou will notice we toned it down slightly to 3 releases a year instead of 4 which we feel would provide us a bit\nmore breathing room as we move forward.\nWe don’t want to get too much into details but one of the features that we have been exploring for the 3.6 timeline\nis the ability to build offline, this is a feature we will only expose to the enterprise grade subscribers.\nWhy only Enterprise? There are several reasons, the technical one is that offline builds are no panacea. Things fail. The support effort\nfor offline builds is huge, as evidence despite the fact that all of our code is open source very few people bothered\ntrying to compile it because of the complexities.\nWe don’t think building offline is convenient and we always recommended avoiding it. When we build\nour own apps we use the cloud just like everyone else because it’s surprisingly faster and more convenient…​\nHowever, some government and regulated industries have issues with SaaS delivered solutions and thus must\nuse offline build. These organizations also require enterprise grade support for most cases and so it makes sense\nto bundle as an enterprise only solution.\nPolicy Since offline builds will in effect be a component that is \u0026ldquo;installed locally\u0026rdquo; we think that the right thing to do is\nto treat this as \u0026ldquo;shrinkwrap software\u0026rdquo;. So once you download a version of the offline build tool from our servers\nthis version will be there until you delete it.\nIt will not \u0026ldquo;dial home\u0026rdquo; or perform any such tests but it will be locked to your development machine.\nYou will be allowed to keep using it based on the terms of the license. So you can keep shipping/building\napps after canceling an enterprise subscription but you won’t be able to update to the latest Codename One\nversion as it will include newer features.\nFunctionality We currently only plan to support iOS \u0026amp; Android build targets for offline builds, the former will (naturally) require\na Mac. We might add additional supported platforms based on user demand.\nThe process will not physically build the app. It will generate a native project for iOS/Android which you will need to\nopen in xcode/Android Studio respectively and build manually.\nFeedback We are currently in the feedback gathering phase for this functionality so if this is something you are interested\nin and already have or plan to upgrade to enterprise we’d love to hear about that.\nWe won’t open this feature to other account tiers, we ran thru the costs/benefits and decided that this isn’t something\nwe can justify. If you have a lower grade account you can use offline builds with the source code from github.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/preparing-for-3-5-offline-builds/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/preparing-for-3-5-offline-builds/codenameone35.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are preparing for the 3.5 code freeze which should go into effect on July 26th. We are still not sure about the\u003cbr\u003e\nfull set of features that will make it into 3.5 as the release is pretty close by now. However, we already have some cool\u003cbr\u003e\ntentative plans for 3.6 and beyond that we are already sketching out.\u003c/p\u003e\n\u003cp\u003eUnless there are major regressions we’ll deliver 3.5 on August 2nd and 3.6 on December 5th. At this time version\u003cbr\u003e\n3.7 is planned for April 4th 2017 and 3.8 for August 1st 2017.\u003c/p\u003e","title":"Preparing for 3.5 \u0026 Offline Builds"},{"content":"\nI blogged about\npeer components\nall the way back in 2014 trying to explain basic facts about their limitations/behaviors. A lot of those limitations\nare inherent but over the past year or so we’ve been thinking more and more about the z-order limitation.\nAs part of that train of thought I filed this issue\nwith a few suggestions about working around some of those limitations. I think these approaches would work really\nwell on iOS which from my experience is more \u0026ldquo;amiable\u0026rdquo; to such hacks. Android is a different beast though.\nAndroid’s rendering logic is a weird hackish nightmare filled with bugs and lore…​\nSo naturally I picked Android first to experiment with and as you can see from the screenshot above, the button\nand labels are Codename One widgets…​\nThis is still buggy and there is no guarantee we’ll be able to bring this to production grade but I’m generally optimistic\nthat this is a doable task that opens up Codename One to a HUGE set of applications in media/mapping etc.\nthat up until now required way too much native code to work properly.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/peering-revisited/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/peering-revisited/native-peer-revisited.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI blogged about\u003cbr\u003e\n\u003ca href=\"/blog/understanding-peer-native-components-why-codename-one-is-so-portable.html\"\u003epeer components\u003c/a\u003e\u003cbr\u003e\nall the way back in 2014 trying to explain basic facts about their limitations/behaviors. A lot of those limitations\u003cbr\u003e\nare inherent but over the past year or so we’ve been thinking more and more about the z-order limitation.\u003c/p\u003e\n\u003cp\u003eAs part of that train of thought I filed \u003ca href=\"https://github.com/codenameone/CodenameOne/issues/1758\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ethis issue\u003c/a\u003e\u003cbr\u003e\nwith a few suggestions about working around some of those limitations. I think these approaches would work really\u003cbr\u003e\nwell on iOS which from my experience is more \u0026ldquo;amiable\u0026rdquo; to such hacks. Android is a different beast though.\u003cbr\u003e\nAndroid’s rendering logic is a weird hackish nightmare filled with bugs and lore…​\u003c/p\u003e","title":"Peering Revisited"},{"content":"\nA common issue we get from developers relates to minor differences between devices which are often very\nhard to quantify. They are also very hard to explain to the developers in some occasions. One of the biggest\npoints of difficulty is density which is a very hard concept to grasp and it’s often hard to know which image will\nbe used from the set of multi images or how many pixels will be used for 1 millimeter.\nTo make this process slightly easier we created a new demo that is remarkably simple but we are hoping it\nwould also be remarkably helpful. It just prints on the screen the settings and values of all the important\ndetails mostly from the Display class.\nThis demo also allows you to send the details to your email directly so you can send it to a user who is experiencing\nissues and understand some things about their device. This will also make it simpler for you to communicate issues\nwith us as we won’t need as much back and forth with device details.\nYou can check out the full repository on github here and you can\nuse that to get proper debug logic for your app. We hope to add it to the IDE’s so it will be a part of the new app\nwizard dialog.\nMy OnePlus One outputs something like this, which you can see is pretty useful if you want to understand the device\ntype we are dealing with:\nDensity: DENSITY_HD Platform Name: and User Agent: Dalvik/2.1.0 (Linux; U; Android 6.0.1; A0001 Build/MMB29X) OS:Android OS Version: 6.0.1 UDID:865800025623619 MSISDN: Display Width X Height: 1080X1920 1mm In Pixels: 18.898 Language: en Locale: US Currency Symbol: $ Are Mutable Images Fast: false Can Dial: true Can Force Orientation: true Has Camera: true Badging: false Desktop: false Tablet: false Gaussian Blur Support: true Get All Contacts Fast: true Multi Touch: true PICKER_TYPE_DATE: true PICKER_TYPE_DATE_AND_TIME: false PICKER_TYPE_STRINGS: true PICKER_TYPE_TIME: true Native Share: true Native Video Player Controls: true Notification: true Open Native Navigation: true Screen Saver Disable: true Simulator: false The Java code to produce this is pretty trivial albeit a bit verbose:\npublic void start() { if(current != null){ current.show(); return; } Form hi = new Form(\u0026quot;Basic Details\u0026quot;, BoxLayout.y()); Display d = Display.getInstance(); String density = \u0026quot;\u0026quot;; switch(Display.getInstance().getDeviceDensity()) { case Display.DENSITY_2HD: density = \u0026quot;DENSITY_2HD\u0026quot;; break; case Display.DENSITY_4K: density = \u0026quot;DENSITY_4K\u0026quot;; break; case Display.DENSITY_560: density = \u0026quot;DENSITY_560\u0026quot;; break; case Display.DENSITY_HD: density = \u0026quot;DENSITY_HD\u0026quot;; break; case Display.DENSITY_HIGH: density = \u0026quot;DENSITY_HIGH\u0026quot;; break; case Display.DENSITY_LOW: density = \u0026quot;DENSITY_LOW\u0026quot;; break; case Display.DENSITY_MEDIUM: density = \u0026quot;DENSITY_MEDIUM\u0026quot;; break; case Display.DENSITY_VERY_HIGH: density = \u0026quot;DENSITY_VERY_HIGH\u0026quot;; break; case Display.DENSITY_VERY_LOW: density = \u0026quot;DENSITY_VERY_LOW\u0026quot;; break; } double pixelsPerMM = (((double)d.convertToPixels(1000)) / 1000.0); L10NManager l10n = L10NManager.getInstance(); hi.add(\u0026quot;Density:\u0026quot;). add(new SpanLabel(density)). add(\u0026quot; \u0026quot;). add(\u0026quot;Platform Name:\u0026quot;). add(new SpanLabel(d.getPlatformName())). add(\u0026quot; \u0026quot;). add(\u0026quot;User Agent:\u0026quot;). add(new SpanLabel(d.getProperty(\u0026quot;User-Agent\u0026quot;, \u0026quot;\u0026quot;))). add(\u0026quot; \u0026quot;). add(\u0026quot;OS:\u0026quot;). add(new SpanLabel(d.getProperty(\u0026quot;OS\u0026quot;, \u0026quot;\u0026quot;))). add(\u0026quot; \u0026quot;). add(\u0026quot;OS Version:\u0026quot;). add(new SpanLabel(d.getProperty(\u0026quot;OSVer\u0026quot;, \u0026quot;\u0026quot;))). add(\u0026quot; \u0026quot;). add(\u0026quot;UDID:\u0026quot;). add(new SpanLabel(d.getUdid())). add(\u0026quot; \u0026quot;). add(\u0026quot;MSISDN:\u0026quot;). add(new SpanLabel(d.getMsisdn())). add(\u0026quot; \u0026quot;). add(\u0026quot;Display Width X Height:\u0026quot;). add(new SpanLabel(d.getDisplayWidth() + \u0026quot;X\u0026quot; + d.getDisplayHeight())). add(\u0026quot; \u0026quot;). add(\u0026quot;1mm In Pixels:\u0026quot;). add(new SpanLabel(l10n.format(pixelsPerMM))). add(\u0026quot; \u0026quot;). add(\u0026quot;Language:\u0026quot;). add(new SpanLabel(l10n.getLanguage())). add(\u0026quot; \u0026quot;). add(\u0026quot;Locale:\u0026quot;). add(new SpanLabel(l10n.getLocale())). add(\u0026quot; \u0026quot;). add(\u0026quot;Currency Symbol:\u0026quot;). add(new SpanLabel(l10n.getCurrencySymbol())). add(\u0026quot; \u0026quot;). add(uneditableCheck(\u0026quot;Are Mutable Images Fast\u0026quot;, d.areMutableImagesFast())). add(uneditableCheck(\u0026quot;Can Dial\u0026quot;, d.canDial())). add(uneditableCheck(\u0026quot;Can Force Orientation\u0026quot;, d.canForceOrientation())). add(uneditableCheck(\u0026quot;Has Camera\u0026quot;, d.hasCamera())). add(uneditableCheck(\u0026quot;Badging\u0026quot;, d.isBadgingSupported())). add(uneditableCheck(\u0026quot;Desktop\u0026quot;, d.isDesktop())). add(uneditableCheck(\u0026quot;Tablet\u0026quot;, d.isTablet())). add(uneditableCheck(\u0026quot;Gaussian Blur Support\u0026quot;, d.isGaussianBlurSupported())). add(uneditableCheck(\u0026quot;Get All Contacts Fast\u0026quot;, d.isGetAllContactsFast())). add(uneditableCheck(\u0026quot;Multi Touch\u0026quot;, d.isMultiTouch())). add(uneditableCheck(\u0026quot;PICKER_TYPE_DATE\u0026quot;, d.isNativePickerTypeSupported(Display.PICKER_TYPE_DATE))). add(uneditableCheck(\u0026quot;PICKER_TYPE_DATE_AND_TIME\u0026quot;, d.isNativePickerTypeSupported(Display.PICKER_TYPE_DATE_AND_TIME))). add(uneditableCheck(\u0026quot;PICKER_TYPE_STRINGS\u0026quot;, d.isNativePickerTypeSupported(Display.PICKER_TYPE_STRINGS))). add(uneditableCheck(\u0026quot;PICKER_TYPE_TIME\u0026quot;, d.isNativePickerTypeSupported(Display.PICKER_TYPE_TIME))). add(uneditableCheck(\u0026quot;Native Share\u0026quot;, d.isNativeShareSupported())). add(uneditableCheck(\u0026quot;Native Video Player Controls\u0026quot;, d.isNativeVideoPlayerControlsIncluded())). add(uneditableCheck(\u0026quot;Notification\u0026quot;, d.isNotificationSupported())). add(uneditableCheck(\u0026quot;Open Native Navigation\u0026quot;, d.isOpenNativeNavigationAppSupported())). add(uneditableCheck(\u0026quot;Screen Saver Disable\u0026quot;, d.isScreenSaverDisableSupported())). add(uneditableCheck(\u0026quot;Simulator\u0026quot;, d.isSimulator())); final String densityStr = density; hi.getToolbar().addMaterialCommandToRightBar(\u0026quot;\u0026quot;, FontImage.MATERIAL_SEND, e -\u0026gt; { StringBuilder body = new StringBuilder(\u0026quot;Density: \u0026quot;). append(densityStr). append(\u0026quot;n\u0026quot;). append(\u0026quot;Platform Name: \u0026quot;). append(d.getPlatformName()). append(\u0026quot;n\u0026quot;). append(\u0026quot;User Agent: \u0026quot;). append(d.getProperty(\u0026quot;User-Agent\u0026quot;, \u0026quot;\u0026quot;)). append(\u0026quot;n\u0026quot;). append(\u0026quot;OS: \u0026quot;). append(d.getProperty(\u0026quot;OS\u0026quot;, \u0026quot;\u0026quot;)). append(\u0026quot;n\u0026quot;). append(\u0026quot;OS Version: \u0026quot;). append(d.getProperty(\u0026quot;OSVer\u0026quot;, \u0026quot;\u0026quot;)). append(\u0026quot;n\u0026quot;). append(\u0026quot;UDID: \u0026quot;). append(d.getUdid()). append(\u0026quot;n\u0026quot;). append(\u0026quot;MSISDN: \u0026quot;). append(d.getMsisdn()). append(\u0026quot;n\u0026quot;). append(\u0026quot;Display Width X Height: \u0026quot;). append(d.getDisplayWidth()).append(\u0026quot;X\u0026quot;).append(d.getDisplayHeight()). append(\u0026quot;n\u0026quot;). append(\u0026quot;1mm In Pixels: \u0026quot;). append(l10n.format(pixelsPerMM)). append(\u0026quot;n\u0026quot;). append(\u0026quot;Language: \u0026quot;). append(l10n.getLanguage()). append(\u0026quot;n\u0026quot;). append(\u0026quot;Locale: \u0026quot;). append(l10n.getLocale()). append(\u0026quot;n\u0026quot;). append(\u0026quot;Currency Symbol: \u0026quot;). append(l10n.getCurrencySymbol()). append(\u0026quot;nAre Mutable Images Fast: \u0026quot;). append(d.areMutableImagesFast()). append(\u0026quot;nCan Dial: \u0026quot;). append(d.canDial()). append(\u0026quot;nCan Force Orientation: \u0026quot;).append(d.canForceOrientation()). append(\u0026quot;nHas Camera: \u0026quot;).append(d.hasCamera()). append(\u0026quot;nBadging: \u0026quot;).append(d.isBadgingSupported()). append(\u0026quot;nDesktop: \u0026quot;).append(d.isDesktop()). append(\u0026quot;nTablet: \u0026quot;).append(d.isTablet()). append(\u0026quot;nGaussian Blur Support: \u0026quot;).append(d.isGaussianBlurSupported()). append(\u0026quot;nGet All Contacts Fast: \u0026quot;).append(d.isGetAllContactsFast()). append(\u0026quot;nMulti Touch: \u0026quot;).append(d.isMultiTouch()). append(\u0026quot;nPICKER_TYPE_DATE: \u0026quot;).append(d.isNativePickerTypeSupported(Display.PICKER_TYPE_DATE)). append(\u0026quot;nPICKER_TYPE_DATE_AND_TIME: \u0026quot;).append(d.isNativePickerTypeSupported(Display.PICKER_TYPE_DATE_AND_TIME)). append(\u0026quot;nPICKER_TYPE_STRINGS: \u0026quot;).append(d.isNativePickerTypeSupported(Display.PICKER_TYPE_STRINGS)). append(\u0026quot;nPICKER_TYPE_TIME: \u0026quot;).append(d.isNativePickerTypeSupported(Display.PICKER_TYPE_TIME)). append(\u0026quot;nNative Share: \u0026quot;).append(d.isNativeShareSupported()). append(\u0026quot;nNative Video Player Controls: \u0026quot;).append(d.isNativeVideoPlayerControlsIncluded()). append(\u0026quot;nNotification: \u0026quot;).append(d.isNotificationSupported()). append(\u0026quot;nOpen Native Navigation: \u0026quot;).append(d.isOpenNativeNavigationAppSupported()). append(\u0026quot;nScreen Saver Disable: \u0026quot;).append(d.isScreenSaverDisableSupported()). append(\u0026quot;nSimulator: \u0026quot;).append(d.isSimulator()); Message msg = new Message(body.toString()); Display.getInstance().sendMessage(new String[] { Display.getInstance().getProperty(\u0026quot;built_by_user\u0026quot;, \u0026quot;[[email protected]](/cdn-cgi/l/email-protection)\u0026quot;) }, \u0026quot;Device Details\u0026quot;, msg); }); hi.show(); } private CheckBox uneditableCheck(String t, boolean v) { CheckBox c = new CheckBox(t); c.setSelected(v); c.setEnabled(false); return c; } Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — July 5, 2016 at 11:02 pm (permalink) bryan says:\nVery useful – thanks.\nbryan — July 5, 2016 at 11:54 pm (permalink) bryan says:\nas per issue 1808, Display.getInstance().sendMessage() doesn’t work on WP10.\nImriel — July 12, 2016 at 5:59 am (permalink) Imriel says:\nHow to check with device memory?\nShai Almog — July 13, 2016 at 3:54 am (permalink) Shai Almog says:\nYou can’t do that reliably. Devices have a mixed notion of memory segmentation and we don’t really know the available memory in some cases.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/device-tester/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/device-tester/device-tester.png\"\u003e\u003c/p\u003e\n\u003cp\u003eA common issue we get from developers relates to minor differences between devices which are often very\u003cbr\u003e\nhard to quantify. They are also very hard to explain to the developers in some occasions. One of the biggest\u003cbr\u003e\npoints of difficulty is density which is a very hard concept to grasp and it’s often hard to know which image will\u003cbr\u003e\nbe used from the set of multi images or how many pixels will be used for 1 millimeter.\u003c/p\u003e","title":"Device Tester"},{"content":"\nWe just updated the QT and\nXamarin comparisons to Codename One that we did a while back.\nThose comparisons now include a property cross comparison section.\nProperty Cross is really valuable for comparing the differences between various cross platform development\nsolutions and Codename One has the smallest implementation (in terms of lines of code) by far!\nOur implementation is also quite superior in some other ways providing features such as infinite scrolling instead\nof simple paging etc.\nWe think that just by looking at the Codename One project and comparing it to the equivalent cross platform\ntools Codename One’s advantages become pretty clear. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — July 6, 2016 at 3:12 pm (permalink) Chidiebere Okwudire says:\nMy two cents: I personally think LOC comparisons are marginally important and somewhat misleading. The user does not see how many LOCs an app has but does see the UI and experience good or bad performance. I think such CPT comparisons should focus more on user experience and development costs (which includes the costs of the development tools, licenses, etc.) instead of on stuff that probably make developers somewhat happier but do not contribute that much to the end goal of apps that are attractive, robust and performant.\nBy the way, the CN1 implementation is still missing from the property cross website – a lost (but redeemable) opportunity for some free PR if you ask me! Maybe time to give it another shot?\nShai Almog — July 6, 2016 at 5:38 pm (permalink) Shai Almog says:\nAll of those are good points. As I mentioned LoC isn’t a great measure but when it’s 3x or higher for most other solutions it does indicate something. Personally I think our solution is also the most readable but I have such a heavy cognitive bias I can’t really evaluate these things.\nPerformance and usability of the end result application is something I can’t objectively discuss as a fact. So I’d rather leave it to the developers to read thru the code and see if this makes sense then try to compile each of the solutions.\nDevelopment costs are really hard to evaluate, costs for licenses etc. are things that shift and with the exception of QT all the solutions we evaluated are free/open source.\nI did try again recently, tried contacting the guy who did the last commit to their repo etc. both thru twitter, his email account etc. There is an issue HE opened asking for a Codename One version. I submitted a pull request and commented a few times… Nothing.\nThis is quite frustrating.\nChidiebere Okwudire — July 8, 2016 at 8:09 am (permalink) Chidiebere Okwudire says:\nThanks for your response. It surprises me that there are not much objective comparisons in the dimensions that arguably matter most, some of which I’ve mentioned above (user experience, performance, costs). I know it’s not easy but it’s definitely possible albeit in a somewhat \u0026ldquo;academic\u0026rdquo; fashion.\nPropertyCross is one of the best initiatives I’ve found in this regard though it only scratches the surface and as you’ve mentioned, the maintainers are not as responsive as one would like. Apparently, they find it more important to change the layout of their homepage instead of incorporating the CN1 comparison (and other pending pull requests?)!\nTalking about costs, while it’s hard to evaluate, it’s worth mentioning some facts. For instance, in one of your previous comparisons (with Xamarin if I’m not mistaken), you highlighted that CN1 support a web app version. That’s definitely a killer feature but what is glaringly missing is a mention of the fact that it is an enterprise-only feature (read $399 per month). Now, that fact makes a H-U-G-E difference in the cost-benefit equation.\nAs you rightly mentioned, most of the solutions are open-source at the core but often have paid extras which make a huge difference. It must be possible to compare these quite objectively – free against free, paid against paid (grouped by feature set not subscription model), etc. I’m not saying you have to do that; all I’m trying to point out is that while you’re obviously positively biased towards CN1, it’s still possible to do more rigorous comparisons 😉\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/compare-thru-property-cross/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/compare-thru-property-cross/property-cross-new.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe just updated the \u003ca href=\"/blog/comparing-qt-and-codename-one.html\"\u003eQT\u003c/a\u003e and\u003cbr\u003e\n\u003ca href=\"/blog/comparing-xamarin-and-codename-one.html\"\u003eXamarin\u003c/a\u003e comparisons to Codename One that we did a while back.\u003cbr\u003e\nThose comparisons now include a \u003ca href=\"/blog/property-cross-revisited.html\"\u003eproperty cross\u003c/a\u003e comparison section.\u003cbr\u003e\nProperty Cross is really valuable for comparing the differences between various cross platform development\u003cbr\u003e\nsolutions and Codename One has the smallest implementation (in terms of lines of code) by far!\u003c/p\u003e\n\u003cp\u003eOur implementation is also quite superior in some other ways providing features such as infinite scrolling instead\u003cbr\u003e\nof simple paging etc.\u003c/p\u003e","title":"Compare Thru Property Cross"},{"content":"\nJune just ended and we are starting the final stretch to get 3.5 ready, there is a lot on our\ntable right now so most of the work in the coming month will probably focus on stabilizing the GUI builder and\nfixing the remaining issues for 3.5.\nOne thing we pushed to todays release in the last minute is a new API called: Toolbar.setCenteredDefault(boolean).\nThis was triggered in part by a\nstackoverflow question\nbelow but is a recurring theme. The Toolbar used to center it’s title thru the alignment style, which is problematic\nas it isn’t centered relatively to the commands on the sides. We now center it properly but this might not be what\nyou want so you can disable this functionality by calling Toolbar.setCenteredDefault(false);.\nOn stackoverflow things are relatively calm:\nHow to make the app use the whole screen height (remove the Toolbar) If you don’t add commands and set the title to blank the Toolbar won’t show up. There will be additional spacing\nfor the StatusBar on iOS but you can style that to padding 0.\nRead on stackoverflow…​\nAdding firebase to Codename One This was asked a few times so I fired a question at the guys from codapps who might have some old demo code lying around…​\nRead on stackoverflow…​\nHow to Store an Array of JSON data in Persistent Memory and Read it Back There are many ways to accomplish that…​\nRead on stackoverflow…​\ngetAppHomePath() seems to throw a wrong path in Simulator? Storage \u0026amp; FileSystemStorage are very confusing and this is compounded by the simulator that somewhat mixes\nthem in the same directory hierarchy. You need to use one or the other for a specific task!\nRead on stackoverflow…​\nGPS fail if not on top Location in the background is a special case that requires special permissions and a different apparoach to the API…​\nRead on stackoverflow…​\nAdding jar files to codenameone in NetBeans Integrating 3rd party libraries for which there isn’t a cn1lib wrapper yet will probably always be a bit tricky…​ There\nis a big section on this in the developer guide and Steve did some videos but it’s still not easy.\nRead on stackoverflow…​\nHow can I prevent my title text from getting misaligned? This is something we now fixed by default so it should no longer be an issue…​\nRead on stackoverflow…​\nHow can I center a SpanLabel’s text in CodenameOne? SpanLabel like many other composite components uses separate UIID’s for the various elements within it.\nRead on stackoverflow…​\nCodenameOne calander event for next/previous month arrow The Calendar component is a bit long in the tooth by now, we don’t use it as much with the picker working natively.\nRead on stackoverflow…​\nOne Drive Multipart upload error HTTP 400 Bad Request This is more of a One Drive question than a Codename One question so there isn’t much we can do here. One\nof the nice things in SO though is the fact that you can get answers from everyone at one place…​\nRead on stackoverflow…​\nImage always missing in the received message while sharing an image Like many issues this was multi-layered but it seems that there is also an issue with the Codename One share\nbutton. The share button handles it’s action performed before it’s listeners had time to react. By enclosing it\nin a call serially we were able to workaround the bug mentioned here.\nRead on stackoverflow…​\nHow can I get an Android device current SDK level in a native interface Native interfaces are harder to debug, we always suggest building a native project and debugging them there\notherwise you might be mislead that something isn’t working as expected.\nRead on stackoverflow…​\nHow to include Adobe Analytics in CodenameOne I don’t really know…​ Those are often the harder questions we get as I’m obviously not an expert in the 3rd party\nlibrary discussed.\nRead on stackoverflow…​\nWhy do I get a different behavior in Codename One simulator than on a real Android device? This was one of those questions that kept coming up again and again from the same persistent user, unfortunately\nI initially discarded the issue as unlikely, then I wasn’t able to reproduce it properly until finally I had a working\ntest case…​ It turns out the simulator used incorrect coordinates for mutable images when it was running in scale\nmode. Persistence pays off…​\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xii/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xii/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eJune just ended and we are starting the final stretch to get 3.5 ready, there is a lot on our\u003cbr\u003e\ntable right now so most of the work in the coming month will probably focus on stabilizing the GUI builder and\u003cbr\u003e\nfixing the remaining issues for 3.5.\u003c/p\u003e\n\u003cp\u003eOne thing we pushed to todays release in the last minute is a new API called: \u003ccode\u003eToolbar.setCenteredDefault(boolean)\u003c/code\u003e.\u003cbr\u003e\nThis was triggered in part by a\u003cbr\u003e\n\u003ca href=\"http://stackoverflow.com/questions/38065436/how-can-i-prevent-my-title-text-from-getting-misaligned\" target=\"_blank\" rel=\"noopener noreferrer\"\u003estackoverflow question\u003c/a\u003e\u003cbr\u003e\nbelow but is a recurring theme. The \u003ccode\u003eToolbar\u003c/code\u003e used to center it’s title thru the alignment style, which is problematic\u003cbr\u003e\nas it isn’t centered relatively to the commands on the sides. We now center it properly but this might not be what\u003cbr\u003e\nyou want so you can disable this functionality by calling \u003ccode\u003eToolbar.setCenteredDefault(false);\u003c/code\u003e.\u003c/p\u003e","title":"Questions of the Week XII"},{"content":"\nThe charts demo is one of the most elaborate/messy demos we have as it was derived/ported from an\naChartEngine demo. Since the\nCodename One charts\nare themselves a derivative of aChartEngine this makes a lot of sense but the demo is a bit big and hard to\nfollow.\nHowever, it does show off a lot of the chart types that can be created using the charts package. As such it is a\nvery valuable demo…​\nWe’d love to modernize it more but time constraints make this impractical, for now we did the following:\nAdded a new tablet mode which makes the demo look completely different on the tablet using it’s screen dimensions\nproperly\nStreamlined the colors/fonts – a lot of the charts were inconsistent and had really tiny/unreadable fonts\nSwitched to Toolbar – while we don’t make extensive use of this API in the demo it’s now the base API\nMigrated the code to Java 8 syntax – we didn’t do it for every case where it could be used but the project\nis now a Java 8 project\nAdded pinch/pan to all the charts – this uses the builtin API in the ChartComponent class\nAdded some experimental features (e.g. chart editing) which are turned off by default at the moment. These were\nhalf baked and getting this to work across all the charts and with all the features would have been challenging\nCheck out a live preview of the demo on the right here thanks to our JavaScript port!\nThe preview works in the mobile phone mode, to see this running in the tablet mode just open\nthis link and it will run in desktop/tablet mode.\nThings like pinch to zoom don’t work in the JavaScript port for some reason but they should work reasonably\nwell on the device.\nThe Source Check out the full source code for the demo in the\ngithub repository for the Charts demo.\nThis demo will be integrated into the upcoming new project wizards in the various IDEs.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/charts-demo-revisited/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/charts-demo-revisited/charts-demo.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe charts demo is one of the most elaborate/messy demos we have as it was derived/ported from an\u003cbr\u003e\n\u003ca href=\"http://www.achartengine.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eaChartEngine\u003c/a\u003e demo. Since the\u003cbr\u003e\n\u003ca href=\"/javadoc/com/codename1/charts/package-summary/\"\u003eCodename One charts\u003c/a\u003e\u003cbr\u003e\nare themselves a derivative of aChartEngine this makes a lot of sense but the demo is a bit big and hard to\u003cbr\u003e\nfollow.\u003c/p\u003e\n\u003cp\u003eHowever, it does show off a lot of the chart types that can be created using the charts package. As such it is a\u003cbr\u003e\nvery valuable demo…​\u003c/p\u003e","title":"Charts Demo Revisited"},{"content":"\nThe ToastBar was one\nof those API’s I didn’t know I needed and yet I became addicted to it…​\nEver since Steve came out with the ToastBar I constantly catch myself typing Display.show only to delete that\nto use the ToastBar. It’s both really easy to use and more consistent with modern mobile UI design.\nAs a replacement for Dialog it really needed the static \u0026ldquo;show methods\u0026rdquo;, so we added a simpler showErrorMessage\nwhich combined the ToastBar with the material font icons to create a proper error message. This allowed us to\nshow an error message with a single line of code, but these things shouldn’t be used only for errors which is\nwhy we just added two new static methods: showMessage(String msg, char icon, int timeout) \u0026amp;\nshowMessage(String msg, char icon).\nThe icon argument is one of the FontImage\nconstants representing the material design icons. This allows us to show simpler notifications e.g. file downloaded\nsuccessfully etc.\nWe can now do this using code such as this:\nForm f = new Form(\u0026quot;Toast\u0026quot;, BoxLayout.y()); Button showError = new Button(\u0026quot;Show Error\u0026quot;); Button showNotification = new Button(\u0026quot;Show Notification\u0026quot;); Button showWarning = new Button(\u0026quot;Show Warning\u0026quot;); showError.addActionListener(e -\u0026gt; ToastBar.showErrorMessage(\u0026quot;This is an error\u0026quot;)); showNotification.addActionListener(e -\u0026gt; ToastBar.showMessage(\u0026quot;This is a notification\u0026quot;, FontImage.MATERIAL_INFO)); showWarning.addActionListener(e -\u0026gt; ToastBar.showMessage(\u0026quot;This is a warning!\u0026quot;, FontImage.MATERIAL_WARNING)); f.add(showError). add(showNotification). add(showWarning); f.show(); Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChris — June 12, 2017 at 4:39 am (permalink) Chris says:\nThanks for the info. ToastBar.showErrorMessage() is displaying with empty box as image( \u0026quot; ! \u0026quot; mark in the example) instead of actual image in the front of the message. Something has been changed recently.\nShai Almog — June 13, 2017 at 5:21 am (permalink) Shai Almog says:\nNo to my knowledge. This is derived from the theme. The icon is created based on the style of the message UIID.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/toastbar-messages/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/toastbar-messages/toast-warning.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe \u003ca href=\"/javadoc/com/codename1/components/ToastBar/\"\u003eToastBar\u003c/a\u003e was one\u003cbr\u003e\nof those API’s I didn’t know I needed and yet I became addicted to it…​\u003cbr\u003e\nEver since Steve came out with the ToastBar I constantly catch myself typing \u003ccode\u003eDisplay.show\u003c/code\u003e only to delete that\u003cbr\u003e\nto use the \u003ccode\u003eToastBar\u003c/code\u003e. It’s both really easy to use and more consistent with modern mobile UI design.\u003c/p\u003e\n\u003cp\u003eAs a replacement for \u003ccode\u003eDialog\u003c/code\u003e it really needed the static \u0026ldquo;show methods\u0026rdquo;, so we added a simpler \u003ccode\u003eshowErrorMessage\u003c/code\u003e\u003cbr\u003e\nwhich combined the \u003ccode\u003eToastBar\u003c/code\u003e with the material font icons to create a proper error message. This allowed us to\u003cbr\u003e\nshow an error message with a single line of code, but these things shouldn’t be used only for errors which is\u003cbr\u003e\nwhy we just added two new static methods: \u003ccode\u003eshowMessage(String msg, char icon, int timeout)\u003c/code\u003e \u0026amp;\u003cbr\u003e\n\u003ccode\u003eshowMessage(String msg, char icon)\u003c/code\u003e.\u003c/p\u003e","title":"ToastBar Messages"},{"content":"\nLast time around we compared Codename One to Xamarin and this\ntime around I’d like to compare Codename One to what is probably the market leader: PhoneGap/Cordova. If Xamain\nis big then Cordova is huge, it is so prevalent that it is often the default assumption when people mention cross\nplatform today.\nIn fact, one of the big problems we had when describing Codename One was distinguishing it from HTML5 based\nsolutions like Cordova.\nOne of the things we’d like to clarify before delving into the comparison is that our goal isn’t to proclaim Codename One\nas the \u0026ldquo;end all\u0026rdquo; of WORA…​\nWe are biased so the comparison might be flawed. However, we think Cordova/PhoneGap are remarkably\ninnovative tools that changed the marketplace significantly. The goal of this comparison is to highlight the\ndifferences/tradeoffs of each solution. In fact we rather like Cordova and even offer some\nCordova compatibility in Codename One…​\nWe were debating a lot on whether we should include Ionic in this comparison and decided to mostly skip it for now.\nWe mention it and related frameworks in the comparison in a few points mostly because PhoneGap is usually used\nwith such frameworks. Unfortunately because of the number of JavaScript frameworks and tools built on top\nof PhoneGap it’s just impractical to single out each and every one of them.\nWe might do a proper discussion of Ionic as I think it’s a very interesting solution that is very similar to Codename One\nin some regards. Most of the things we discuss about PhoneGap/Cordova apply to ionic too.\nBackground PhoneGap was started in the iPhoneDevCamp hackathon, this highlights the genius behind the solution:\nthe underlying idea is trivial. PhoneGap is in-effect a very simple solution which is a pretty good thing.\nPhoneGap places a single web view UI within an app which it then uses to display HTML. It exposes a set of\nJavaScript API’s to provide access to native functionality e.g. camera, filesystem etc.\nIt also includes a rich set of plugins that provide quite a few capabilities, in fact we just ported one of those\ngreat plugins to add bluetooth support to Codename One…​\nAdobe purchased Nitobi who made PhoneGap and open sourced the project thru Apache as the Cordova project.\nBoth PhoneGap and Cordova are very similar with PhoneGap offering some pretty interesting features on top of\nthe core open source product such as PhoneGap build.\nBecause Cordova/PhoneGap is so simple it was adopted throughout the industry practically all major enterprise mobility\ntools such as Worklight rely on it for their client side UI. It’s become a synonym for the idea of packaging HTML\nas an application and even tools that are not using Cordova internally are often referred to as PhoneGap or Cordova.\nIn fact even we announced PhoneGap/Cordova support\na while back and it didn’t take much to implement that…​\nAt a Glance Category PhoneGap/Cordova Codename One Language HTML, CSS \u0026amp; JavaScript Java Packaging Packaged code optionally obfuscated Compiled binaries VM Ownership Device/OS vendor Codename One Cloud Build Yes thru PhoneGap build Yes Web Deployment Yes Yes Widgets HTML/Lightweight Lightweight Size Overhead Depends on framework Small In Detail Language We’ve always said that if you love doing client side HTML/JavaScript for mobile devices then PhoneGap/Cordova\nis probably the right tool for you. HTML5 has come a very long way and is no longer as restrictive as it used to be\nespecially with recent iOS updates.\nHowever, Java is still a formidable opponent. Unlike HTML/JavaScript, Java is strict, statically typed and compiled.\nJavaScript isn’t the most intuitive language to interface into native code. Native concepts such as threads or even\nbinary data don’t map in a natural way to the higher level functions of JavaScript. This isn’t the case for Java which\nis literally the native language of Android and maps rather well to C/Objective-C/Swift concepts.\nWith modern Java 8 semantics Java is also quite terse and should be comparably elegant to JavaScript in most\nregards.\nPackaging PhoneGap applications are just zipped into the standard OS distribution. A complaint some PhoneGap developers\nhave is that hackers in some markets unzip their apps and take the HTML/JavaScript/CSS etc. into their own\napp. This allows them to sell the app within the standard markets as if it was their own. Such scams are\nquite common and very hard to catch/enforce.\nThis is not feasible in Codename One where the source code is compiled together and obfuscated by default\non Android making it even more \u0026ldquo;secure\u0026rdquo;. A Codename One application can be decompiled but this would be\na far harder process than doing the same for a PhoneGap/Cordova application.\nVM Ownership Java is the native platform for Android whereas JavaScript/HTML are supported everywhere by the OS vendor.\nThis brings about some interesting situations, Android completely replaced it’s browser implementation between\nversions of the OS relatively abruptly. This can trigger a situation where shipping applications will start misbehaving\ndue to OS changes. This also means that the only way to fix some issues is thru a workaround, there is no central\nauthority that can fix an HTML rendering issue or add a missing feature to an old OS.\nWith Codename One the VM and UI are the responsibility of a single entity. Since the implementation of Codename One\nis at a lower point in the porting stack most of the relevant code can be ported/fixed or worked around by Codename One\nitself. This means that if a low level reproducible failure happens, Codename One has the ability to fix it whereas\nPhoneGap developers would need to workaround it.\nCloud Build PhoneGap Build supports building native applications via the cloud which is a wonderful approach.\nCodename One works in the same way but unlike PhoneGap build, Codename One is built around that\napproach as a basic expectation.\nPhoneGap build works with a set of pre-determined plugins whereas Codename One is more flexible with\nit’s support for native code and 3rd party libraries.\nWidgets Codename One uses lightweight widgets to do it’s rendering. Arguably HTML can be considered lightweight\nas well but it is often not the case.\nOne of the core powers of HTML has been it’s complex support for dynamic reflows, this allows positioning\ncomponents using a very elaborate box model. However, this power is also the source of HTML’s greatest performance\nchallenges. Some HTML frameworks choose to position elements absolutely and lay them out thru code\nlogic, which is pretty close to what Codename One does in it’s layout managers. However, this forces the\nJavaScript developer into a custom environment that won’t \u0026ldquo;play nicely\u0026rdquo; with everything else within the ecosystem.\nFrameworks like Ionic have taken up the lightweight approach to creating native \u0026ldquo;themes\u0026rdquo; in a similar way to\nCodename One. This provides Ionic with many of the advantages Codename One enjoys but also some of the\ndrawbacks/advantages inherent from layering on top of Cordova.\nOne of the core capabilities of Codename One is in embedding native widgets directly into the app. This is demonstrated\nin Codename One thru the native Google Maps support and other such capabilities. Since embedding an OS\nnative widget into HTML is \u0026ldquo;problematic\u0026rdquo; that level of platform extension can’t be accomplished in Cordova.\nSize Overhead Cordova and Codename One can be used to create very small applications. In fact Cordova can be even smaller\nthan Codename One in the hands of a skilled developer.\nHowever, using Cordova without a JavaScript framework/tooling is more challenging and less common today.\nThese tools include their own overhead which is rather extensive in some cases. E.g. Ionic is specifically well\nknown for producing very large application binaries.\nProperty Cross Comparison The PropertyCross demo was built as a tool that allows us to compare two cross platform frameworks, as such\nthere are versions of the demo for many such platforms. You can check out details of the Codename One\nimplementation here. The github repository for this demo\nis here.\nSince PhoneGap/Cordova is mostly an infrastructure tool there are several implementations that support PhoneGap\nBuild. E.g. jquerymobile,\nionic,\nsencha touch and too many others to even\ncount…​\nWith so many variations how can we properly compare the two frameworks?\nThere are several things we can gleam from property cross by reviewing all of the above:\nCodename One has 2 file types that aren’t configuration or build scripts: res file (resources) \u0026amp; Java files.\nPhoneGap solutions use JavaScript, HTML \u0026amp; CSS.\nCodename One doesn’t have splashscreens or multiple icon sizes…​ Those are generated automatically unlike\nthe PhoneGap based solutions where you need dozens of resource files even without tablet support!\nCodename One is terse. Ionic, is one of the smallest implementations. It includes more than 600 lines of\nundocumented code spread across JavaScript and HTML (not counting angular, other JS libraries or CSS).\nThe Codename One implementation has 623 lines of code out of which over 150 lines are comments and 40\nlines are import statements…​\nWho says Java is verbose?\nFinal Word Notice that Codename One can\nembed PhoneGap/Cordova code into\nCodename One applications. Would that make it superior to just using Cordova directly?\nNot necessarily. Cordova is a mature, widely supported solution. If you like working with HTML/JavaScript\nthen it’s hard to compete with that…​\nHowever, if you want to use proper Java to develop your app and care more about the security of your code\nthen Codename One has advantages.\nIf you think we misrepresented Codename One or PhoneGap/Cordova in any way let us know in the comments. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — June 28, 2016 at 8:46 pm (permalink) bryan says:\nCN1 vs React Native ?\nShai Almog — June 29, 2016 at 4:19 am (permalink) Shai Almog says:\nAgreed. I already wrote something but it wasn’t a real comparison: http://www.codenameone.com/…\nbryan — June 29, 2016 at 4:34 am (permalink) bryan says:\nah.. yes I remember now. Would be good to get a feature for feature comparison.\nJosé Ignacio Santa Cruz — June 29, 2016 at 12:39 pm (permalink) José Ignacio Santa Cruz says:\nSeems you haven’t seen http://microsoft.github.io/… yet.\nNice comparison, I used CN1 in the early LWUIT days. Due to the lack of Android support those days I went native and finally hybrid using jQuery mobile. Today I’m using Ionic, but the main reason is because of how fast can my team deliver an almost ready product, making HTML is fast and easy. JavaScript developers are not so difficult to find, and if you have design issues, giving the CSS to a designer is no big deal, he/she won’t have to learn anything new. It needs tweaking and tooling and putting brain on the deployment process to get small sized and small memory footprint apps, just like any other developing strategy chosen.\nNot better or worse, just different, aimed for different needs.\nShai Almog — June 29, 2016 at 1:20 pm (permalink) Shai Almog says:\nThanks for the headsup, I actually did see this when it was announced and it totally slipped my mind. I wonder how well it works with the native HTML rendering?\nCodename One is totally different from LWUIT by now, we even have some CSS support. Although the \u0026ldquo;giving CSS to a designer\u0026rdquo; line is a bit… I’ve worked a lot with designers and never got anything remotely close to a usable CSS snippet from them. The best they could offer is the CSS photoshop produces for a layer which isn’t much…\nIn mobile where the design needs to be aware of screen size, density, orientation, font constraints etc. the design requires proper programming skills. I’ve yet to see a designer produce something half decent for a website and I can’t imagine one producing something workable for cross platform mobile devices…\nDavid Hinckley — July 1, 2016 at 11:15 am (permalink) David Hinckley says:\nI am a Java/Android developer and was asked to create an Android watch application to be added to an existing Cordova project. I was hoping that Cordova could receive requests from the watch through Android Wear messaging, but our Cordova expert says that Cordova can only receive Wear messages, if the Cordova app is currently in the foreground. It appears Cordova can’t run in the background without writing native code. If this is true, it may be important when considering Cordova. So, I ended up writing the native Android Wear message receiving piece for Cordova.\namikeliunas — July 6, 2016 at 4:58 am (permalink) amikeliunas says:\nWas that a comment, concern, or just venting out?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/comparing-phonegap-cordova-and-codename-one/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/comparing-phonegap-cordova-and-codename-one/compare-to-cordova.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eLast time around we compared \u003ca href=\"/blog/comparing-xamarin-and-codename-one.html\"\u003eCodename One to Xamarin\u003c/a\u003e and this\u003cbr\u003e\ntime around I’d like to compare \u003ca href=\"/\"\u003eCodename One\u003c/a\u003e to what is probably the market leader: PhoneGap/Cordova. If Xamain\u003cbr\u003e\nis big then Cordova is huge, it is so prevalent that it is often the default assumption when people mention cross\u003cbr\u003e\nplatform today.\u003c/p\u003e\n\u003cp\u003eIn fact, one of the big problems we had when describing Codename One was distinguishing it from HTML5 based\u003cbr\u003e\nsolutions like Cordova.\u003c/p\u003e","title":"Comparing PhoneGap/Cordova and Codename One"},{"content":"\nInfiniteContainer and\nInfiniteScrollAdapter\nrevolutionized the way we think about Codename One. Up until their introduction we advocated lists for large\nsets of components and this is no longer the case.\nHowever, InfiniteContainer has a controversial feature even within out team. It violates the EDT on purpose …​\nInfiniteContainer allows you to \u0026ldquo;fetch\u0026rdquo; data dynamically into the container as the user scrolls down. The definition\nof \u0026ldquo;fetch\u0026rdquo; is problematic though. Up until now the fetch\nmethod was invoked in a separate thread. This was documented in the class but it is pretty problematic as the\nmethod returns an array of components.\nIn practice creating a component in a separate shouldn’t pose a problem, yes it does violate the core Codename One\nprincipal of always doing everything on the EDT but construction should work. However, this does include some\nproblems:\nThe EDT violation detection marks such code as violating\nThe most common case (networking) already works rather well off the EDT and doesn’t need a separate thread\nThis is inconsistent with the rest of Codename One\nThere are some edge cases where this might trigger a real EDT violation e.g. if component construction triggers\nan event thus creating a race condition with the EDT\nSo to workaround this we added the new method: protected boolean isAsync().\nIf you override this method to return false the fetch method will be invoked on the EDT but this might break\ncompatibility so currently this method is set to return true.\nWe currently plan to change the method to return false by default within a couple of weeks. This might change\nbased on feedback we get from developers.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/synchronous-inifinitecontainer/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/synchronous-inifinitecontainer/generic-java-2.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/javadoc/com/codename1/ui/InfiniteContainer/\"\u003eInfiniteContainer\u003c/a\u003e and\u003cbr\u003e\n\u003ca href=\"/javadoc/com/codename1/components/InfiniteScrollAdapter/\"\u003eInfiniteScrollAdapter\u003c/a\u003e\u003cbr\u003e\nrevolutionized the way we think about Codename One. Up until their introduction we advocated lists for large\u003cbr\u003e\nsets of components and this is no longer the case.\u003c/p\u003e\n\u003cp\u003eHowever, \u003ccode\u003eInfiniteContainer\u003c/code\u003e has a controversial feature even within out team. It violates the EDT \u003cstrong\u003eon purpose\u003c/strong\u003e …​\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eInfiniteContainer\u003c/code\u003e allows you to \u0026ldquo;fetch\u0026rdquo; data dynamically into the container as the user scrolls down. The definition\u003cbr\u003e\nof \u0026ldquo;fetch\u0026rdquo; is problematic though. Up until now the \u003ca href=\"/javadoc/com/codename1/ui/InfiniteContainer/#fetchComponents-int-int-\"\u003efetch\u003c/a\u003e\u003cbr\u003e\nmethod was invoked in a separate thread. This was documented in the class but it is pretty problematic as the\u003cbr\u003e\nmethod returns an array of components.\u003c/p\u003e","title":"Synchronous InfiniteContainer"},{"content":"\nWe covered the new Accordion component last week and just started using\nit in a demo for which it was very suitable. As we were working with it we discovered that it was missing some\ncore methods to remove an Accordion entry or change it’s title. But worse, was the fact that a delete button in\nthe title wouldn’t work!\nThe crux of the issue is in the fact that\nlead component\ndoesn’t support excluding a specific component within the hierarchy from it’s behavior so we set about to fix that…​\nWe added two new methods to the Component class: setBlockLead(boolean) \u0026amp; isBlockLead().\nEffectively when you have a Component within the lead hierarchy that you would like to treat differently from the\nrest you can use this method to exclude it from the lead component behavior while keeping the rest in line…​\nThis should have no effect if the component isn’t a part of a lead component.\nOther than that we also added to Accordion some methods that allow us to mutate it’s state:\nremoveContent\n\u0026amp; two variations of\nsetHeader.\n__ | If you use a Component as the header you will need to use the version of the method that accepts a\ncomponent and not the version that accepts a String otherwise you will get an exception…​ With these new API’s we can now add mutable content. The following demo allows us to add/remove elements\nand as we change them we can see the title updating. We can also remove elements from the accordion by\npressing the delete button, however pressing in any other place will just expand/collapse the accordion.\nCheck out the live demo powered by the JavaScript port here on the right, you can also see the source\nbelow or the full project (which doesn’t include much more)\nhere.\npublic void start() { if(current != null){ current.show(); return; } Form f = new Form(\u0026quot;Accordion\u0026quot;, new BorderLayout()); Accordion accr = new Accordion(); f.getToolbar().addMaterialCommandToRightBar(\u0026quot;\u0026quot;, FontImage.MATERIAL_ADD, e -\u0026gt; addEntry(accr)); addEntry(accr); f.add(BorderLayout.CENTER, accr); f.show(); } void addEntry(Accordion accr) { TextArea t = new TextArea(\u0026quot;New Entry\u0026quot;); Button delete = new Button(); FontImage.setMaterialIcon(delete, FontImage.MATERIAL_DELETE); Label title = new Label(t.getText()); t.addActionListener(ee -\u0026gt; title.setText(t.getText())); delete.addActionListener(ee -\u0026gt; { accr.removeContent(t); accr.animateLayout(200); }); delete.setBlockLead(true); delete.setUIID(\u0026quot;Label\u0026quot;); Container header = BorderLayout.center(title). add(BorderLayout.EAST, delete); accr.addContent(header, t); accr.animateLayout(200); } Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/unleading-mutating-accordion/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/unleading-mutating-accordion/accordion-post.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe covered the \u003ca href=\"/blog/accordion-component.html\"\u003enew Accordion component last week\u003c/a\u003e and just started using\u003cbr\u003e\nit in a demo for which it was very suitable. As we were working with it we discovered that it was missing some\u003cbr\u003e\ncore methods to remove an \u003ccode\u003eAccordion\u003c/code\u003e entry or change it’s title. But worse, was the fact that a delete button in\u003cbr\u003e\nthe title wouldn’t work!\u003cbr\u003e\nThe crux of the issue is in the fact that\u003cbr\u003e\n\u003ca href=\"/manual/misc-features/#lead-component-section\"\u003elead component\u003c/a\u003e\u003cbr\u003e\ndoesn’t support excluding a specific component within the hierarchy from it’s behavior so we set about to fix that…​\u003c/p\u003e","title":"Unleading \u0026 Mutating Accordion"},{"content":"\nWe just released an updated set of plugins with many bug fixes and enhancement mostly revolving around\nthe new settings UI but also a lot of the functionality required for proper Windows UWP support…​\nThis has been a very busy week for us although most of the stuff we did was \u0026ldquo;under the hood\u0026rdquo; and not as\nvisible as some of the previous weeks. We are also fast approaching the 3.5 release due this August\nso hopefully we can get our ducks in a row to create another compelling release.\nStackoverflow was quieter this week when compared to the previous one:\nBackground image scaled and in center of container If you use the scaled() method on an Image it creates a new copy, when that Image is a URLImage you will\nlose it’s ability to fetch the image data dynamically.\nRead on stackoverflow…​\nUsing \u0026ldquo;Login with LinkedIn\u0026rdquo; to log into chat application I’d love to have additional standard connectors for Codename One to all the common social networks. It might\nbe worth doing these as cn1libs so they can be maintained by the community.\nRead on stackoverflow…​\nParse Date, CET vs CEST, invalid TimeZone, unparseable Time/Date APIs are probably the most frustrating, annoying and painful aspects of Java SE. I’ve yet to try a mobile\nimplementation that handles them correctly. We codified many of the use cases into L10NManager but should\nprobably do more there…​\nRead on stackoverflow…​\nHow to access Codename one Preferences from Android Native code? You can just invoke Codename One API’s directly from Android native code without much of a problem. This\nbecomes a bit more challenging on iOS though…​\nRead on stackoverflow…​\nFileSystemStorage.delete() doesn’t delete captured files on ALL android devices? Application isolation is one of the hard concepts to grasp in mobile programming, we just can’t reach/delete\nfiles in some places.\nRead on stackoverflow…​\nHow to accurately get the width of a drawn String (in pixel) with Codename One This thread demonstrates the need for using handcoded complete compilable samples to reproduce test cases\nRead on stackoverflow…​\nIs there a Tool Tip for CodenameOne? Not quite since it isn’t useful on touch UI’s but there are some things from the glass pane to InteractionDialog.\nRead on stackoverflow…​\nAdding Skins from Git Clone We had some issues with the add skins menu and CDN so developers were looking for a workaround thru git.\nRead on stackoverflow…​\nHow to write an \u0026ldquo;indefinitly expanding list\u0026rdquo; in CodenameOne? That’s really a Tree component.\nRead on stackoverflow…​\nCodename One Send Build Error I’m still not sure I understand why this issue happened to that developer but it got resolved so it might be\nhelpful to some…​\nRead on stackoverflow…​\nAccessing .properties property It’s actually an interesting idea to provide some constants to a running app and maybe pre-populate the preferences\nAPI…​\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-xi/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-xi/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe just released an updated set of plugins with many bug fixes and enhancement mostly revolving around\u003cbr\u003e\nthe new settings UI but also a lot of the functionality required for proper Windows UWP support…​\u003c/p\u003e\n\u003cp\u003eThis has been a very busy week for us although most of the stuff we did was \u0026ldquo;under the hood\u0026rdquo; and not as\u003cbr\u003e\nvisible as some of the previous weeks. We are also fast approaching the 3.5 release due this August\u003cbr\u003e\nso hopefully we can get our ducks in a row to create another compelling release.\u003c/p\u003e","title":"Questions of the Week XI"},{"content":"\nWe’ve been working very hard on updating a very ambitious demo for this week but alas it still isn’t ready…​ In the\nmeantime we decided to modernize the clock demo which is an important demo that is missing from the IDE’s for\nsome reason which is a shame because it’s probably our only low level graphics focused demo…​\nCheck out a live preview of the demo on the right here thanks to our JavaScript port!\nThis demo was developed by Steve as part of a tutorial to teach low level graphics programming, this tutorial\nwas folded into the developer guide graphics section. Due to it’s nature there is\nnot much we can improve about the demo. It’s a wonderful demo both in simplicity and scope.\nStill we modernized some of the boilerplate code that was improved since the original demo.\nWe also updated the fonts which really took the demo to the next level. We had some other thoughts but this\nis one of those cases where adding features would probably detract from the value of the demo so we left it as it is.\nYou can check out the slightly modified source code of this demo in\nthis github project.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/clock-demo/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/clock-demo/clock-demo.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve been working very hard on updating a very ambitious demo for this week but alas it still isn’t ready…​ In the\u003cbr\u003e\nmeantime we decided to modernize the clock demo which is an important demo that is missing from the IDE’s for\u003cbr\u003e\nsome reason which is a shame because it’s probably our only low level graphics focused demo…​\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eCheck out a live preview of the demo on the right here thanks to our JavaScript port!\u003c/strong\u003e\u003c/p\u003e","title":"Clock Demo"},{"content":"\nHistorical note: Codename One\u0026rsquo;s UWP target was discontinued in release 7.0.229. This post is preserved for historical context only, and its build/setup instructions no longer apply to current Codename One projects.\nChidiebere Okwudire of SMash ICT Solutions just\nreleased version 3.0 of the parse4cn1 library.\nThe biggest feature of which is support for the open source Parse server which should work with some of the\nparse alternatives that popped up to fill the void left by Facebook.\nThis is great news. In a way I’m more optimistic about the future of Parse than most other MBaaS\n(mobile backend as a service) solutions (e.g. Firebase). Now we have competition and options within\nthe Parse space which aren’t as common for other MBaaS solutions.\nHaving worked with Parse4cn1 in the past I’m pretty excited about this update.\nI hope to have a blog post in the near future detailing the migration to new parse servers and working with the\nAPI in the post Facebook era.\nNew Windows Servers \u0026amp; UWP Docs One somewhat undocumented pleasant result of the new UWP (Universal Windows Platform) support is the fact\nthat we needed new Windows based build servers to provide support for UWP. As part of that need we now have\nbetter (faster and more reliable) servers for Windows desktop builds which should hopefully spend less time in\nthe building queue.\nWhile we are on the subject of the UWP support Steve is working on making this target more seamless. There\nare still some issues in the current version when targeting phones and we will probably need to do some work\nto get this to the smoothness enjoyed by other platforms. We will also need to release a new plugin as the\nsettings for UWP builds have become far more challenging.\nThis level of complexity justified a new developer guide section dedicated to UWP, this is still under active\ndevelopment but you can follow it on our website here or in the\nwiki\nthat hosts the entire developer guide (which you can\nhelp us write/edit !). Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — June 23, 2016 at 8:06 am (permalink) Chidiebere Okwudire says:\nHI Shai, thanks for promptly sharing the parse4cn1 update!\nI also agree with you that Parse Server is actually a blessing in disguise. More on that in the upcoming article that you referred to 😉\nCarlos — June 23, 2016 at 12:54 pm (permalink) Carlos says:\nLooking forward to that blog post about parse migration\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/parse-update-faster-windows-desktop-uwp-guide/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/parse-update-faster-windows-desktop-uwp-guide/universal-windows-apps_thumb.jpg\"\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003eHistorical note:\u003c/strong\u003e Codename One\u0026rsquo;s UWP target was discontinued in release \u003cstrong\u003e7.0.229\u003c/strong\u003e. This post is preserved for historical context only, and its build/setup instructions no longer apply to current Codename One projects.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/sidiabale\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eChidiebere Okwudire\u003c/a\u003e of \u003ca href=\"https://www.smash-ict.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eSMash ICT Solutions\u003c/a\u003e just\u003cbr\u003e\nreleased \u003ca href=\"https://github.com/sidiabale/parse4cn1/releases/tag/parse4cn1-3.0\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eversion 3.0 of the parse4cn1 library\u003c/a\u003e.\u003cbr\u003e\nThe biggest feature of which is support for the open source Parse server which should work with some of the\u003cbr\u003e\nparse alternatives that popped up to fill the void left by Facebook.\u003c/p\u003e","title":"Parse Update, Faster Windows Desktop \u0026 UWP Guide"},{"content":"\nBackground fetch allows an app to periodically \u0026ldquo;fetch\u0026rdquo; information from the network while the app is in\nthe background. This is scheduled by the native platform, where apps that support background\nfetch will be started up (in the background), and their performBackgroundFetch method will be invoked.\n__ | Since the app will be launched directly to the background, you cannot assume that the\nstart() method was invoked prior to the performBackgroundFetch call Implementing Background Fetch Apps that wish to implement background fetch must implement the\nBackgroundFetch\ninterface in their main class.\n__ The main class is the one mentioned in the preferences not the state machine or some other class! On iOS, you also need to include fetch in the list of background modes specifically include fetch in the\nios.background_modes build hint e.g.:\nios.background_modes=fetch Or for more than one mode:\nios.background_modes=fetch,music In addition to implementing the BackgroundFetch interface, apps must explicitly set the background fetch\ninterval by invoking Display.getInstance().setPreferredBackgroundFetchInterval(interval) at some point, usually\nin the start() or init() method.\nPlatform Support Currently background fetch is supported on iOS, Android, and in the Simulator (simulated using timers when the\napp is paused). You should use the Display.getInstance().isBackgroundFetchSupported() call to check if the\ncurrent platform supports it.\nSample The following code demonstrates simple usage of the API:\n/** * A simple demo showing the use of the Background Fetch API. This demo will load * data from the Slashdot RSS feed while it is in the background. * * To test it out, put the app into the background (or select Pause App in the simulator) * and wait 10 seconds. Then open the app again. You should see that the data is loaded. */ public class BackgroundFetchTest implements BackgroundFetch { private Form current; private Resources theme; List\u0026lt;Map\u0026gt; records; // Container to hold the list of records. Container recordsContainer; public void init(Object context) { theme = UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;); // Enable Toolbar on all Forms by default Toolbar.setGlobalToolbar(true); // Pro only feature, uncomment if you have a pro subscription // Log.bindCrashProtection(true); } public void start() { if(current != null){ // Make sure we update the records as we are coming in from the // background. updateRecords(); current.show(); return; } Display d = Display.getInstance(); Form hi = new Form(\u0026quot;Background Fetch Demo\u0026quot;); hi.setLayout(new BoxLayout(BoxLayout.Y_AXIS)); Label supported = new Label(); if (d.isBackgroundFetchSupported()){ // This call is necessary to initialize background fetch d.setPreferredBackgroundFetchInterval(10); supported.setText(\u0026quot;Background Fetch IS Supported\u0026quot;); } else { supported.setText(\u0026quot;Background Fetch is NOT Supported\u0026quot;); } hi.addComponent(new Label(\u0026quot;Records:\u0026quot;)); recordsContainer = new Container(new BoxLayout(BoxLayout.Y_AXIS)); //recordsContainer.setScrollableY(true); hi.addComponent(recordsContainer); hi.addComponent(supported); updateRecords(); hi.show(); } /** * Update the UI with the records that are currently loaded. */ private void updateRecords() { recordsContainer.removeAll(); if (records != null) { for (Map m : records) { recordsContainer.addComponent(new SpanLabel((String)m.get(\u0026quot;title\u0026quot;))); } } else { recordsContainer.addComponent(new SpanLabel(\u0026quot;Put the app in the background, wait 10 seconds, then open it again. The app should background fetch some data from the Slashdot RSS feed and show it here.\u0026quot;)); } if (Display.getInstance().getCurrent() != null) { Display.getInstance().getCurrent().revalidate(); } } public void stop() { current = Display.getInstance().getCurrent(); if(current instanceof Dialog) { ((Dialog)current).dispose(); current = Display.getInstance().getCurrent(); } } public void destroy() { } /** * This method will be called in the background by the platform. It will * load the RSS feed. Note: This only runs when the app is in the background. * @param deadline * @param onComplete */ @Override public void performBackgroundFetch(long deadline, Callback\u0026lt;Boolean\u0026gt; onComplete) { RSSService rss = new RSSService(\u0026quot;http://rss.slashdot.org/Slashdot/slashdotMain\u0026quot;); NetworkManager.getInstance().addToQueueAndWait(rss); records = rss.getResults(); System.out.println(records); onComplete.onSucess(Boolean.TRUE); } } Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nNick Koirala — June 22, 2016 at 5:13 am (permalink) Nick Koirala says:\nJust tried this out on Android.\nIt looks good, and I was pleased to see that I can schedule a local notification from the backgroundFetch, so if there is a reason for the user to open the app based on the background fetch it is possible.\nI’ve found that you can’t poll faster than 60 seconds, not a big problem, an update every minute is still plenty, but might be worth noting as the example code uses 10 seconds, but that’s not what result I’m getting on my phone. If you set it lower then it’ll just call the method every 60 seconds.\nLukman Javalove Idealist Jaji — June 23, 2016 at 9:00 am (permalink) Lukman Javalove Idealist Jaji says:\nWill it be a good programming practice to use this feature to connect to a remote DB every x minutes? Or is there a more effective way to achieve this? Sometimes when the back button is pressed on the MainForm, the app ought to be minmized but when I reopen, it looks like the app starts all over again. Does this feature prevent that?\nShai Almog — June 24, 2016 at 6:24 am (permalink) Shai Almog says:\nProbably not, it will grind your battery down to nothing. The right thing to do is to use push to trigger an update.\nLukman Javalove Idealist Jaji — June 26, 2016 at 6:36 am (permalink) Lukman Javalove Idealist Jaji says:\nThanks Shai .. does this apply also to on device background checks … say if a file exists in storage or on the filesystem\nShai Almog — June 27, 2016 at 3:04 am (permalink) Shai Almog says:\nI have no idea. I’m guessing it should work.\nScott Turner — May 11, 2017 at 2:21 pm (permalink) Scott Turner says:\nI noticed an issue with the BackgroundFetch functionality. It’s not mentioned in this blog post, but for ios, you have to set ios.locationusagedescription in the build hints, otherwise it won’t hit the performBackgroundFetch callback on apple devices. It took me several hours of poking around to figure this out, so it’s definitely worth amending the post.\nShai Almog — May 12, 2017 at 12:25 pm (permalink) Shai Almog says:\nI’m not familiar enough with that piece of code so I asked about it. I understand that there should be no dependency on location usage description so if this happens with a simple hello world that might be a bug. One thing I did understand is that iOS is ridiculously sensitive about background behavior. So if you use things like location etc. this might fail by crashing with no messages or any indication of what went wrong.\nScott Turner — May 12, 2017 at 12:48 pm (permalink) Scott Turner says:\nThanks, Shai. After playing around with BackgroundFetch I realized it wasn’t really right for my use case anyway. It’s far too unpredictable on ios. I need it to hit reliably at least once every 30 seconds and it seems like it doesn’t allow that sort of flexibility. Oh well! Thanks for the follow up.\nCh Hjelm — May 20, 2019 at 8:28 pm (permalink) Ch Hjelm says:\nI understand that only init() will be executed before performBackgroundFetch is run in the background. If I have a lot of things being executed on a normal application startup (and which are not necessary for the performBackgroundFetch to execute), I guess that initialization code should then rather go into start() to avoid slowing the performBackgroundFetch down (with the risk that it takes too long and get killed). In which case, start() should test on whether current is null like in your example, and only execute all the initialization code if current actually is null. Would you agree this is the best approach?\nShai Almog — May 21, 2019 at 4:26 am (permalink) Shai Almog says:\nThis is standard Codename One code that has nothing to do with suspend resume. I suggest checking out the second chapter of the uber book available for free here: https://uber.cn1.co/ look for the part about application lifecycle.\ninit is only invoked when the app is launched from destroyed mode (cold start). Start is invoked on resume from suspended mode. This lets us detect a case of resume which might be applicable.\nCh Hjelm — May 21, 2019 at 6:42 am (permalink) Ch Hjelm says:\nThanks. I already understand the life cycle (and I have your book :-)) and my question IS specific to background fetch. To rephrase: today I have a lot of heavy initialization in init() which is only needed if a user cold-starts the app but not necessary if the app is cold-started just to run the performBackgroundFetch . If all that initialization code is run on every background fetch it may slow down the fetch and the app may get killed, or at least it will consume unnecessary battery. So, I just wanted to double check if it is a good/workable approach to move the heavy initialization into start() using the pattern shown below?\nstart() { if (current!=null) { current.show(); return; } else { //heavy initialization normally placed in init(), only needed for user but not necessary for background fetch } //normal start code… }\nHope I managed to make it clear. I basically want to double check with your expertise because any issues here could be difficult to catch in the Simulator or in device testing.\nShai Almog — May 22, 2019 at 9:33 am (permalink) Shai Almog says:\nYou shouldn’t write any code there. It could slow down restore and you should minimize code in init as they can trigger ANR’s (app not responding). In a case of ANR your app could be killed instantly. You can start a thread in the init code and do initialization logic there after a small delay to let the UI grab some CPU. There is no reason to prefer start over init() for this sort of logic though.\nArthur Major — July 23, 2021 at 4:42 pm (permalink) Arthur Major says:\nI tested this code and works good in Android 7 and below, but Android 8+ just run once, is there something else I have to do?\nSteve Hannah — July 23, 2021 at 5:04 pm (permalink) Steve Hannah says:\nBackground execution has gotten a lot harder with newer versions of Android. It is difficult to predict when the platform will run your background tasks, and they may be blocked for any reason on both Android and iOS. If you can check the device log it might give you a clue as to what its \u0026ldquo;complaint\u0026rdquo; is.\nArthur Major — July 23, 2021 at 11:57 pm (permalink) Arthur Major says:\n2021-07-23 17:25:42.650 8479-8479/? D/ViewRootImpl@984f7f7[SigueloNotifAppStub]: setView = DecorView@bbbdd82[SigueloNotifAppStub] TM=true MM=false\n2021-07-23 17:25:42.651 8479-8479/? D/ViewRootImpl@984f7f7[SigueloNotifAppStub]: dispatchAttachedToWindow\n2021-07-23 17:25:42.677 8479-8479/? D/ViewRootImpl@984f7f7[SigueloNotifAppStub]: Relayout returned: old=[0,0][0,0] new=[0,0][1080,1920] result=0x7 surface={valid=true 535584559104} changed=true\n2021-07-23 17:25:42.721 8479-8479/? D/ViewRootImpl@984f7f7[SigueloNotifAppStub]: MSG_RESIZED_REPORT: frame=Rect(0, 0 – 1080, 1920) ci=Rect(0, 72 – 0, 0) vi=Rect(0, 72 – 0, 0) or=1\n2021-07-23 17:25:42.721 8479-8479/? D/ViewRootImpl@984f7f7[SigueloNotifAppStub]: MSG_WINDOW_FOCUS_CHANGED 1\n2021-07-23 17:25:48.534 8479-8479/? D/ViewRootImpl@984f7f7[SigueloNotifAppStub]: MSG_WINDOW_FOCUS_CHANGED 0\n2021-07-23 17:25:48.603 8479-8479/? D/ViewRootImpl@984f7f7[SigueloNotifAppStub]: Relayout returned: old=[0,0][1080,1920] new=[0,0][1080,1920] result=0x5 surface={valid=false 0} changed=true\n2021-07-23 17:25:48.650 8479-8479/? D/ViewRootImpl@984f7f7[SigueloNotifAppStub]: Relayout returned: old=[0,0][1080,1920] new=[0,0][1080,1920] result=0x1 surface={valid=false 0} changed=false\n2021-07-23 17:25:53.304 8668-8668/? D/ViewRootImpl@de60cd[SigueloNotifAppStub]: setView = DecorView@bbbdd82[SigueloNotifAppStub] TM=true MM=false\n2021-07-23 17:25:53.313 8668-8668/? D/ViewRootImpl@de60cd[SigueloNotifAppStub]: dispatchAttachedToWindow\n2021-07-23 17:25:53.346 8668-8668/? D/ViewRootImpl@de60cd[SigueloNotifAppStub]: Relayout returned: old=[0,0][0,0] new=[0,0][1080,1920] result=0x7 surface={valid=true 535584444416} changed=true\n2021-07-23 17:25:53.385 8668-8668/? D/ViewRootImpl@de60cd[SigueloNotifAppStub]: MSG_RESIZED_REPORT: frame=Rect(0, 0 – 1080, 1920) ci=Rect(0, 72 – 0, 0) vi=Rect(0, 72 – 0, 0) or=1\n2021-07-23 17:25:53.385 8668-8668/? D/ViewRootImpl@de60cd[SigueloNotifAppStub]: MSG_WINDOW_FOCUS_CHANGED 1\n2021-07-23 17:25:58.730 8668-8668/? D/ViewRootImpl@de60cd[SigueloNotifAppStub]: MSG_WINDOW_FOCUS_CHANGED 0\n2021-07-23 17:25:58.775 8668-8668/? D/ViewRootImpl@de60cd[SigueloNotifAppStub]: Relayout returned: old=[0,0][1080,1920] new=[0,0][1080,1920] result=0x5 surface={valid=false 0} changed=true\n2021-07-23 17:25:58.884 8668-8668/? D/ViewRootImpl@de60cd[SigueloNotifAppStub]: Relayout returned: old=[0,0][1080,1920] new=[0,0][1080,1920] result=0x1 surface={valid=false 0} changed=false\n2021-07-23 17:27:39.347 8668-8668/? D/ViewRootImpl@de60cd[SigueloNotifAppStub]: Relayout returned: old=[0,0][1080,1920] new=[0,0][1080,1920] result=0x1 surface={valid=false 0} changed=false\n2021-07-23 17:27:39.394 8668-8668/? D/ViewRootImpl@de60cd[SigueloNotifAppStub]: Relayout returned: old=[0,0][1080,1920] new=[0,0][1080,1920] result=0x7 surface={valid=true 535346876416} changed=true\n2021-07-23 17:27:39.409 8668-8668/? D/ViewRootImpl@de60cd[SigueloNotifAppStub]: MSG_WINDOW_FOCUS_CHANGED 1\n2021-07-23 17:27:43.525 8668-8668/? D/ViewRootImpl@de60cd[SigueloNotifAppStub]: MSG_WINDOW_FOCUS_CHANGED 0\n2021-07-23 17:27:43.596 8668-8668/? D/ViewRootImpl@de60cd[SigueloNotifAppStub]: Relayout returned: old=[0,0][1080,1920] new=[0,0][1080,1920] result=0x5 surface={valid=false 0} changed=true\n2021-07-23 17:27:43.677 8668-8668/? D/ViewRootImpl@de60cd[SigueloNotifAppStub]: Relayout returned: old=[0,0][1080,1920] new=[0,0][1080,1920] result=0x1 surface={valid=false 0} changed=false\nThat’s all the log I got when it runs.\nSteve Hannah — July 28, 2021 at 12:54 pm (permalink) Steve Hannah says:\nI’ve done some digging on this, and believe I have found the issue. (described here https://developer.android.com/about/versions/oreo/background.html#services).\n\u0026ldquo;Prior to Android 8.0, the usual way to create a foreground service was to create a background service, then promote that service to the foreground. With Android 8.0, there is a complication; the system doesn’t allow a background app to create a background service. For this reason, Android 8.0 introduces the new method startForegroundService() to start a new service in the foreground. After the system has created the service, the app has five seconds to call the service’s startForeground() method to show the new service’s user-visible notification. If the app does not call startForeground() within the time limit, the system stops the service and declares the app to be ANR.\u0026rdquo;\nThis doesn’t offer a clear solution at your level, unfortunately, other than attempting to keep execution of background fetches under 5 seconds — it isn’t clear whether that is a solution or not.\nWorking around these growing background execution restrictions is tricky. We may end up deprecating some of these background execution APIs and shifting to implementing this type of thing in cn1libs.\nArthur Major — July 28, 2021 at 4:44 pm (permalink) Arthur Major says:\nThanks for your response, so i think in this case is better continue with a native solution.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/background-fetch/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/background-fetch/background-fetch.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eBackground fetch allows an app to periodically \u0026ldquo;fetch\u0026rdquo; information from the network while the app is in\u003cbr\u003e\nthe background. This is scheduled by the native platform, where apps that support background\u003cbr\u003e\nfetch will be started up (in the background), and their \u003ccode\u003eperformBackgroundFetch\u003c/code\u003e method will be invoked.\u003c/p\u003e\n\u003cp\u003e__ |  Since the app will be launched directly to the background, you cannot assume that the\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e\u003ccode\u003estart()\u003c/code\u003e method was invoked prior to the \u003ccode\u003eperformBackgroundFetch\u003c/code\u003e call\u003c/th\u003e\n          \u003cth\u003e\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"implementing-background-fetch\"\u003eImplementing Background Fetch\u003c/h3\u003e\n\u003cp\u003eApps that wish to implement background fetch must implement the\u003cbr\u003e\n\u003ca href=\"/javadoc/com/codename1/background/BackgroundFetch/\"\u003eBackgroundFetch\u003c/a\u003e\u003cbr\u003e\ninterface in their main class.\u003c/p\u003e","title":"Background Fetch"},{"content":"\nA couple of weeks ago we detailed a plan to migrate to the new xcode 7.x\nbuild servers. We tried this migration over the weekend and while for most developers this worked rather nicely\nfor some there were issues that we can’t explain so we decided to revert the change and regroup.\nWe want this transition to be smoother than past transitions and since we aren’t currently working against a\ndeadline we feel we have some time to refine this migration to a point where it will be seamless for all/most\nof our users.\nWe don’t have a set date to retry the migration but we are currently aiming for 2-3 weeks from now.\nThe main issue involves the rather elaborate build script we have in place since the days of xcode 4.x. It seems\nthat for some applications or provisioning profiles xcode just crashes…​\nThe solution is probably to build the application in a rather different way than we current do which might not crash\nxcode but unfortunately this will make this change \u0026amp; migration more complicated than we initially hoped so the\nsensible solution seems to be to move back to the iphone_new mode and make builds go to the old servers\nwhile we experiment.\nWe will announce details of the second attempt at migration in this blog…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/ios-migration-setback/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/ios-migration-setback/xcode-migration.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA couple of weeks ago we \u003ca href=\"/blog/ios-migration-continued.html\"\u003edetailed a plan\u003c/a\u003e to migrate to the new xcode 7.x\u003cbr\u003e\nbuild servers. We tried this migration over the weekend and while for most developers this worked rather nicely\u003cbr\u003e\nfor some there were issues that we can’t explain so we decided to revert the change and regroup.\u003c/p\u003e\n\u003cp\u003eWe want this transition to be smoother than past transitions and since we aren’t currently working against a\u003cbr\u003e\ndeadline we feel we have some time to refine this migration to a point where it will be seamless for all/most\u003cbr\u003e\nof our users.\u003c/p\u003e","title":"iOS Migration Setback"},{"content":"\nThe Accordion ui pattern\nis a vertically stacked list of items. Each item can be opened/closed to reveal more content similarly to a\nTree however unlike the\nTree the Accordion is designed to include containers or arbitrary components rather than model based data.\nThis makes the Accordion more convenient as a tool for folding/collapsing UI elements known in advance\nwhereas a Tree makes more sense as a tool to map data e.g. filesystem structure, XML hierarchy etc.\nNote that the Accordion like many composite components in Codename One is scrollable by default which\nmeans you should use it within a non-scrollable hierarchy. If you wish to add it into a scrollable Container you\nshould disable it’s default scrollability using setScrollable(false).\nForm f = new Form(\u0026quot;Accordion\u0026quot;, new BorderLayout()); Accordion accr = new Accordion(); accr.addContent(\u0026quot;Item1\u0026quot;, new SpanLabel(\u0026quot;The quick brown fox jumps over the lazy dogn\u0026quot; + \u0026quot;The quick brown fox jumps over the lazy dog\u0026quot;)); accr.addContent(\u0026quot;Item2\u0026quot;, new SpanLabel(\u0026quot;The quick brown fox jumps over the lazy dogn\u0026quot; + \u0026quot;The quick brown fox jumps over the lazy dogn \u0026quot; + \u0026quot;The quick brown fox jumps over the lazy dogn \u0026quot; + \u0026quot;The quick brown fox jumps over the lazy dogn \u0026quot; + \u0026quot;\u0026quot;)); accr.addContent(\u0026quot;Item3\u0026quot;, BoxLayout.encloseY(new Label(\u0026quot;Label\u0026quot;), new TextField(), new Button(\u0026quot;Button\u0026quot;), new CheckBox(\u0026quot;CheckBox\u0026quot;))); f.add(BorderLayout.CENTER, accr); f.show(); Figure 1. Accordion component\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/accordion-component/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/accordion-component/accordion-post.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe \u003ca href=\"/javadoc/com/codename1/components/Accordion/\"\u003eAccordion\u003c/a\u003e ui pattern\u003cbr\u003e\nis a vertically stacked list of items. Each item can be opened/closed to reveal more content similarly to a\u003cbr\u003e\n\u003ca href=\"/javadoc/com/codename1/ui/tree/Tree/\"\u003eTree\u003c/a\u003e however unlike the\u003cbr\u003e\n\u003ccode\u003eTree\u003c/code\u003e the \u003ccode\u003eAccordion\u003c/code\u003e is designed to include containers or arbitrary components rather than model based data.\u003c/p\u003e\n\u003cp\u003eThis makes the \u003ccode\u003eAccordion\u003c/code\u003e more convenient as a tool for folding/collapsing UI elements known in advance\u003cbr\u003e\nwhereas a \u003ccode\u003eTree\u003c/code\u003e makes more sense as a tool to map data e.g. filesystem structure, XML hierarchy etc.\u003c/p\u003e","title":"Accordion Component"},{"content":"\nThis has been a tremendous week with a lot of news \u0026amp; next week will be even more hectic!\nNext week we will turn on the new iOS build servers by default which means a huge change is coming\nthe biggest is probably http connection problems but I’m sure we’ll run into\nquite a few other issues…​\nPlease let us know immediately as you run into issues…​\nOnwards to the activity on stackoverflow this week:\nIS there a way to obtain device screen width and height This was marked as a duplicate despite being very explicitly defined as a Codename One question. I think\nthe biggest takeaway is don’t call anything \u0026ldquo;urgent\u0026rdquo; on stackoverflow…​\nRead on stackoverflow…​\nIs glassPane painting model broken? Surprisingly the answer is yes, we broke something when fixing\nissue 1680 a while back and this should be fixed\nin todays release.\nRead on stackoverflow…​\nSearching for a good parse4cn11 alternative I’m curious about that myself, I’d like to actually keep using parse4cn1 but map it to a different 3rd party server\nfor simpler migration.\nRead on stackoverflow…​\nWebSocket with multiple ClientEndpoints and binary messages Turns out this was a server issue related to the websocket implementation there. I think we need to have better\nwebsocket demos/tutorials as this is picking up as a standard and is really appropriate for Codename One…​\nRead on stackoverflow…​\nAdding multiple multibuttons to a form after querying a webservice When you change a form after it is shown you need to revalidate…​\nAnother common mistake is to change the form from a network thread.\nRead on stackoverflow…​\nSwipe the screens for next pages Tabs was designed with exactly that\nuse case in mind…​\nRead on stackoverflow…​\nApp unfortunately stopped form codenameone with paypal integration When you get that error it means you got an exception that you didn’t catch in the native code.\nRead on stackoverflow…​\nInitialising subcomponents of a GUI form We are in the process of moving to the new GUI builder which is mostly delay due to lack of documentation.\nWe hope to release docs for this in the coming weeks.\nRead on stackoverflow…​\nError in Native Interface It’s often hard to tell what the error is without a call stack or more information.\nRead on stackoverflow…​\nLog in with Facebook using Webview component This was a rather long thread that stretched into several related questions, it turns out that the problem originates\nfrom a slightly older Facebook SDK using an approach Apple suddenly decided to reject.\nFacebook updated the SDK and we already integrated the new SDK to support the new bitcode build mode.\nHowever, to preserve compatibility we limited the SDK only for that new version. So starting with todays\nrelease all builds are using the new Facebook SDK.\nRead on stackoverflow…​\nCodename one Native IOS implementation error: .h file not found This is related to the previous question which was eventually resolved by us but it might be interesting to developers\nworking with native SDKs.\nRead on stackoverflow…​\nHow to include using Smartwatches in an app written with Codename One? We don’t support smartwatches at this time although you should be able to add support for them using native code.\nWe think supporting smartwatches/TV’s should be pretty easy but both depend on demand we get from developers\nwhich is currently non-existent. This might change overnight though.\nRead on stackoverflow…​\nReact on Tree expansion or collapse Tree is very customizeable, I would also recommend checking out the new\nAccordion component\nwhich we will cover more in depth in a post sometime next week…​\nRead on stackoverflow…​\nChange color of checkbox in theme The color of checkboxes in some themes is derived from images, we are trying to slowly de-emphasize that\nin favor of the builtin material design icon font which should make color inheritance much easier.\nRead on stackoverflow…​\nCan not access com.codename1.impl.android.AndroidNativeUtil From nativeInterface You still need import statements when building the native code for an application…​\nRead on stackoverflow…​\nWhy the decreasing the png/jpg quality factor in ImageIO.save() does not decrease the output image file size? It’s nice that people notice small things like that about the API, it was indeed unclear from the JavaDocs that\nthis was acceptable by design.\nRead on stackoverflow…​\nDisable pull-to-refresh on InfiniteContainer in codenameone That’s an easy answer, you can’t. For that we have the InfiniteScrollAdapter which is roughly of the same complexity\nlevel as the InfiniteContainer.\nRead on stackoverflow…​\nHow to prevent west and East elements from overlapping center in BorderLayout BorderLayout is often over simplistic when it comes to some UI styles, in these cases we need more elaborate\nlayouts which we already have…​\nRead on stackoverflow…​\nWhat is the best way to write a GUI in Codename One : Use the designer or code the GUI? One of the motivations we have to switch to the new GUI builder is the fact that it will remove the need to decide\nup-front whether you want to code the UI with the GUI builder or by hand. You could decide this dynamically\non a specific Form.\nRead on stackoverflow…​\nIs Codenameone geofencing locations limited to 1? It’s not, but it is sometimes hard to find out exactly how many locations were bounds and what are the platform\nlimits in regards to location binding.\nRead on stackoverflow…​\nHow to minimize gap between Tab icon and Tab text in Codename one? There is a default padding within the FontImage class, the padding allows for a more whitespace which is\noften more visually pleasing. However, you can turn that off…​\nRead on stackoverflow…​\nError during android build for native interface Native interfaces are sometimes challenging especially if you just copy and paste code, this does need\nsome native coding skills which is why we often recommend leaving the stubs and building the app. Then\nimplementing the native code in the native IDE and copying the results back to Codename One.\nRead on stackoverflow…​\nCodenameOne APK is not zip aligned Google broke Android builds again thru some changes to it’s build again, so we had to scramble to find the\nreason. One of the nice things about Codename One is that we have to do the scrambling after Google/Apple’s\nshenanigans for you…​\nRead on stackoverflow…​\nSpecifying animations and Toolbar items in the resource editor Toolbar didn’t exist during the days we developed the resource editor, we are bringing it more into the new\nGUI builder which will hopefully become our chief tool in the near future.\nRead on stackoverflow…​\nWhy a String drawn on a Graphics object change its position depending on the used skin? This is a bit of a challenging thread, drawString is core to the platform and it’s hard to figure\nout what is the reason for the inconsistency n this thread.\nRead on stackoverflow…​\nAvoid app from closing on app switching Controlling lifecycle in mobile is problematic, a lot of the assumptions that are true for desktop just don’t carry\nover…​\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-x/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-x/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis has been a tremendous week with a lot of news \u0026amp; next week will be even more hectic!\u003cbr\u003e\nNext week we will turn on the new iOS build servers by default which means a huge change is coming\u003cbr\u003e\nthe biggest is probably \u003ca href=\"/blog/ios-http-urls.html\"\u003ehttp connection problems\u003c/a\u003e but I’m sure we’ll run into\u003cbr\u003e\nquite a few other issues…​\u003c/p\u003e\n\u003cp\u003ePlease let us know immediately as you run into issues…​\u003c/p\u003e\n\u003cp\u003eOnwards to the activity on stackoverflow this week:\u003c/p\u003e","title":"Questions of the Week X"},{"content":"\nWe’ll be migrating to the new iOS build servers\nthis Sunday \u0026amp; this does entail one major thing you need to be aware of. With the new version of xcode http\nURL’s are blocked by Apple. We\nblogged about this a while back but this bares repeating as it’s something a lot of you will start running into.\nTo get an overview of the issue check out\nthis article or\nthe actual document from Apple.\nIn a nutshell http URL’s are no longer supported by Apple to facilitate proper security.\nYou can disable this block by using the build hint\nios.plistInject=\u0026lt;key\u0026gt;NSAppTransportSecurity\u0026lt;/key\u0026gt;\u0026lt;dict\u0026gt;\u0026lt;key\u0026gt;NSAllowsArbitraryLoads\u0026lt;/key\u0026gt;\u0026lt;true/\u0026gt;\u0026lt;/dict\u0026gt;\nbut if you don’t have a good reason to do this Apple will reject your app and won’t let you ship your app\nthru the appstore.\nBe sure to update your apps!\nStarting with this update our simulator will print out a warning every time you try to connect to an HTTP URL\nto help you detect the cases where you do so. Hopefully this will make the migration to the new servers smoother. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nGareth Murfin — June 16, 2016 at 5:02 pm (permalink) Gareth Murfin says:\nSo HttpS will be fine right?\nShai Almog — June 17, 2016 at 3:40 am (permalink) Shai Almog says:\nThat’s the goal. To force apps to use proper https sites and proper security.\nI understand the logic here. In a browser you can see the lock icon on the top left and know if you are submitting to a secure website. In an app there is no such indication.\nEric Coolman — July 1, 2016 at 11:24 pm (permalink) Eric Coolman says:\nATS minimum defaults: HTTPS + TLS 1.2 + FS\nhttps://developer.apple.com…\nSo far we haven’t been flagged for enabling arbitrary loads support with our banking apps, but I’m sure Apple will start clamping down soon.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/ios-http-urls/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/ios-http-urls/xcode-migration.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ll be \u003ca href=\"/blog/ios-server-migration-plan.html\"\u003emigrating to the new iOS build servers\u003c/a\u003e\u003cbr\u003e\nthis Sunday \u0026amp; this does entail one major thing you need to be aware of. With the new version of xcode http\u003cbr\u003e\nURL’s \u003ca href=\"/blog/hiding-url-security-advocacy.html\"\u003eare blocked by Apple\u003c/a\u003e. We\u003cbr\u003e\nblogged about this a while back but this bares repeating as it’s something a lot of you will start running into.\u003c/p\u003e\n\u003cp\u003eTo get an overview of the issue check out\u003cbr\u003e\n\u003ca href=\"http://code.tutsplus.com/articles/apple-tightens-security-with-app-transport-security%e2%80%94%e2%80%8bcms-24420\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ethis article\u003c/a\u003e or\u003cbr\u003e\nthe \u003ca href=\"https://developer.apple.com/library/mac/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eactual document from Apple\u003c/a\u003e.\u003cbr\u003e\nIn a nutshell http URL’s are no longer supported by Apple to facilitate proper security.\u003c/p\u003e","title":"iOS Http URL's"},{"content":"\nSocialBoo originated from the same app design vault set\nof designs that brought us the Chrome Demo. This demo uses a somewhat outdated but still reasonable gunmetal look, it also features different UI styles when running\non a tablet/phone. Notice in the screenshot above that the UI for the demo differs when running in a\nphone/tablet and even changes when the tablet flips between portrait and landscape…​\nThis demo was originally created using the old GUI builder but was modernized to use the new GUI builder.\nCheck the live version running on the right hand side thanks to the power of the Codename One JavaScript port!\nYou can check out the\nfull source code here.\nWe barely changed anything in this demo, although it did \u0026ldquo;age\u0026rdquo; it still looks reasonable even today. One of the\nfew things added was a button to toggle the phone/tablet mode, this is really useful for a demo to show off\nhow these differences apply especially when running in a browser.\nWe replaced the old title behavior with the new Toolbar API, this required a few code changes but not much and\nin terms of the design we didn’t need to do anything…​\nThe switch from the old GUI builder to the new GUI builder almost worked but there was some reliance on splash\nscreen support in the old code. This isn’t supported by the new GUI builder as there is no concept of \u0026ldquo;flow\u0026rdquo;\nso we replicated roughly the same behavior using:\nif(SocialBoo.isTabletMode()) { UITimer.timer(2000, false, this, () -\u0026gt; new Person().show()); } else { UITimer.timer(2000, false, this, () -\u0026gt; new Main().show()); } Notice that we used the SocialBoo.isTabletMode() call instead of Display.getInstance().isTablet(). We did that\nto allow forcing tablet/phone mode which is great for a demo although not really necessary for a \u0026ldquo;real world app\u0026rdquo;.\nUp Next Social Boo isn’t currently a part of the builtin demos in the IDE’s but I think it should be. In our last update we\nwere supposed to include some of the revised demos but the build scripts didn’t chug correctly and some demos\njust didn’t make it…​\nWe fixed the scripts so hopefully Social Boo and the other demos we’ve revisited will all make it to the coming\nplugin updates. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nsalah Alhaddabi — December 22, 2016 at 4:43 pm (permalink) salah Alhaddabi says:\nDear shai,\nCan you please help me i dont know exactly how to clone this prject from github. When i import it using the download url it only clones the source folder and when i try to edit the form java classes it gives an error that the gui builder is only for classes created with the new gui builder.\nCan you please guide me how to clone this project so after i clone it it appears as if it was created using the netbeans codename one plugin???\nThanks a lot in advance…\nShai Almog — December 23, 2016 at 6:36 am (permalink) Shai Almog says:\nHi,\nIt was created with NetBeans. I’m assuming you use Eclipse?\nYou need to create a new project with the right package names and copy the source/properties and resources into the eclipse workspace.\nsalah Alhaddabi — December 24, 2016 at 7:13 am (permalink) salah Alhaddabi says:\nDear Shai I am using netbeans\nI want to know how to clone the project using netbeans please\nShai Almog — December 24, 2016 at 9:12 am (permalink) Shai Almog says:\nFile -\u0026gt; New Project -\u0026gt; Codename One -\u0026gt; Demos -\u0026gt; Social Boo…\nsalah Alhaddabi — December 24, 2016 at 5:53 pm (permalink) salah Alhaddabi says:\nDear Shai thanks a lot.\nNow I have deleted the themes from the old GUI designer and only kept the UIIDs and the imported images.\nI am depending on the new GUI builder. When I run the app in the simulator I got the following issues:\nError messages in the generated code in Main.java file\nWhen I checked I found that all of the setPropertyValue methods which have \u0026ldquo;icon\u0026rdquo;, \u0026ldquo;icons\u0026rdquo;, or \u0026ldquo;selectedIcons\u0026rdquo; property name are not generated correctly.\nFor example, the closing parentheses in the following statement is missing when the code is regenerated every time the app is run:\ngui_JessicaButton.setPropertyValue(\u0026ldquo;icon\u0026rdquo;, (resourceObjectInstance.getImage(\u0026ldquo;avatar-1a.jpg\u0026rdquo;));\nThere are other similar icon setters methods in the same file that have the same issue.\nDue to that I am not able to run the app. Please help.\nShai Almog — December 25, 2016 at 8:23 am (permalink) Shai Almog says:\nThanks I see the bug. Unfortunately the only workaround I can see for now is to edit the .GUI file by hand and deleting this block:\n\u0026lt;custom name=\u0026#34;icons\u0026#34; type=\u0026#34;com.codename1.ui.Image\u0026#34; array=\u0026#34;true\u0026#34; dimensions=\u0026#34;1″\u0026gt; \u0026lt;str\u0026gt;friends@2x.png\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;chats@2x.png\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;send-email@2x.png\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;settings@2x.png\u0026lt;/str\u0026gt; \u0026lt;/custom\u0026gt; \u0026lt;custom name=\u0026#34;selectedIcons\u0026#34; type=\u0026#34;com.codename1.ui.Image\u0026#34; array=\u0026#34;true\u0026#34; dimensions=\u0026#34;1″\u0026gt; \u0026lt;str\u0026gt;friends@2x_sel.png\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;chats@2x_sel.png\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;send-email@2x_sel.png\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;settings@2x_sel.png\u0026lt;/str\u0026gt; \u0026lt;/custom\u0026gt; We’ve committed a fix for this but because it needs a plugin update it might take a couple of weeks to release it as it’s a longer cycle than the typical library cycle.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/social-boo-revisited/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/social-boo-revisited/socialboo.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSocialBoo originated from the same \u003ca href=\"http://www.appdesignvault.com/shop/social-boo/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eapp design vault\u003c/a\u003e set\u003cbr\u003e\nof designs that brought us the Chrome Demo. This demo uses a somewhat outdated but still reasonable gunmetal look, it also features different UI styles when running\u003cbr\u003e\non a tablet/phone. Notice in the screenshot above that the UI for the demo differs when running in a\u003cbr\u003e\nphone/tablet and even changes when the tablet flips between portrait and landscape…​\u003c/p\u003e\n\u003cp\u003eThis demo was originally created using the old GUI builder but was modernized to use the new GUI builder.\u003c/p\u003e","title":"Social Boo Revisited"},{"content":"\nAre you interested in selling your custom made themes, templates \u0026amp; libraries for Codename One?\nEric Dodji Gbofu founder of Codename One Fr and author of the French language\nCodename One book is launching\na Codename One store.\nThis is meant as a Codename One equivalent to sites such as theme forest that provide ready made templates\nof various kinds for a reasonable price. It answers a very common need within the community to get started\nwith a cookie cutter solution.\nThe site has been under development for a while and is now collecting submissions of themes, templates, libraries\netc.\nIf you have questions about the site there is also an email contact there as well.\nWe are quite pleased with the community picking up such things, but keep in mind that the site isn’t directly\naffiliated with us so we can’t answer questions or provide help/advice in that regard.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-store/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-store/generic-java-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAre you interested in selling your custom made themes, templates \u0026amp; libraries for Codename One?\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://twitter.com/doderic/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eEric Dodji Gbofu\u003c/a\u003e founder of \u003ca href=\"http://www.codenameonefr.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCodename One Fr\u003c/a\u003e and author of the French language\u003cbr\u003e\n\u003ca href=\"/blog/book-continued-migration/\"\u003eCodename One book\u003c/a\u003e is launching\u003cbr\u003e\na \u003ca href=\"http://www.codenameone-store.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCodename One store\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eThis is meant as a Codename One equivalent to sites such as theme forest that provide ready made templates\u003cbr\u003e\nof various kinds for a reasonable price. It answers a very common need within the community to get started\u003cbr\u003e\nwith a cookie cutter solution.\u003c/p\u003e","title":"Codename One Store"},{"content":"\nThe Toolbar is a pretty flexible\nAPI for handling the title area. It allows a lot of things including search but up until now that very common\nuse case was not a standard part of the API.\nIt is now, we just added a new API that effectively allows you to bind search to a form and just get the text\nsearched as part of the callback. The Toolbar handles everything else including replacing the title area\nand returning it back to its original state when you are done.\nYou can also customize the appearance of the search bar by using the UIID’s: ToolbarSearch, TextFieldSearch \u0026amp;\nTextHintSearch.\nIn the sample below we fetch all the contacts from the device and enable search thru them, notice it expects\nand image called duke.png which is really just the default Codename One icon renamed and placed in the src\nfolder:\nImage duke = null; try { duke = Image.createImage(\u0026quot;/duke.png\u0026quot;); } catch(IOException err) { Log.e(err); } int fiveMM = Display.getInstance().convertToPixels(5); final Image finalDuke = duke.scaledWidth(fiveMM); Toolbar.setGlobalToolbar(true); Form hi = new Form(\u0026quot;Search\u0026quot;, BoxLayout.y()); hi.add(new InfiniteProgress()); Display.getInstance().scheduleBackgroundTask(()-\u0026gt; { // this will take a while... Contact[] cnts = Display.getInstance().getAllContacts(true, true, true, true, false, false); Display.getInstance().callSerially(() -\u0026gt; { hi.removeAll(); for(Contact c : cnts) { MultiButton m = new MultiButton(); m.setTextLine1(c.getDisplayName()); m.setTextLine2(c.getPrimaryPhoneNumber()); Image pic = c.getPhoto(); if(pic != null) { m.setIcon(fill(pic, finalDuke.getWidth(), finalDuke.getHeight())); } else { m.setIcon(finalDuke); } hi.add(m); } hi.revalidate(); }); }); hi.getToolbar().addSearchCommand(e -\u0026gt; { String text = (String)e.getSource(); if(text == null || text.length() == 0) { // clear search for(Component cmp : hi.getContentPane()) { cmp.setHidden(false); cmp.setVisible(true); } hi.getContentPane().animateLayout(150); } else { text = text.toLowerCase(); for(Component cmp : hi.getContentPane()) { MultiButton mb = (MultiButton)cmp; String line1 = mb.getTextLine1(); String line2 = mb.getTextLine2(); boolean show = line1 != null \u0026amp;\u0026amp; line1.toLowerCase().indexOf(text) \u0026gt; -1 || line2 != null \u0026amp;\u0026amp; line2.toLowerCase().indexOf(text) \u0026gt; -1; mb.setHidden(!show); mb.setVisible(show); } hi.getContentPane().animateLayout(150); } }, 4); hi.show(); Up Next I think this shows some of the directions we will be taking with Codename One components as we move forward.\nFuture components from us will make more use of the icon fonts and material design icons to allow a default\nlook that \u0026ldquo;just works\u0026rdquo; everywhere.\nYou would still be able to customize everything like you always did but unlike the past, we hope the default look\nwill start off as both functional and attractive. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMac Flanegan — February 17, 2017 at 9:08 pm (permalink) Mac Flanegan says:\nHi Guys,\nHow do I translate the text (\u0026ldquo;Search\u0026rdquo; ) of TextHintSearch?\nI’m testing on Android and I notice a strange behavior.\nIs it possible to delete any forrm animation? To avoid appearing to be reloaded?\nI have commented hi.getContentPane().animateLayout(150); but still flickering the form when click in back.\nWhen testing on Android (did not test on others), and start typing, does not show the magnifying glass icon in \u0026ldquo;Enter\u0026rdquo; key of keyboard, is possible?\nAnd also does not accept ENTER in search text field. To perform the search I have to hit back (on device) and only then the text is accepted and search performed.\nI believe the component is interpreting ENTER as a new line rather than executing the command.\nShai Almog — February 18, 2017 at 10:57 am (permalink) Shai Almog says:\nHi,\nI’ll make it so \u0026ldquo;m.search\u0026rdquo; in the resource bundle will allow you to localize this. This video is a bit old but it discusses localizations: https://www.codenameone.com…\nCurrently we don’t support disabling the animation but what did you do that triggered this? It’s hard for me to visualize the issue you’re seeing.\nThe magnifying glass issue is a simple fix I’m surprised we didn’t notice that. It should be fixed in the coming update.\nSearch happens as you type so I’m not sure how you are seeing that behavior. I think the problem is that you aren’t using revalidate or animateLayout to show your changes to the UI and so the search only updates when we do it on the back button.\nMac Flanegan — February 18, 2017 at 12:47 pm (permalink) Mac Flanegan says:\nThanks,\nI’ll work a little on it.\nPS: It may be interesting to leave the SearchTextField field public.\nSo I could make small hacks like search.getSearchTextField (). PutClientProperty (\u0026ldquo;searchField\u0026rdquo;, Boolean.TRUE);\nShai Almog — February 19, 2017 at 7:15 am (permalink) Shai Almog says:\nThe problem with doing things like this is that the more you expose people end up relying on edge cases of the API and you can’t change them. E.g. in the future we might want to support iOS style search where the text field appears below the title. If we expose too much of the implementation details this can become a problem.\nNotice you can still add features to this thru a pull request to our main repository which is really easy to do: https://www.codenameone.com…\nNils Lamb — August 4, 2017 at 12:08 pm (permalink) Nils Lamb says:\nI added the \u0026ldquo;m.search\u0026rdquo; key into my custom resource bundle. This currently contains the locales de and en, which works fine for the rest of the application. However, the search hint text which defaults to \u0026ldquo;Search\u0026rdquo; in english, does not use the values from the m.search key.\nIs this implemented already?\nShai Almog — August 5, 2017 at 6:23 am (permalink) Shai Almog says:\nYes it was implemented but looking at the code it’s possible this wasn’t 100% correct for all cases. I made a fix which will hopefully resolve the issue you are seeing.\nYaakov Gesher — February 27, 2018 at 1:25 pm (permalink) Yaakov Gesher says:\nHi, is there a way to filter out the events from the SearchBar so that I know when the ENTER key was pressed? I’m interested in only executing a search when the user initiates it by pressing the search key\nShai Almog — February 28, 2018 at 8:59 am (permalink) Shai Almog says:\nNo. Right now the search bar is only designed for interactive search.\nYou can create a completely custom toolbar with the samples in the Toolbar class in the JavaDoc. You can change the datachange listener to an action listener or done listener in that code.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/toolbar-search-mode/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/toolbar-search-mode/toolbar-search-mode.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe \u003ca href=\"/javadoc/com/codename1/ui/Toolbar/\"\u003eToolbar\u003c/a\u003e is a pretty flexible\u003cbr\u003e\nAPI for handling the title area. It allows a lot of things including search but up until now that very common\u003cbr\u003e\nuse case was not a standard part of the API.\u003c/p\u003e\n\u003cp\u003eIt is now, we just added a new API that effectively allows you to bind search to a form and just get the text\u003cbr\u003e\nsearched as part of the callback. The \u003ccode\u003eToolbar\u003c/code\u003e handles everything else including replacing the title area\u003cbr\u003e\nand returning it back to its original state when you are done.\u003c/p\u003e","title":"Toolbar Search Mode"},{"content":"\nHistorical note: Codename One\u0026rsquo;s UWP target was discontinued in release 7.0.229. This post is preserved for historical context only, and its build/setup instructions no longer apply to current Codename One projects.\nAfter many months of work and effort put in by all of us but especially by Steve Hannah and\nFabrício Carvalho Cabeça we are finally live with the Windows Universal Platform (AKA UWP)\nnative build target!\nAs far as I know Codename One is the only native option for Java developers to build native Windows UWP apps.\n__ Notice that this target is still in technology preview stage! Please report any issue you run into Besides the effort of building the Codename One port with everything it entails (including newer build servers)\nwe also leveraged the ambitious iKVM project which we had to modify extensively with\nthe help of some community members specifically Eugene who proved very\nhelpful during this work!\n(I hope I didn’t forget anyone, I didn’t take an active role in this port and I might have missed someone if so please\naccept my apologies).\nThe whole source of this port as well as our changes to iKVM are available in our git repository.\nWhat does this Mean? As of May Windows 10 is installed on 300 million PC’s and devices making it a significant platform and appstore.\nMicrosoft has traditionally been quite strong in the enterprise and the ability to sell into that market thru it’s\nappstore (with the success of the Surface tablet line) is valuable.\nMicrosoft has standardized on the Universal Windows Platform which effectively \u0026ldquo;reinvents\u0026rdquo; Windows as\na single platform on all supported devices. In a way this is very much like Java’s Write Once Run Anywhere\nfor the Windows ecosystem (mobile, tablets, xbox, desktops etc.).\nWindows UWP apps can be sold thru the Microsoft appstore which is currently growing as users are still\nadopting Windows 10.\nBuilding an App You don’t need to make any change to your app to run it on a Windows 10 device/computer. Notice that you\nwill need a certificate file to ship such an app, we are still working on instructions to generate such a certificate\nin a simple way but you can configure a license file in the new Codename One settings UI under the\nWindows UWP settings.\n__ This is currently optional, you can send a build without configuring a certificate to test this on your local machine Figure 1. Open the new Codename One preferences options in the right click of the project\nFigure 2. Scroll down using swipe and click the UWP section\nFigure 3. You can now set a certficiate file and password for signing a universal app\nTo actually build the native app you can just right click and select the Windows UWP target, don’t be confused\nwith the two other options for desktop \u0026amp; the old Windows Phone support…​\nFigure 4. The new Windows UWP target\nInstalling the build on your machine requires Windows 10 (obviously) but also requires development mode indicating\nthat you can \u0026ldquo;sideload\u0026rdquo; applications. We need to writeup our own documentation on how to do this but\nfor now check out\nthis well written guide.\nOnce you do that your app can run on your machine and we should be able to submit such apps to the Windows\nstore:\nFigure 5. Hello world app running on a Windows 10 laptop\nWhat’s Next? The next set of steps depend on you. We will try to get apps into the Windows Store in order to complete the process\nbut we will consider this port production grade only when significant apps start shipping to the Windows Store.\nSo we need bug reports and demand from you in order to bring this to that coveted production grade status…​\nFuture of Windows Desktop Port You will also notice, UWP allows building Windows desktop apps which overlaps with the Windows Desktop\nbuild target that is currently limited to pro subscribers.\nThere is still some value in the Windows desktop build in the sense that it’s really a Java SE application with the\nfull power of the JRE behind it. If you need that and compatibility to older versions of Windows this can be quite\npowerful…​\nHowever, if you are interested in a smaller native binary and can live with Windows 10 or newer as the baseline\nI’d go for the new port as it should provide a superior native experience with a smaller footprint.\nFor now we will keep supporting the Windows desktop target and have no plans of removing/deprecating it.\nBuild Hints __ This section was added on June 14th and was missing from the original post…​ By default debug builds are sent for Windows UWP builds, those default to using x64 architecture only to keep\nthe size small. When you send release builds you will receive a proper universal binary.\nTo toggle these modes we added two build hints:\nuwp.buildType which can be either debug (the default) or release.\nuwp.platforms which defaults to x64 on debug builds but can be set to x64|x86|ARM for universal builds. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — June 12, 2016 at 9:26 pm (permalink) This sounds really good. I don’t have much to do with the Windows eco-system, so if I want to try this, I’m guessing any recent Windows mobile should run this, or is there some specific version (of the seemingly ever changing) Windows mobile platform I need to look for ?\nShai Almog — June 13, 2016 at 3:53 am (permalink) It requires a device that’s running windows 10 and some of the older devices won’t get that upgrade.\nChibuike Mba — June 13, 2016 at 7:40 am (permalink) WOW!!! CodenameOne rocks, one stone (code base) to kill(target) all the birds(platforms) in the air(out there). Am loving it. Will surely try it in the next version of our app http://ozioma.net. Great job guys. 🙂\nLukman Javalove Idealist Jaji — June 13, 2016 at 1:20 pm (permalink) I am over the moon with this!!!!!!!!!\nBen A — August 8, 2016 at 8:49 pm (permalink) Good news for Java devs\nTeguh Kusuma — September 5, 2016 at 4:24 pm (permalink) Teguh Kusuma says:\nIs it free for beginner developer?\nShai Almog — September 6, 2016 at 3:54 am (permalink) Shai Almog says:\nIt is available to all subscription levels including the free level.\nCristian Romascu — September 29, 2016 at 5:51 am (permalink) Cristian Romascu says:\nHello, i have 3 already made Java apps (using nothing but Java SE), can i convert them to UWP using Codename One?\nShai Almog — September 30, 2016 at 6:48 am (permalink) Shai Almog says:\nNo. Codename One supports a subset of Java SE and our own UI API which is more portable than anything available in JavaSE.\nOTOH you will gain for your effort the portability to iOS, Android, UWP, JavaScript (with threads etc.)\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/java-developers-can-finally-target-windows-uwp/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/java-developers-can-finally-target-windows-uwp/universal-windows-apps_thumb.jpg\"\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003eHistorical note:\u003c/strong\u003e Codename One\u0026rsquo;s UWP target was discontinued in release \u003cstrong\u003e7.0.229\u003c/strong\u003e. This post is preserved for historical context only, and its build/setup instructions no longer apply to current Codename One projects.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eAfter many months of work and effort put in by all of us but especially by \u003ca href=\"http://twitter.com/shannah78\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eSteve Hannah\u003c/a\u003e and\u003cbr\u003e\n\u003ca href=\"https://twitter.com/ravnos_kun\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFabrício Carvalho Cabeça\u003c/a\u003e we are finally live with the Windows Universal Platform (AKA UWP)\u003cbr\u003e\nnative build target!\u003cbr\u003e\nAs far as I know Codename One is the only native option for Java developers to build native Windows UWP apps.\u003c/p\u003e","title":"Java Developers can FINALLY Target Windows UWP"},{"content":"\nThis week has seen a lot of announcements and looking at the submission queue for next week it looks like\nit will be jam packed with updates and new features. Today we have a new plugin update which is jam packed\nwith features and changes, the biggest of which is the removal of all the skins (they are now in the More menu\nitem).\nWe also have a lot of great new features in this plugin including Windows UWP build preview, new settings UI \u0026amp;\nmuch more!\nWe’ll write more about all of those next week…​.\nStackoverflow was also brimming with great questions on a multitude of subjects.\nHow to enhance a class in Codename One API This is probably my favorite question of the week because it’s a tough question that is asked rather frequently.\nIn this case it was asked in a proactive way (how can I do that, rather than why don’t you guys do that…​) which\nis really nice making it my favorite.\nUnfortunately there are no easy answers!\nThere is a reason why we shy away from adding too many VM level API’s, it’s damn hard to do.\nRead on stackoverflow…​\nIs there a way to save a Graphics object in Codename One without without taking a screenshot? Graphics doesn’t always map to a surface which is why it doesn’t include capabilities such as getPixel.\nThis allows us to use rather elaborate hardware acceleration when running on some platforms and also\nuse two very different implementations of graphics (for screen drawing and mutable image drawing).\nRead on stackoverflow…​\nNeed to access native interface code (android paypal integration) Adding native 3rd party activities is a pretty common task for native SDK integrations…​\nRead on stackoverflow…​\nHow to add an unselectedTab icon in codename one? Reading that question I tend to agree, the API naming here is really unintuitive.\nRead on stackoverflow…​\nVideo Display in Codename One Most issues with web/video or other peer components boil down to wrong layout. Since the preferred size of the\nmedia is 0 when we initially lay out the form it’s sized as 0 and stays that way…​ Using a different layout manager\nworks around that.\nRead on stackoverflow…​\nLog into a NTLM server with CodeName One We got asked about NTLM support in the past but no one has emphasized this as important. It’s doable but\nchallenging, we could bake NTLM and other such capabilities directly into Codename One but to do that\nwe need to see enterprise customer demand.\nRead on stackoverflow…​\nHow do I specify a degree character (U+00B0) in a Label Our default encoding for source compilations was not UTF-8 for NetBeans/IntelliJ projects. We’ve changed this\nfor the upcoming update but this answer is still interesting…​.\nRead on stackoverflow…​\nHow should the result of getDeviceDensity() method from Codename One be used? Working with multi-DPI devices can be quite challenging and the device density aspect is often murky…​\nRead on stackoverflow…​\nIs it possible to save a generated image in Codename One? The answer is yes (thru ImageIO) but the question goes more into the details of how to create an image in\nterms of API’s…​\nRead on stackoverflow…​\nProvisioning profile does not match bundle identifier : Existing IOS bundle ID starts with a numeric When we implemented Codename One we decided to tie package names to provisioning on iOS/Android/Windows etc.\nThis simplified a lot of the underlying code and logic but introduced edge cases like this. Unfortunately, there\nare no easy answers for some problems…​\nRead on stackoverflow…​\nStore inherited class object in codename one storage Externalization has always been a challenging subject for developers, there are some common pitfalls\nthat people fall into but it’s often messy to discover them the first time around. Caching is probably one\nof the bigger pains during debugging as it defers the error to a later point…​\nRead on stackoverflow…​\nBest strategy for a magazine app It’s always difficult to give advice on strategy/design. We can’t debug design and some things become obvious\nonly after trying a design and discovering it’s flaws, that is why it is crucial to build applications that are robust\nenough to survive aggressive refactoring.\nRead on stackoverflow…​\nWhat would cause the \u0026ldquo;time\u0026rdquo; picker to display an hour that is different in the selector This question picked up a bug in Codename One with meridiem time. Notice it took 4 days for the asker to figure\nthis out…​\nIf the question had included a test case this might have been resolved sooner.\nRead on stackoverflow…​\nKeypad decreases the screen Height issue Centering elements in Codename One can be accomplished in several ways. I’m not a fan of the set paddings to\nposition elements approach though…​\nRead on stackoverflow…​\nDatabase replication best-practices in codenameone Storage is hard in mobile devices which has given rise to a cottage industry of on-device-databases.\nSome developers use sqlite but having used it for quite a few things I find it inherently quite flawed…​ We’d\nlove to have a better story for on device database that is ideally also more cross platform than our current options.\nRead on stackoverflow…​\nInstant messaging in coenameone We often have samples covering many different things, e.g. we have an actual IM app sample that answers\nthis question:\nRead on stackoverflow…​\nRestrict user to record video for 3 seconds only There are some things you can only do in native code at this time. Actually implementing a \u0026ldquo;proper\u0026rdquo; camera\nview for most OS’s should be pretty trivial with a native interface and peer components. However, it would\nrequire some understanding of the underlying OS semantics.\nRead on stackoverflow…​\nCreate a CN1 JSON Array from POJO for Jackson A lot of Codename One developers don’t even know about this great library from Steve, it’s pretty cool to see\ndevelopers finding out about it and figuring things for themselves!\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-ix/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-ix/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis week has seen a lot of announcements and looking at the submission queue for next week it looks like\u003cbr\u003e\nit will be jam packed with updates and new features. Today we have a new plugin update which is jam packed\u003cbr\u003e\nwith features and changes, the biggest of which is the removal of all the skins (they are now in the More menu\u003cbr\u003e\nitem).\u003c/p\u003e\n\u003cp\u003eWe also have a lot of great new features in this plugin including Windows UWP build preview, new settings UI \u0026amp;\u003cbr\u003e\nmuch more!\u003c/p\u003e","title":"Questions of the Week IX"},{"content":"\nWe announced our plans to migrate to the newest version of xcode\nrecently and so far these plans have gone rather well with most tests passing without a problem. We did decide\nto disable bitcode by default which means the new build hint ios.bitcode will now default to false to avoid issues\nwith some libraries that are still not up to date.\nOne point of confusion from that update was whether iphone_new should still be used. The answer is NO.\nYou should use the iphone build target as before and we will switch the servers seamlessly.\nWe will perform the migration to the new servers over the course of the next 2 months as we prepare for 3.5.\nSince 3.5 is slated for early August we’d like to have the new servers in place by then…​\nSwitch Transitory Period During the switch transitory period we will allow building to a special iphone_old target to workaround potential\nserver regressions. If you built to the iphone_new this is the same thing and you should skip ahead if not then\nread this for instructions on how to temporarily workaround regressions.\n__ | You MUST report all regressions to us at once!\nIf you don’t file issues we will not know a regression exists and might continue the migration plan assuming everything\nworks. Open the build.xml file \u0026amp; search for the string \u0026quot;iphone\u0026quot; with the quotes.\nReplace it with \u0026quot;iphone_old\u0026quot; .\nE.g. notice the targetType=\u0026quot;iphone_old\u0026quot; line below:\n\u0026lt;target name=\u0026quot;build-for-ios-device\u0026quot; depends=\u0026quot;clean,copy-ios-override,copy-libs,jar,clean-override\u0026quot;\u0026gt; \u0026lt;codeNameOne jarFile=\u0026quot;${dist.jar}\u0026quot; displayName=\u0026quot;${codename1.displayName}\u0026quot; packageName = \u0026quot;${codename1.packageName}\u0026quot; mainClassName = \u0026quot;${codename1.mainName}\u0026quot; version=\u0026quot;${codename1.version}\u0026quot; icon=\u0026quot;${codename1.icon}\u0026quot; vendor=\u0026quot;${codename1.vendor}\u0026quot; subtitle=\u0026quot;${codename1.secondaryTitle}\u0026quot; targetType=\u0026quot;iphone_old\u0026quot; certificate=\u0026quot;${codename1.ios.debug.certificate}\u0026quot; certPassword=\u0026quot;${codename1.ios.debug.certificatePassword}\u0026quot; provisioningProfile=\u0026quot;${codename1.ios.debug.provision}\u0026quot; appid=\u0026quot;${codename1.ios.appid}\u0026quot; /\u0026gt; \u0026lt;/target\u0026gt; Trial Switch On Sunday June 19th we will switch to the new build servers so all standard iphone builds will reach the new\nservers. We will also setup the old servers as iphone_old servers.\nOn that day some builds might get \u0026ldquo;lost\u0026rdquo; in the ether of migration so if a build gets stuck cancel it…​\nThis will be a trial run, if everything will \u0026ldquo;just work\u0026rdquo; which is a possibility (however unlikely) this will be it.\nHowever, if issues are reported we will probably revert back to the old servers.\nComplete Switch Assuming the trial teaches us about some issues we might do another trial but our final switch target date is\nJuly 3rd. Assuming things mostly work our correctly we aim to bring down some of our build server capacity for\nOS upgrade in preparation of the full switch.\nThis will mark the full switch to the new version of xcode.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/ios-migration-continued/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/ios-migration-continued/xcode-migration.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe announced our \u003ca href=\"/blog/ios-server-migration-plan.html\"\u003eplans to migrate to the newest version of xcode\u003c/a\u003e\u003cbr\u003e\nrecently and so far these plans have gone rather well with most tests passing without a problem. We did decide\u003cbr\u003e\nto disable bitcode by default which means the new build hint \u003ccode\u003eios.bitcode\u003c/code\u003e will now default to \u003ccode\u003efalse\u003c/code\u003e to avoid issues\u003cbr\u003e\nwith some libraries that are still not up to date.\u003c/p\u003e\n\u003cp\u003eOne point of confusion from that update was whether \u003ccode\u003eiphone_new\u003c/code\u003e should still be used. The answer is \u003cstrong\u003eNO\u003c/strong\u003e.\u003c/p\u003e","title":"iOS Migration Continued"},{"content":"\nManaging your project dependencies and 3rd party extensions among the hard to navigate list of cn1libs has\nalways been challenging. We are now tackling this problem in the new settings UI which is scheduled to launch\nfor all IDE’s this Friday.\nTo get started just open the new Codename One settings UI:\nFigure 1. Launching the new preferences UI\n__ You need to use an up to date plugin from the June 10th release Then open the extensions option:\nFigure 2. Extensions Option In the Settings\nOnce you launch the extensions UI you should see this screen where you can download/search thru available\nCodename One extensions.\nFigure 3. The Extensions UI\nOnce downloaded you will see a check mark next to the installed extensions.\nAdding your Own The list of extensions is based on a github project which\nyou can fork to extend. You can update the version of cn1libs you make and also contribute. Notice that while\nall the current libraries in the list are open source this is by no means a requirement…​\nWe have quite a few cn1libs already from the community and we’d appreciate more of those to help the community\nat large.\nWhat’s Next? We will probably refine this process as it matures e.g. add more tagging based UI and make an \u0026ldquo;uninstall\u0026rdquo;\nprocess as well…​\nHowever, this depends a lot on your involvement \u0026amp; feedback so let us know what you think and take part in the\nproject. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — June 8, 2016 at 2:50 pm (permalink) This sounds really cool! I’m definitely gonna try it out in the upcoming parse4cn1 update scheduled for later this month and give you feedback.\nBy the way, I have an interesting situation and I’d like to know how best to handle it. The current (and most likely upcoming) version(s) of parse4cn1 ships in two flavors: One with push notification support and one without, the reason being that push notification requires some native sdks which conflicted with those in CN1 causing build failures (e.g., Facebook SDK).\nHow best can I handle this? Make two separate CN1libs (e.g. Parse4CN1.Push and Parse4CN1.NoPush)? Ideas are most welcome.\nCan’t wait to try this out 🙂\nShai Almog — June 9, 2016 at 3:50 am (permalink) Thanks!\nWe wanted the current version to be as simple as possible and the only complexity we really tried to solve was relatively simple dependency management. So I don’t see another way other than the one you suggested.\nFYI parse4cn1 is already in the current repository (we added most of our existing cn1libs section). At the moment we didn’t take that strategy and it’s listed as the standard cn1lib.\nChidiebere Okwudire — June 9, 2016 at 7:47 am (permalink) Yeah, I already peeped at the git repo. The version number is also incorrect but that’s no problem. I’ll fix it within the coming update hopefully next week. At the time, I’ll also split it up\nShai Almog — June 9, 2016 at 8:05 am (permalink) Shai Almog says:\nNotice that this isn’t the \u0026ldquo;actual\u0026rdquo; version number. It’s the version in our repo which is an integer. We use this to determine if there is an update only and this isn’t displayed to the user… So the number is fine in that sense.\nChidiebere Okwudire — June 17, 2016 at 8:30 am (permalink) Chidiebere Okwudire says:\nGood point. By the way, do the IDEs automatically detect updates of the github repo is are the changes only available after the weekly cn1 updates?\nShai Almog — June 17, 2016 at 11:51 am (permalink) Shai Almog says:\nNeither. It’s a separate process where we manually deploy the changes to the codenameone.com website. We try to be quick about it but there is also caching from CDN and it’s a manual thing.\nThe logic is that we want the ability to migrate hosting. In the past we had an update center for NetBeans on Google code and it seems some people were still using it until now… In the future github might come down on partial binary hosting and we’d like such an eventuality to be seamless to our users.\nJérémy MARQUER — August 9, 2016 at 10:15 am (permalink) Jérémy MARQUER says:\nHey. I cannot access to the new Preferences UI of CN1 with eclipse. My cn1 plugin version is \u0026ldquo;1.0.0.201608062027\u0026rdquo;. Thanks.\nShai Almog — August 10, 2016 at 5:37 am (permalink) Shai Almog says:\nHi,\nis this on a Mac or a PC?\nAre you using JDK 8 to run Eclipse (you need to set it up in eclipse.ini)?\nJérémy MARQUER — August 10, 2016 at 7:09 am (permalink) Jérémy MARQUER says:\nOn a PC. Yes sure, I launch Eclipse with this flag\n\u0026ldquo;-vm\nC:/Program Files/Java/jre1.8.0_77/bin/javaw.exe\u0026rdquo;\nShai Almog — August 11, 2016 at 4:41 am (permalink) Shai Almog says:\nCheck that you have the GUIBuilder jar at c:myuserhomedir.codenameoneguibuilder_1.jar\nAssuming it’s there try running it from command line using java -jar c:myuserhomedir.codenameoneguibuilder_1.jar -settings path_to_projectcodenameone_settings.proper… are there any errors printed to the console?\nJérémy MARQUER — August 11, 2016 at 7:12 am (permalink) Jérémy MARQUER says:\nAs I expected, I obtain the old settings UI (not the latest I think) …\n(and no errors printed)\nShai Almog — August 12, 2016 at 4:16 am (permalink) Shai Almog says:\nThat’s a problem. We’ll look into it.\nJérémy MARQUER — August 17, 2016 at 4:31 pm (permalink) Jérémy MARQUER says:\nIt’s ok, thanks.\nJulien Sosin — December 5, 2017 at 3:24 pm (permalink) Julien Sosin says:\nHi !\nHow can I delete a lib ? I tried CodeScanner but it looks deprecated and I can’t build iOS app anymore :/\nShai Almog — December 6, 2017 at 9:11 am (permalink) Shai Almog says:\nHi,\nthere is currently no standard uninstaller but it shouldn’t be too hard. See the instructions I posted here: https://stackoverflow.com/a…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/automatically-install-update-distribute-cn1libs-extensions/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/automatically-install-update-distribute-cn1libs-extensions/extensions.png\"\u003e\u003c/p\u003e\n\u003cp\u003eManaging your project dependencies and 3rd party extensions among the hard to navigate list of cn1libs has\u003cbr\u003e\nalways been challenging. We are now tackling this problem in the new settings UI which is scheduled to launch\u003cbr\u003e\nfor all IDE’s this Friday.\u003c/p\u003e\n\u003cp\u003eTo get started just open the new Codename One settings UI:\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Launching the new preferences UI\" loading=\"lazy\" src=\"/blog/automatically-install-update-distribute-cn1libs-extensions/newsettings-ui.png\"\u003e\u003c/p\u003e\n\u003cp\u003eFigure 1. Launching the new preferences UI\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eYou need to use an up to date plugin from the June 10th release\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eThen open the extensions option:\u003c/p\u003e","title":"Automatically Install, Update \u0026 Distribute cn1libs (extensions)"},{"content":"\nDr. Sbaitso is one of our newer demos. We wrote it for a workshop at JavaZone a couple of years ago and it\nproved to be an excellent tutorial on many complex abilities of Codename One. It captures images from the\ncamera, rounds them, does dynamic search with a chat like bubble interface…​\nCheck the live version running on the right hand side thanks to the power of the Codename One JavaScript port!\nBut the coolest part is the speech synthesis…​\nIt uses native interfaces to access the text-to-speech capabilities of the device and \u0026ldquo;says\u0026rdquo; what the \u0026ldquo;doctor\u0026rdquo; is\nsaying. This both demonstrates native access and the rather cool TTS functionality.\nWhat’s to Improve? The demo is already so good and relatively terse, there isn’t much to improve about it.\nWe naturally updated it to Java 8 and the newer terse syntax which cleaned up a bit of the UI. We also replaced\nthe next command with an arrow material design icon which is more attractive…​\nBut the coolest change is that we added native interface support for JavaScript so Dr. Sbaitso now speaks in\nthe Chrome browser!\nThis works really well and runs very smoothly on my desktop, it’s not ideal because speech synthesis isn’t\nwidely supported by browsers and I wasn’t able to get it to work on firefox or any other browser. But it’s still\nremarkably cool.\n__ This pretty much shows off the benefit of having a native framework vs. the pain of web fragmentation…​ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nRoss Taylor — June 16, 2016 at 7:44 pm (permalink) Ross Taylor says:\nHi Shai, would it be possible to create text input that allows for paragraph to be created and emojis to be inserted? Also allow to create a bubble to format text appropriately when needed like bullet points (if pasted from a document that does have them), telephone numbers (tapping on numbers to trigger events like calling or saving to address book) , URL links (underline them and when tapped to open web browser), i.a.w, pretty much like the way bubbles displays the text richly like existing IMs you get now?\nShai Almog — June 17, 2016 at 3:44 am (permalink) Shai Almog says:\nHi,\nYou can insert emojiis on the device today and it should work fine for this and other apps.\nHowever, what you are talking about is called a \u0026ldquo;rich edit component\u0026rdquo; we have a cn1lib that supports that somewhere (Steve did it) thru a web browser UI. The problem is that Android and iOS have rather bad support for that concept and it’s rather different between the OS’s.\nIt’s something we wanted to integrate a while back but we didn’t have any actionable user demand which is really needed for such a problematic task.\nssybesma — December 30, 2016 at 3:43 am (permalink) ssybesma says:\nYou have to be kidding…all it does is ask you questions about what you just said. Dr. Sbaitso actually is intelligent compared to this. He does more than just that.\nShai Almog — December 30, 2016 at 5:20 am (permalink) Shai Almog says:\n🙂\nThat’s the nature of demos. I totally meant to write a decent AI chat and instead focused on the other features. By the time I was done I couldn’t justify writing more code for something that’s meant to teach UI programming and native interfaces…\nFeel free to submit a pull request though, all the logic is in AI.java so it should be pretty easy.\nssybesma — December 30, 2016 at 6:03 am (permalink) ssybesma says:\nI appreciate that you were not offended and I apologize for being a bit harsh. I do look forward to the eventual release of an application that does Dr. Sbaitso one better. The voice has to be the same, though…sorry. I’m sentimental.\nShai Almog — December 31, 2016 at 12:16 pm (permalink) Shai Almog says:\nIf I’d spend time on this I’d work on the AI but I doubt I’ll get any time to work on that. When I initially presented the demo no one knew about the original so the points were a bit lost on them… Plus it made me feel old 😉\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/dr-sbaitso-revisited/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/dr-sbaitso-revisited/drsbaitso.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eDr. Sbaitso is one of our newer demos. We wrote it for a workshop at JavaZone a couple of years ago and it\u003cbr\u003e\nproved to be an excellent tutorial on many complex abilities of Codename One. It captures images from the\u003cbr\u003e\ncamera, rounds them, does dynamic search with a chat like bubble interface…​\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eCheck the live version running on the right hand side thanks to the power of the Codename One JavaScript port!\u003c/strong\u003e\u003c/p\u003e","title":"Dr. Sbaitso Revisited"},{"content":" Corporate Server On-site installation of the Codename One cloud for large corporate/government entities.\nHome Corporate Server Important: After much deliberation with corporate customers we are discontinuing the corporate server in favor of a more dynamic option for offline build. If you require offline builds please use the contact us form to contact sales and we will follow up with details on our upcoming offering.\nWe intend to launch a beta preview of this new offering in Q4 2016 for early adopters.\nA corporate sever allows companies to install a private Codename One build cloud within their company, this means that Codename One builds will be performed on the local network and not in the cloud. The corporate server is completely isolated and never contacts Codename One, the same is true for applications created by the corporate server which now rely on it to perform push and other tasks. The Codename One build server requires a complex installation involving a minimum of 4 machines that can\u0026rsquo;t be fully virtualized, it is a task for a trained system administrator. To get a sense of the complexity involved see the corporate server install guide here:\nDownload Install GuidePDF instructions for installing the corporate server\nSince the server is hosted within the organization Codename One places no limitations on the number of developers using the server, however Codename One developer support must be purchased separately since there is no way for Codename One to properly price support incidents for such cases.\nIf you are interested in purchasing a cloud server please contact us using the form below, payment for the corporate server is performed via SWIFT transfer. Pricing is comprised of the following pieces:\nBase Corporate Server Cost Build cloud server software Partial cloud services software (see details below) Installation support (doesn\u0026rsquo;t include individual developer support) Single company location install (can be used by multiple teams within the company) Starts at\n$19,900annually\nDeveloper Support Seat E-mail support Office Hours - Phone support Access to cloud servers at enterprise grade if applicable Issue escalation \u0026amp; feature requests Per developer\n$2,790annually\nOptional\nEnterprise vs. Corporate Server The two products are very different from one another. Enterprise subscription still uses the Codename One build cloud and is a managed SaaS solution whereas the corporate server is a traditional offline software installation that uses an internal cloud.\nIf you have the ability, we recommend that you go with the enterprise license which is both cheaper, more flexible and easier to work with by a very large margin. However, if you are in a highly regulated/restricted field that doesn\u0026rsquo;t allow for such a product you need to be aware of the differences between enterprise and corporate servers. Some features were removed from the corporate server to make the offline install simpler. See the table below:\nEnterprise Corporate On-Site Private Cloud Cloud Storage Versioning Live Preview Please Fill Out This Form for our sales team Given Name\nSurname\nCompany\nE-mail:\nPhone\nMessage\nSend\n","permalink":"https://www.codenameone.com/corporate-server/","summary":"\u003c!-- raw HTML omitted --\u003e\n\u003ch1 id=\"corporate-server\"\u003eCorporate Server\u003c/h1\u003e\n\u003cp\u003eOn-site installation of the Codename One cloud for large corporate/government entities.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eCorporate Server\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eImportant:\u003c/strong\u003e After much deliberation with corporate customers we are discontinuing the corporate server in favor of a more dynamic option for offline build. If you require offline builds please use the \u003ca href=\"/contact-us.html\"\u003econtact us\u003c/a\u003e form to contact sales and we will follow up with details on our upcoming offering.\u003cbr\u003e\nWe intend to launch a beta preview of this new offering in Q4 2016 for early adopters.\u003c/p\u003e","title":"Corporate Server"},{"content":"\nWith the upcoming library update this weekend we will remove the venerable (old) skins that are baked into the\nsimulator. This means that they will no longer be immediately accessible but you can still download all of them\nthru the Skins → More menu option.\nThe chief motivations for this are to keep the distribution smaller (our plugin just crossed the 100MB mark which\nisn’t great) \u0026amp; to keep the skins up to date. Some of the newer skins (e.g. iPad pro) are HUGE and bundling them\nis impractical.\nThis means that if you use a different simulator of the builtin ones it will flip to the iPhone 3gs simulator which is\nthe only one we will ship by default. To fix this just select the More option and download any skin you like.\nWorking Behind a Proxy In this weeks library update we released an important feature: Proxy support.\nPreviously setting up a proxy required doing this globally in the Java settings which are somewhat hidden. This\nnew UI allows you to determine a custom setting for Codename One and also allows you to pick the system\nproxy which is what most of us would expect to be the default.\nThis is all part of the work done on issue 1740 and\nshould apply to apps built with Codename One seamlessly.\nStarting with the next plugin update the setting for the proxy picked in the simulator will also apply to builds sent\nto the cloud servers so this is will allow you to avoid previous hacks such as editing the build.xml to add proxy\nsettings.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/unskin-proxy-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/unskin-proxy-support/proxy-settings.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWith the upcoming library update this weekend we will remove the venerable (old) skins that are baked into the\u003cbr\u003e\nsimulator. This means that they will no longer be immediately accessible but you can still download all of them\u003cbr\u003e\nthru the Skins → More menu option.\u003c/p\u003e\n\u003cp\u003eThe chief motivations for this are to keep the distribution smaller (our plugin just crossed the 100MB mark which\u003cbr\u003e\nisn’t great) \u0026amp; to keep the skins up to date. Some of the newer skins (e.g. iPad pro) are HUGE and bundling them\u003cbr\u003e\nis impractical.\u003c/p\u003e","title":"Unskin \u0026 Proxy Support"},{"content":"\nThe corporate server offering has always been controversial and problematic both within Codename One \u0026amp;\nfor the customers who bought that service. We struggled a lot with trying to get it just right but with every installation\nwe ran into a painful reminder of exactly why we chose to use the cloud. After discussing this with our existing\ncorporate customers we came to the conclusion that we need something better that would still address the\nrequirement of offline building.\nWe have something in the works based on the feedback from these customers and we intend to roll it out\nat the 3.6 timeline (end of year, note that these are tentative plans…​). If you are currently evaluating Codename One\nand are interested in the ability to build offline then please use the contact us section\nto discuss your interest with our sales dept.\n__ | We already discussed this extensively with all existing corporate customers, this post is strictly for people evaluating Codename One\nand the corporate server! Since the upcoming replacement isn’t finished we can’t really discuss tentative plans but we will discuss planned\nfeatures/requirements in some cases to make sure that our upcoming plans align with corporate requirements.\nCurrently the replacement for the corporate server is scheduled as a private beta on Q4 2016 so we are looking\nfor interested parties to try it out/provide feedback.\nDiscontinuing the Old Push Servers We plan to retire the old push servers currently using the appspot URL. We reviewed the list of developers still\nusing it and from conversations with most of them 3 months should be enough time to completely phase\nout the old servers.\nMost developers have migrated to the new push servers which as of now are our only supported option. Even\nmost of those still using the old servers are mostly using them for legacy installs…​\nPlease try to migrate away within the next 3 months. At that time we will evaluate the traffic to these servers\nand decide whether to take these servers offline.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/discontinuing-the-corporate-server-old-push-server/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/discontinuing-the-corporate-server-old-push-server/push-megaphone.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe corporate server offering has always been controversial and problematic both within Codename One \u0026amp;\u003cbr\u003e\nfor the customers who bought that service. We struggled a lot with trying to get it just right but with every installation\u003cbr\u003e\nwe ran into a painful reminder of exactly why we chose to use the cloud. After discussing this with our existing\u003cbr\u003e\ncorporate customers we came to the conclusion that we need something better that would still address the\u003cbr\u003e\nrequirement of offline building.\u003c/p\u003e","title":"Discontinuing the Corporate Server \u0026 Old Push Servers"},{"content":"\nIt’s been a remarkably busy week with so many big announcements and it’s shaping up to be a very busy\nmonth…​ We wanted to release a new plugin update this week but due to some external pressure we will\nupdate the plugin next week and keep this Friday update only to the libraries.\nOn stackoverflow there were quite a lot of questions:\nIs there a way in which one can read data stored in a file with extension of .sql Shipping an app with a default \u0026ldquo;starter\u0026rdquo; sql database is pretty common and still pretty confusing.\nRead on stackoverflow…​\nHow to migrate my \u0026ldquo;Codenameone\u0026rdquo; Project from (java 5) to (Java 8) This is a pretty common FAQ about the move to Java 8, we should blog about it more as clearly this isn’t clear\nenough…​\nRead on stackoverflow…​\nWhy is the JSONParser always returning a double? One painful ommission from the API subset supported by Codename One is the Number class. We’d really like\nto fix that ommission soon.\nRead on stackoverflow…​\nWhy won’t my MenuBar show? As a product that evolved over time the \u0026ldquo;right way\u0026rdquo; to do things has changed drastically over the years and sometimes\nthe legacy support is hard to distinguish. In this case legacy doesn’t really warrant the overly harsh deprecation\nbut confuses developers still…​\nRead on stackoverflow…​\nRight side menu shadow is flipped This was a regression we introduced with this weeks release, it should be fixed by the time you read this…​\nRead on stackoverflow…​\nCodename1 Android not building on 3.4 Some issues with Android builds and google play are just painful, we addressed most of those problems but sometimes\nwalking thru the maze of build hints is non-trivial.\nRead on stackoverflow…​\nNeed examples headers and cookies Working with cookies in Codename One is something that is quite missing from the documentation, we should\nbolster that at least by asking questions…​.\nRead on stackoverflow…​\nBrowserComponent / WebBrowser doesn’t close when back is pressed When you use the andWait version of methods sometimes weird things happen because the rest of the execution\nchain doesn’t go thru. You should use these methods but be prudent about it…​\nRead on stackoverflow…​\nCodeName One error: cannot find symbol You can’t change the class/package name after creation easily. You need to change it everywhere within the\nproperties files and the project. It’s non-trivial.\nRead on stackoverflow…​\nLibrary update broke textboxes This was already fixed by the time the question was asked. FYI you can see commit history in the github project\nand you can subscribe to notification as explained in\nthis post.\nRead on stackoverflow…​\nCodename one missing from NetBeans plugins on Ubuntu Turns out OpenJDK is quite problematic with NetBeans plugins and various other tools including Codename One.\nRead on stackoverflow…​\nSetting image as background is not working Labels/Buttons hide themselves when they are blank. This is often confusing to developers but is quite useful\nfor many cases…​\nRead on stackoverflow…​\nBlack content pane instead of tiled background If you ask a question that has a visual aspect a screenshot always goes a long way to help with the answer.\nRead on stackoverflow…​\nSome questioning about codenameone This question is already marked for deletion by moderators so it might not be there by the time you see this…​\nGenerally product opinion questions are frowned upon in stack overflow as they tend to promote religious debate.\nRead on stackoverflow…​\nWriting a string at a given position in a drawing The position of a drawing are slightly different from the Swing/AWT convention. This is a common\npitfall for developers.\nYou should also keep in mind that component size can always change (and frequently does)…​\nRead on stackoverflow…​\nStyling the side Menu The sidemenu is quite customizable in the Toolbar API. We lost some of the customization abilities we had in the\nold SideMenuBar but we gained a lot of simplicity and usability in return…​\nRead on stackoverflow…​\nInfiniteProgress component issue in postForm() Handling progress while doing something else usually falls flat with people abusing the EDT or failing to account\nfor the fact that things are still happening in the background…​\nRead on stackoverflow…​\nChange app language in emulator We should probably add deeper configuration for this as we move forward but right now you can hack a lot\nof things relatively easily by just manipulating the VM arguments for the simulator…​\nRead on stackoverflow…​\nZipme implementation The newly announced ZipSupport cn1lib already has some\ninterest. We didn’t get a chance to document it as it was pretty much a quick port. Since it’s so similar to the\nJavaSE version of zip support it should be pretty easy to use.\nRead on stackoverflow…​\nThe app needs to be configured to android Tablets only from Google play store We have a combo box to configure this for iOS builds but Google made this a bit more \u0026ldquo;interesting\u0026rdquo; and\nthe definition of what is a tablet on the play store is also pretty challenging…​\nRead on stackoverflow…​\nShow image only on specific device Different UI’s for tablets/phones is a pretty common question.\nRead on stackoverflow…​\nios.googleAdUnitId bottom banner doesn’t show on iPhone 6 and 6+ in landscape mode Most developers don’t use banner ads anymore as they provide very poor returns so we just don’t get that many\nbug reports on our banner ad support. This issue is probably related to the version of Google play services we\nuse in the iOS builds. Thanks to the latest cocoapods support we might be able to solve this effectively.\nRead on stackoverflow…​\nRe fade animation not working properly This has been an ongoing question that we’re trying to track down unsuccessfully. Unfortunately narrowing this\ndown to see the problem whether in the code or in Codename One requires something more terse.\nRead on stackoverflow…​\nWhy can’t I select the first item in the side menu? If the top most item is very small and near the area of the status bar of the phone it will be impossible to touch it\nas the native OS will mistake your taps for attempts to touch the status bar area. The solution is not to place\nelements that high and style things to have enough space for touch.\nRead on stackoverflow…​\nWhy are my menu items too small or too big? When using the native theme it’s important to make sure that elements are styled correctly. The native theme\ndoesn’t always override elements such as SideComponent etc. out of the assumptions that these will always be\nstyled by the user.\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-viii/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-viii/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIt’s been a remarkably busy week with so many big announcements and it’s shaping up to be a very busy\u003cbr\u003e\nmonth…​ We wanted to release a new plugin update this week but due to some external pressure we will\u003cbr\u003e\nupdate the plugin next week and keep this Friday update only to the libraries.\u003c/p\u003e\n\u003cp\u003eOn stackoverflow there were quite a lot of questions:\u003c/p\u003e\n\u003ch3 id=\"is-there-a-way-in-which-one-can-read-data-stored-in-a-file-with-extension-of-sql\"\u003eIs there a way in which one can read data stored in a file with extension of .sql\u003c/h3\u003e\n\u003cp\u003eShipping an app with a default \u0026ldquo;starter\u0026rdquo; sql database is pretty common and still pretty confusing.\u003c/p\u003e","title":"Questions of the Week VIII"},{"content":"\nWhile the Codename One skin file format is trivial it is a bit under documented, to partially alleviate this problem\nwe created a simple tool: Skin Designer.\nThis tool allows us to create a device skin from two images (landscape \u0026amp; portrait). This skin file can then\nbe used with the Codename One simulator \u0026amp; also contributed so other developers can enjoy it!\nThe first version of this tool is relatively simple but should allow you to create an contribute skins to our skin\ndatabase as explained below.\nUsing the Skin Designer The Skin Designer is a Codename One app that you can\ncheckout from github. You can also\nrun it directly in the web browser or install it locally on your Mac or Windows desktop from its demos page.\n__ You can also run it on your mobile devices but it might not be as convenient The main value of building this app in Codename One is the ability to run it in the web and the desktop unmodified.\nIt also serves as an excellent reference sample for developers.\nHow to Use it? The skin designer tool allows you to visually design and save a Codename One skin file that you can\nuse to simulate a custom device type. To use this tool you need two pictures of the device in portrait\nand landscape mode. The screen area of these pictures must match the device screen size!\n__ | To find files like that just search for the name of the device you are looking for followed by \u0026ldquo;mockup\u0026rdquo;.\nThis will bring up device mockups you can often use. FYI be sure to read the license of the graphic you use\nif you intend to publish this, many creators require attribution! Creating a Skin You will need to select the device image in portrait/landscape, you can then enter the screen dimensions\nin pixels that should match the area within the graphic.\nYou can enter the X/Y position or use the hand \u0026ldquo;pan tool\u0026rdquo; to visually position the screen within the graphic.\nCheck out the help page within the application for detailed explanation of the skin creation process.\nSubmitting the Skin Assuming your skin file doesn’t violate any copyrights we’d appreciate if you submit it to our official skin repository!\nIf your skin file requires attribution please include that within the skin image…​\nStart by navigating to github.com/codenameone/codenameone-skins\n\u0026amp; fork the project. Drag your skin file into the OTA directory. Create a 112x112 icon png file for the skin\nand drag it into that directory as well.\nNext select the Skins.xml file and edit it. Add your skin in a similar way to the other skin files and commit.\nNow click the submit pull request button to submit these changes for inclusion in the main repository.\na bug fix in the simulator __ | Skins created with the web interface will only start working with the upcoming Friday release as they require Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nGareth Murfin — February 5, 2018 at 10:18 am (permalink) Gareth Murfin says:\nIs there a way to change default zoom some how? I just want to use a good modern skin without having to resize everytime.\nShai Almog — February 6, 2018 at 7:16 am (permalink) Shai Almog says:\nHaven’t played with it for a while so I’m not sure. Do you see an exception? Notice you can just debug this as it’s a regular cn1 project. FYI next week we’ll be pushing out an update to the simulator and at that point we’ll add a lot of new skins e.g. Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/skin-designer/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/skin-designer/skindesigner.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWhile the Codename One skin file format is trivial it is a bit under documented, to partially alleviate this problem\u003cbr\u003e\nwe created a simple tool: \u003ca href=\"/demos/SkinDesigner/\"\u003eSkin Designer\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eThis tool allows us to create a device skin from two images (landscape \u0026amp; portrait). This skin file can then\u003cbr\u003e\nbe used with the Codename One simulator \u0026amp; also contributed so other developers can enjoy it!\u003c/p\u003e\n\u003cp\u003eThe first version of this tool is relatively simple but should allow you to create an contribute skins to our skin\u003cbr\u003e\ndatabase as explained below.\u003c/p\u003e","title":"Skin Designer"},{"content":"\nOne of my pet peeves when we switched to github was that email notifications never worked for me. For most\nrepositories I had to setup my own account just to get emails. I’m guessing that this is a common problem for\nthose of us who are used to emails notifying us of changes.\nSo we went over all the repositories at github.com/codenameone and made\nthem all send an email to the codenameone-commits google group.\nSo you can now subscribe to email notifications from this group\nand you will get an email every time one of us commits something to the repositories of Codename One!\nYou will notice that the group has some commits from 2012…​\nThis is actually an old group that was used for commit notification a while back and eventually got deprecated\nas it wasn’t necessary for google code. There was really no point in creating a new group as this one worked fine.\n__ | If you see an issue in a commit please don’t post to that group as we’d like to keep it completely based on\nthe automated emails ConnectionRequest Duplicates ConnectionRequest\nhad special protection from duplicate requests for the same data. This was added to prevent cases\nsuch as multiple image downloaders fetching the same image over and over again.\nThe mistake was that we set the duplicate detection mode to be on by default which made some networking\nissues really hard to track down consistently. We decided to flip the switch setDuplicateSupported(true) will no\nlonger be required as it will be the default.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/keep-track-of-codename-one-changes-duplicates/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/keep-track-of-codename-one-changes-duplicates/how-to-use-the-codename-one-sources.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of my pet peeves when we switched to github was that email notifications never worked for me. For most\u003cbr\u003e\nrepositories I had to setup my own account just to get emails. I’m guessing that this is a common problem for\u003cbr\u003e\nthose of us who are used to emails notifying us of changes.\u003c/p\u003e\n\u003cp\u003eSo we went over all the repositories at \u003ca href=\"http://github.com/codenameone\" target=\"_blank\" rel=\"noopener noreferrer\"\u003egithub.com/codenameone\u003c/a\u003e and made\u003cbr\u003e\nthem all send an email to the \u003ca href=\"https://groups.google.com/forum/#!forum/codenameone-commits\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ecodenameone-commits google group\u003c/a\u003e.\u003c/p\u003e","title":"Keep Track of Codename One Changes \u0026 Duplicates"},{"content":"\nDebugging Codename One apps on iOS devices has been documented well with a video for years, we didn’t\nspend too much time outlining the Android counterpart mostly because we didn’t really use it as much and it\nwas far simpler.\nAs Android Studio launched this actually became really easy as it was possible to actually open the gradle project\nin Android Studio and just run it. But due to the fragile nature of the gradle project this stopped working for our recent\nbuilds, this works for some cases but is a bit of a flaky touch \u0026amp; go.\n__ | If\nthese instructions\nwork for you then you can ignore the video/instructions below. However, if they don’t then keep reading Google has the tendency to change things frequently which makes documenting a process to work\nwith Android much harder than the iOS equivalent.\nThe method outlined in the \u0026ldquo;how do i\u0026rdquo; video that we just launched\nshould work regardless of future changes. It might not be the best way to do this but it’s simple and it works.\nHere are the steps highlighted in the video:\nCheck the include source flag in the IDE and send a build\nDownload the sources.zip result from the build server\nLaunch Android Studio and create a new project\nMake sure to use the same package and app name as you did in the Codename One project, select to not create an activity\nUnzip the sources.zip file and copy the main directory from its src directory to the Android Studio projects src directory\nmake sure to overwrite files/directories.\nCopy its libs directory on top of the existing libs\nCopy the source gradle files dependencies content to the destination gradle file\nConnect your device and press the Debug button for the IDE\n__ You might need to copy additional gradle file meta-data such as multi-dexing etc. You might not need to repeat the whole thing with every build. E.g. it might be practical to only copy the userSources.jar\nfrom the libs directory to get the latest version of your code.and you can copy the src/main directory to get our\nup to date port.\nRefinement There are many edge cases and hints that probably don’t fit into this process, let us know in the comments below\nabout the difficulties and success you’ve had with this process and also provide tips about simpler hacks to\nbuild the code for device.\nThere is a portion we didn’t get into with the video, copying updated sources directly without sending a build.\nThis is possible if you turn on the new Android Java 8 support. At this point you should be able to remove the libs\njar file which contains your compiled data and place your source code directly into the native project for debugging\non the device. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nNilmar Castro — December 28, 2016 at 12:58 pm (permalink) Nilmar Castro says:\nHello Shai,\nI’m starting at codenameone. I am not fluent in English but I understand very well the majority of the tutorials that are presented. However in this specifically the presenter speaks very fast and it is not possible for me to understand as necessary.\nIs there any other?\nThank you very much\nShai Almog — December 29, 2016 at 5:41 am (permalink) Shai Almog says:\nHi,\nI prefer her voice to mine (I narrated the old videos) but thanks 😉\nIn the newer videos we have subtitles that contain the full text that you can read in the youtube page. You can also see the full transcript of every one of the new videos in their \u0026ldquo;How Do I?\u0026rdquo; page.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/debug-a-codename-one-app-on-an-android-device/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/debug-a-codename-one-app-on-an-android-device/mqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eDebugging Codename One apps on iOS devices has been documented well with a video for years, we didn’t\u003cbr\u003e\nspend too much time outlining the Android counterpart mostly because we didn’t really use it as much and it\u003cbr\u003e\nwas far simpler.\u003c/p\u003e\n\u003cp\u003eAs Android Studio launched this actually became really easy as it was possible to actually open the gradle project\u003cbr\u003e\nin Android Studio and just run it. But due to the fragile nature of the gradle project this stopped working for our recent\u003cbr\u003e\nbuilds, this works for some cases but is a bit of a flaky touch \u0026amp; go.\u003c/p\u003e","title":"Debug a Codename One app on an Android Device"},{"content":"\nBluetooth is one of those specs that makes me take a step back…​ It’s nuanced, complex and multi-layered.\nThat isn’t necessarily bad, it solves a remarkably hard problem. Unfortunately when people say the words \u0026ldquo;bluetooth\nsupport\u0026rdquo; it’s rare to find two people who actually mean the same thing!\nSo while we did have a lot of requests for bluetooth support over the years most of them were too vague and when\nwe tried to follow thru we usually reached a dead end where the customers themselves often didn’t really know\nthe part of the spec they wanted.\nNormally when something is so huge and vague we try to look at what the native OS’s did, but iOS and Android took\nvery different routes to bluetooth.\nAnother approach is to look at what other companies in the field did to support bluetooth and historically there\nwasn’t much. Most \u0026ldquo;Write Once Run Anywhere\u0026rdquo; solutions just ignored that feature.\nHowever, recently we became aware of this bluetooth plugin for Cordova\nwhich Chen and Steve adapted to a Codename One cn1lib here.\nCheck it out and let us know what you think…​ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nNick Koirala — June 2, 2016 at 2:55 am (permalink) Nick Koirala says:\nNice, just built the demo and found it picking things up. Can it scan in the background and call back to the app? I.e., for discovering beacons.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/bluetooth-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/bluetooth-support/bluetooth.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eBluetooth is one of those specs that makes me take a step back…​ It’s nuanced, complex and multi-layered.\u003cbr\u003e\nThat isn’t necessarily bad, it solves a remarkably hard problem. Unfortunately when people say the words \u0026ldquo;bluetooth\u003cbr\u003e\nsupport\u0026rdquo; it’s rare to find two people who actually mean the same thing!\u003c/p\u003e\n\u003cp\u003eSo while we did have a lot of requests for bluetooth support over the years most of them were too vague and when\u003cbr\u003e\nwe tried to follow thru we usually reached a dead end where the customers themselves often didn’t really know\u003cbr\u003e\nthe part of the spec they wanted.\u003c/p\u003e","title":"Bluetooth Support"},{"content":"\nEditor note: CocoaPods remains supported, but current iOS dependency guidance now also covers Swift Package Manager (SPM) and mixed CocoaPods/SPM setups. See the current \u0026ldquo;Working with iOS\u0026rdquo; section in the developer guide.\nCocoaPods is a dependency manager for Swift and Objective-C Cocoa projects.\nIt has over eighteen thousand libraries and can help you scale your projects elegantly. Cocoapods can be\nused in your Codename One project to include native iOS libraries without having to go through the hassle\nof bundling the actual library into your project. Rather than bundling .h and .a files in your ios/native directory,\nyou can specify which \u0026ldquo;pods\u0026rdquo; your app uses via the ios.pods build hint. (There are other build hints also\nif you need more advanced features).\nE.g.:\nTo include the AFNetworking library in your app use the build\nhint:\nios.pods=AFNetworking To include the AFNetworking version 3.0.x library in your app use\nthe build hint:\nios.pods=AFNetworking ~\u0026gt; 3.0 For full versioning syntax specifying pods see the\nPodfile spec for the \u0026ldquo;pod\u0026rdquo; directive.\nIncluding Multiple Pods Multiple pods can be separated by either commas or semi-colons in the value of the ios.pods build hint.\nE.g. To include GoogleMaps and AFNetworking, you could:\nios.pods=GoogleMaps,AFNetworking Or specifying versions:\nios.pods=AFNetworking ~\u0026gt; 3.0,GoogleMaps Other Pod Related Build Hints ios.pods.platform : The minimum platform to target. In some cases, Cocoapods require functionality that is\nnot in older version of iOS. For example, the GoogleMaps pod requires iOS 7.0 or higher, so you would need to\nadd the ios.pods.platform=7.0 build hint.\nios.pods.sources : Some pods require that you specify a URL for the source of the pod spec. This may be\noptional if the spec is hosted in the central CocoaPods source (\u0026lt;https://github.com/CocoaPods/Specs.git\u0026gt;).\nConverting PodFile To Build Hints Most documentation for Cocoapods \u0026ldquo;pods\u0026rdquo; provide instructions on what you need to add to your Xcode\nproject’s PodFile. Here is an example from the GoogleMaps cocoapod to show you how a PodFile can be\nconverted into equivalent build hints in a Codename One project.\nThe GoogleMaps cocoapod directs you to add the following to your PodFile:\nsource 'https://github.com/CocoaPods/Specs.git' platform :ios, '7.0' pod 'GoogleMaps' This would translate to the following build hints in your Codename One project:\nios.pods.sources=https://github.com/CocoaPods/Specs.git ios.pods.platform=7.0 ios.pods=GoogleMaps __ Note that the ios.pods.sources directive is optional Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — January 24, 2017 at 2:14 am (permalink) Chidiebere Okwudire says:\nThis is really great! It’s made integrating the Parse iOS SDK much simpler. Thanks!!\n3lix — February 13, 2017 at 3:55 pm (permalink) 3lix says:\nWould these pods work on all three platforms (iOS, Android and Windows) or are these iOS specific?\nShai Almog — February 14, 2017 at 8:02 am (permalink) Shai Almog says:\nNo it’s designed for iOS native code.\nFrancesco Galgani — October 17, 2018 at 9:40 pm (permalink) Francesco Galgani says:\nIs there anything similar for Android?\nShai Almog — October 18, 2018 at 4:04 am (permalink) Shai Almog says:\nSure, Gradle: https://www.codenameone.com…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/cocoapods/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/cocoapods/cocoapods.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cem\u003eEditor note: CocoaPods remains supported, but current iOS dependency guidance now also covers Swift Package Manager (SPM) and mixed CocoaPods/SPM setups. See the current \u0026ldquo;Working with iOS\u0026rdquo; section in the developer guide.\u003c/em\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://cocoapods.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCocoaPods\u003c/a\u003e is a dependency manager for Swift and Objective-C Cocoa projects.\u003cbr\u003e\nIt has over eighteen thousand libraries and can help you scale your projects elegantly. Cocoapods can be\u003cbr\u003e\nused in your Codename One project to include native iOS libraries without having to go through the hassle\u003cbr\u003e\nof bundling the actual library into your project. Rather than bundling .h and .a files in your ios/native directory,\u003cbr\u003e\nyou can specify which \u0026ldquo;pods\u0026rdquo; your app uses via the \u003ccode\u003eios.pods\u003c/code\u003e build hint. (There are other build hints also\u003cbr\u003e\nif you need more advanced features).\u003c/p\u003e","title":"Cocoapods Support"},{"content":"\nWoke up this morning to the amazing news of Google winning against Oracle on the issue of fair use!\nThis is great news for everyone as it effectively makes \u0026ldquo;clean room implementation\u0026rdquo; legal. This solidifies\nJava’s status as \u0026ldquo;open\u0026rdquo; showing that even its owner has limitations on their power.\nI might write more about this next week if I have some time, I just hope the verdict doesn’t get turned in an appeal.\nIt’s been an eventful week, we are nearing the initial release of our new Windows UWP port and have put out some pretty\ncool demos. We have some new and exciting demos waiting for next week and have been as usual pretty busy\non community support in stack overflow.\nHow to make images in local Storage visible in WebComponent Injecting data into the web browser in a portable way is pretty hard no matter which platform you are on. In this\nquestion we give one of the most portable approaches to passing an image between Java and the web view.\nRead on stackoverflow…​\nGet the current visible image index from a DefaultListModel included in an ImageViewer Using the selection listener of the model is a swing like way of thinking that might be counter intuitive even though\nit’s pretty darn elegant. It’s great seeing a developer finding out and answering his own questions…​\nRead on stackoverflow…​\nHow to show two or more label at centre of the Container This question has quite a few potential correct answers…​.\nRead on stackoverflow…​\nNull pointer exception while calling web service in codenameone ImageAdapter is a required argument to the URLImage class.\nRead on stackoverflow…​\nHow do I simulate w3c Dom API in Codenameone We took a pretty different direction when implementing DOM in Codename One mostly due to the size constraints\nimposed in the LWUIT days. This is sometimes confusing:\nRead on stackoverflow…​\nFade animation not working properly when used with other animation Mixing and serializing animations can sometimes be tricky when one animation relies on another to complete,\nthese things are designed to work with each other thanks to the new animation framework.\nRead on stackoverflow…​\nTitle bar text doesn’t show Please upvote this question.\nIt’s a perfectly decent question that got downvoted for no reason, it’s still unclear to me why Anas was\nrunning into this issue though. It seems that some uses cases of the old GUI builder and the Toolbar API collide badly\nbut I can’t see which use cases.\nRead on stackoverflow…​\nCenter the Component in BorderLayout Using layout animations with nested hierarchies is often hard and error prone. It produces results that might be\nundesirable in some cases due to the clipping in nested layouts.\nRead on stackoverflow…​\nLandscape search textfield and keyboard issue This behavior has been around for quite a while in Codename One and I guess people didn’t complain much\nbecause they were used to it by now. This shows how important it is to ask because within a week of asking\nthe issue was already fixed…​\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-vii/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-vii/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWoke up this morning to the amazing news of Google winning against Oracle on the issue of fair use!\u003cbr\u003e\nThis is great news for everyone as it effectively makes \u0026ldquo;clean room implementation\u0026rdquo; legal. This solidifies\u003cbr\u003e\nJava’s status as \u0026ldquo;open\u0026rdquo; showing that even its owner has limitations on their power.\u003c/p\u003e\n\u003cp\u003eI might write more about this next week if I have some time, I just hope the verdict doesn’t get turned in an appeal.\u003c/p\u003e","title":"Questions of the Week VII"},{"content":"\nStarting with the new version of the NetBeans plugin we will have the new settings/preferences UI which we\nintroduced in the IntelliJ/IDEA plugin. Currently this will be in addition to the main\npreferences but as we move forward we will only add features to the new settings UI.\nYou will be able to open the new project preferences UI by right clicking the project and selecting it in the\nCodename One section:\nFigure 1. Launching the new preferences UI\nNotice that the UX while similar has some distinct differences:\nWe use the mobile style of scrolling as it was built with Codename One\nYou can see global settings by clicking the \u0026ldquo;Globe\u0026rdquo; button on the top left\nYou can save/cancel using the X or save buttons on the top right.\nWe will probably make quite a few changes to this UI in the coming months to refine it further based on feedback\nfrom you guys.\nThe main motivation for doing this change is the new Windows UWP port which needed changes to the windows\nsection of the preferences. Doing this 3 times over is silly, changing one single global preferences tool is always\nthe right thing to do.\n__ This isn’t yet implemented in the Eclipse plugin but it might be done before the next update Command Icon States In a previous post we mentioned the ability to handle states\nin buttons and how that fits well with icon fonts.\nA question in the post raised the issue of commands which support such states but the API isn’t there.\nTo solve this we added a version of setMaterialIcon to FontImage\nthat accepts a Command as\nits argument. This effectively makes commands work with such icon fonts.\nTo support that further we also added to Toolbar\nthe methods: addMaterialCommandToSideMenu, addMaterialCommandToRightBar, addMaterialCommandToLeftBar \u0026amp;\naddMaterialCommandToOverflowMenu.\nThese accept one of the MATERIAL_* char constants from the FontImage class to create the icon for a command\nrelatively easily.\nSuppress Localization By default strings in Codename One are implicitly localized which is unique. Most frameworks require some\nlevel of intervention to implement localization but since Codename One was developed by people whose\nnative language isn’t English we felt compelled to fix that…​\nLocalization should be the default and Codename One does the right thing here, however sometimes you want to\nturn it off e.g. if you have a user submitted string that might be identical to an application resource bundle value.\nIn Label we have the\nsetShouldLocalize\nmethod which works great for disabling the implicit localization. However, as\nissue 1744 pointed out this needs to be done for\nother components too…​\nSo we added the same method to SpanLabel, SpanButton \u0026amp; MultiButton. You can now control localization\nspecifically in all of those components.\nBetter Locking Image locking is an esoteric performance implementation detail that most of you can and should be unaware of.\nIf you don’t care about the nitty gritty skip this section, for those of you who care and don’t know what I’m talking\nabout you can\nread this section and sidebar in the developer guide.\nIn the coming update we fixed issue #1746 to\nalso lock other button states (this was very visible with things like toggle buttons). But the main change was\nalso changing the locking behavior to act more like a smartpointer and less as a boolean flag which should reduce\nthe cases of memory thrashing when using the same encoded image, over and over…​ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChibuike Mba — May 31, 2016 at 11:59 pm (permalink) Hi Shai,\naddMaterialCommandToLeftBar of the Toolbar adds the command to the right instead of left.\nSecondly, FontImage passed to any of these methods does not show addMaterialCommandToRightBar and addMaterialCommandToLeftBar.\nRegards.\nShai Almog — June 1, 2016 at 3:43 am (permalink) Shai Almog says:\nHi,\nthanks for noticing 😉\nWe fixed that in git.\nWe also fixed the issue and added an additional version of the method that accepts font size. Should be in this Friday release.\nChibuike Mba — June 1, 2016 at 10:09 am (permalink) Chibuike Mba says:\nNice one Shai. Waiting for Friday release.\nI also noticed that FontImage added to addMaterialCommandToSideMenu does not change color based on the command state Pressed/Unselected. Has that been taken care of already and pending Friday release?\nRegards.\nShai Almog — June 2, 2016 at 3:35 am (permalink) Shai Almog says:\nI hope it does. If it doesn’t after this Friday release please file an issue.\nChibuike Mba — June 2, 2016 at 2:32 pm (permalink) Chibuike Mba says:\nOK.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-preferences-command-state-localization-locking/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-preferences-command-state-localization-locking/new-settings.png\"\u003e\u003c/p\u003e\n\u003cp\u003eStarting with the new version of the NetBeans plugin we will have the new settings/preferences UI which we\u003cbr\u003e\nintroduced in the \u003ca href=\"/blog/a-new-idea.html\"\u003eIntelliJ/IDEA plugin\u003c/a\u003e. Currently this will be in addition to the main\u003cbr\u003e\npreferences but as we move forward we will only add features to the new settings UI.\u003c/p\u003e\n\u003cp\u003eYou will be able to open the new project preferences UI by right clicking the project and selecting it in the\u003cbr\u003e\nCodename One section:\u003c/p\u003e","title":"New Preferences, Command State, Localization \u0026 Locking"},{"content":"\nWe were stuck on an \u0026ldquo;old\u0026rdquo; version of xcode in the build servers. This hasn’t been a big deal for most features\nbut in some cases we are running into issues e.g. in using the full capabilities of the new iPad or 3d touch. The reason\nfor this is Apples backwards compatibility policy.\nApple allows you to run an older version of xcode, but the newer versions of xcode always require the latest\nversion of Mac OS X. The problem here is that the latest version of Mac OS X doesn’t support older versions\nof xcode so if we upgrade we won’t be able to support older versions of the build…​\nNormally this shouldn’t be a problem, we already run fine on the latest version of xcode without a problem. However,\nyou might inadvertently have relied on some behaviors or functionality of the old xcode e.g. thru native code,\nthird party cn1lib or slight behavior variation.\nUnfortunately, this means that once we upgrade there is no way to turn back. We’ll need to update the OS’s of\nthe build servers and do this consistently so you will get consistent build results. This would also mean that some\naspects of versioned builds will not work as smoothly as the new iOS build servers won’t have the older version\nof xcode in place.\nThe Migration Plan We’ve setup a new build server as a \u0026ldquo;test pilot\u0026rdquo; to see that builds go thru as planned. You can/should test your\napp to see if it will be affected by the migration, please let us know immediately if there are issues!\n__ If you don’t do this we will not be able to go back! To test your app on the test pilot build server open the build.xml and search for the string \u0026quot;iphone\u0026quot; with the quotes.\nReplace it with \u0026quot;iphone_new\u0026quot; .\nE.g. notice the targetType=\u0026quot;iphone_new\u0026quot; line below:\n\u0026lt;target name=\u0026quot;build-for-ios-device\u0026quot; depends=\u0026quot;clean,copy-ios-override,copy-libs,jar,clean-override\u0026quot;\u0026gt; \u0026lt;codeNameOne jarFile=\u0026quot;${dist.jar}\u0026quot; displayName=\u0026quot;${codename1.displayName}\u0026quot; packageName = \u0026quot;${codename1.packageName}\u0026quot; mainClassName = \u0026quot;${codename1.mainName}\u0026quot; version=\u0026quot;${codename1.version}\u0026quot; icon=\u0026quot;${codename1.icon}\u0026quot; vendor=\u0026quot;${codename1.vendor}\u0026quot; subtitle=\u0026quot;${codename1.secondaryTitle}\u0026quot; targetType=\u0026quot;iphone_new\u0026quot; certificate=\u0026quot;${codename1.ios.debug.certificate}\u0026quot; certPassword=\u0026quot;${codename1.ios.debug.certificatePassword}\u0026quot; provisioningProfile=\u0026quot;${codename1.ios.debug.provision}\u0026quot; appid=\u0026quot;${codename1.ios.appid}\u0026quot; /\u0026gt; \u0026lt;/target\u0026gt; Assuming all goes well we will flip the switch and update some of the build servers to the latest OS. We’ll keep\none build server around with the legacy OS and change it so you will need to explicitly send a build to it…​\nThis effectively means you will need to revert this build.xml change to keep building as the new servers will\nthen use the \u0026ldquo;iphone\u0026rdquo; target. To build for the old build target you will need to do the inverse of the current change\nby sending a build to the \u0026quot;iphone_old\u0026quot; target.\nWe’ll support that for a while until we are convinced that the migration went smoothly at which point we will retire\nthe server.\nFrom past experience these things always generate issues for some developers that can sometimes take a while\nto resolve. That’s why it’s important to keep a legacy build server around. Unfortunately our experience here\nalso taught us that once we provide a workaround people use that and don’t test the new update.\nThe nice thing about this switch is that most developers won’t really feel it. Your builds will use newer\niOS capabilities without a single change made by you.\nBitcode Probably the biggest issue with the migration is bitcode support which was introduced a while back. To understand\nbitcode you need to understand a bit of the background…​\niOS applications are really Mac OS app bundles. The natively compiled binary can contain more than one processor\narchitecture and usually does. So by default when you build an iOS appstore build you are really building a 32 bit\nand 64 bit fat binary. Assuming you want to support the (Apple native) simulator too you will also need x86 binaries\nand this is just a partial list…​\nWhen we look into more esoteric devices like the Apple Watch or TV things become more complicated and would\nobviously become worse as a result.\nThis is the problem bitcode aims to solve. Since Apple already uses LLVM which has an intermediate representation\nafter compilation they might as well use that instead of the native OS executables. This would allow Apples servers\nto natively compile the app to any future processor platform without you changing your code…​ Effectively this is\nvery much like a form of bytecode for Apples benefit.\nBitcode is required for Apple Watch apps and might become required for all apps in the future so it’s a good idea\nto leave it on.\nThe main challenge with bitcode is 3rd party libraries, if you use any of those they need to be compiled with bitcode\nsupport enabled otherwise the compiler will fail. Many libraries (especially older ones) don’t have bitcode support\nso you might need to update native code to include that functionality.\nWe intend to offer a flag to disable bitcode before we go into production with this version, however right now it’s\nnot in the current version.\nZlib QR/Barcode Support A while back we announced that we are removing the QR/Bar code support from Codename One and moving\nit to an external library. We deprecated the API’s and starting from recent builds you will no longer be able to\nuse the builtin API.\nZlib uses a native library that doesn’t support the new bitcode architecture expected in iOS. So once we removed\nit Codename One compiled without a problem with bitcode support turned on.\nIf you need support for QR/bar code scanning you need to migrate your code to use the new\ncn1-codescan library instead. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nShai Almog — May 25, 2016 at 5:54 pm (permalink) Shai Almog says:\nWe just added ios.bitcode=false as an option to disable bitcode. If you are running into issues please try that build hint and let us know either way.\nGareth Murfin — May 27, 2016 at 12:06 am (permalink) Gareth Murfin says:\nWill try this out Shai and let you know the results. Cheers, Gaz.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/ios-server-migration-plan/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/ios-server-migration-plan/xcode-migration.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe were stuck on an \u0026ldquo;old\u0026rdquo; version of xcode in the build servers. This hasn’t been a big deal for most features\u003cbr\u003e\nbut in some cases we are running into issues e.g. in using the full capabilities of the new iPad or 3d touch. The reason\u003cbr\u003e\nfor this is Apples backwards compatibility policy.\u003c/p\u003e\n\u003cp\u003eApple allows you to run an older version of xcode, but the newer versions of xcode always require the latest\u003cbr\u003e\nversion of Mac OS X. The problem here is that the latest version of Mac OS X doesn’t support older versions\u003cbr\u003e\nof xcode so if we upgrade we won’t be able to support older versions of the build…​\u003c/p\u003e","title":"iOS Server Migration Plan"},{"content":"\nPropertyCross is one of our newer demos, due to that there was\nrelatively very little work needed to modernize it and this resulted in a stunning improvement over the existing\ndemo. During that process we also discovered a small regression due to changed in the web service we relied on.\nCheck the live version running on the right hand side thanks to the power of the Codename One JavaScript port!\nProperty Cross uses the nestoria webservice to list houses (properties) for sale in the UK. The webservice is a\ntypical JSON based web service with the common use cases of searching, listing, thumbnail view, favorites etc.\nThe demo is specifically designed to be very simple and use caching/location to enhance the native app experience\nas opposed to just using a web app. The core of this demo was developed to help compare cross platform tools\nand showcase their differences.\nOur implementation of property cross is 100% portable and contains no platform specific or native code, it\nincludes 630 well commented lines of code (including imports and boilerplate) with no extra XML’s or special\ndesigns. This makes the Codename One implementation the smallest one we can find in the native tools\nimplementations (in some cases 5x smaller).\nIn fact Codename Ones implementation is so terse it is smaller than most HTML5 implementations despite\nJavaScripts famed terseness.\nThis is despite the fact that Codename One implements some functionality that isn’t specified such as\ninfinite scrolling etc…​\nWhat Changed To modernize the demo we started by updating the syntax to use Java 8 features such as lambdas, diamond operator\netc.\nWe then migrated the code to use the new Toolbar API\n\u0026amp; updated the syntax to use the terse version of the layout code.\nWe changed the back button behavior to use the Toolbar which looks great but the biggest effect was in a\nsmall change to use the native thin fonts. It really made the app feel more native.\nOther than that we used the new material icon fonts for the star/favorite functionality which makes the app both\nmore adaptable and more attractive.\nThe Source Check out the full source code for the demo in the\ngithub repository for the PropertyCross demo.\nThis demo will be integrated into the upcoming new project wizards in the various IDEs.\nUp Next I was working on a couple of more challenging apps/demos but ran into time constraints, I’d hope to tackle the\nbigger fish as we move forward but I’m not sure if this will be feasible in the next couple of weeks with the current\nworkload in place.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/property-cross-revisited/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/property-cross-revisited/property-cross-new.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/codenameone/PropertyCross\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ePropertyCross\u003c/a\u003e is one of our newer demos, due to that there was\u003cbr\u003e\nrelatively very little work needed to modernize it and this resulted in a stunning improvement over the existing\u003cbr\u003e\ndemo. During that process we also discovered a small regression due to changed in the web service we relied on.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eCheck the live version running on the right hand side thanks to the power of the Codename One JavaScript port!\u003c/strong\u003e\u003c/p\u003e","title":"Property Cross Revisited"},{"content":"\nSticky headers was one of the first big requests we said no to. Back in the day a lot of people asked for\nit but we always shot it down because it was too hard to implement on top of our Swing inspired lists.\nThis predated our Container improvement, InfiniteContainer\nand InfiniteScrollAdapter.\nWhile our preference for lists has waned we never got around to show how easy it is to do sticky headers with Container\nuntil last week when Chen released the\nsticky headers demo.\nIt’s a pretty basic demo and relatively simple at that but that’s exactly the point. Codename One is flexible\nenough to do pretty much anything you want especially if you don’t lock yourself into a rather restrictive\ncomponent like List.\nCheck out a live demo to the right here…​\nYou can see the full source for the demo\nhere.\nChen chose to implement this on top of the glass pane which provides some capabilities and control over graphics,\nyou could also use the layered pane or a LayeredLayout to achieve similar effects as well. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChibuike Mba — May 26, 2016 at 7:15 am (permalink) Chibuike Mba says:\nHi Shai, does List component support InfiniteScrollAdapter?\nShai Almog — May 27, 2016 at 5:09 am (permalink) Shai Almog says:\nHi,\nNo. It’s an either/or situation. Infinite components are meant to replace list.\nChibuike Mba — May 27, 2016 at 6:43 am (permalink) Chibuike Mba says:\nOk Shai, I will experiment with Infinite components to know if they will serve my needs. But is there any performance advantage of using Infinite components over List?\nShai Almog — May 29, 2016 at 2:55 am (permalink) Shai Almog says:\nThat depends a lot on your use case but generally yes.\nThe performance advantage starts to erode in the thousands of elements.\nNigel Chomba — May 30, 2016 at 9:48 am (permalink) Nigel Chomba says:\nits causing Stack overflow error..[EDT] 0:0:0,0 – java.lang.StackOverflowError\nChen Fishbein — May 30, 2016 at 11:57 am (permalink) Chen Fishbein says:\nCan you please open an issue here:https://github.com/chen-fis…\nWith a snippet of code that reproduces this error\nChibuike Mba — July 21, 2016 at 3:05 pm (permalink) Chibuike Mba says:\nHi Shai and Chen,\nI use StickyHeader class in one of my app’s UIs and it gave me what I want in terms of layout as can be seen in first image as attached to my post.\nBut am having 2 challenges:\nWhen the list (MultiButtons inside Tab) is scrolled, if the floating action button (FAB) is on screen the StickyHeader component overlaps the Toolbar as can be seen in the second image but if I remove the FAB (which is added to LayeredPane) it displays well as can be seen in the third image. In my Form layout I have 3 components added directly to the Form (BoxLayout.y): First Container, Second StickyHeader and third Tab as can be seen in the fourth image.\nWhen the list is scrolled and the StickyHeader component (which contains my Tab title buttons) sticks at the top of the screen the tab title buttons(SUBSCRIBERS AND FOLLOW UPS) stops responding to clicks. Please you assistance in helping me resolve these issues is highly anticipated and appreciated.\nKind Regards.\nShai Almog — July 22, 2016 at 4:45 am (permalink) Shai Almog says:\nNice looking app! Is it in the gallery?\n1. I don’t see that issue, am I missing something in the image?\nIt looks like you are using title hiding too, is it possible it collides with that?\n2. Can you reproduce this in a standalone testcase?\nChibuike Mba — July 22, 2016 at 1:09 pm (permalink) Chibuike Mba says:\n\u0026ldquo;Nice looking app!\u0026rdquo; Thanks.\n\u0026ldquo;Is it in the gallery?\u0026rdquo; Yes, but this particular screen is part of new version currently under development and will be out before the end of August.\n\u0026ldquo;1. I don’t see that issue, am I missing something in the image?\u0026rdquo; Sorry, the images reordered from the way I uploaded them.\n\u0026ldquo;It looks like you are using title hiding too, is it possible it collides with that?\u0026rdquo; No, am not using Title hidden, that is where the issue lies, the StickyHeader component just collides with and covers the Toolbar while scrolling (as you can see in the image without back icon) and this occurs only when I add any component to the Form’s LayeredPane (link FAB).\nIf I did not add any component to the Form’s LayeredPane (as you can see in the image without FAB button at the bottomright side of the screen) the StickyHeader component will behave well and stick below the Toolbar while scrolling.\nThe StickyHeader component dimension is highlighted with black bordered rectangle in on of the images.\n\u0026ldquo;2. Can you reproduce this in a standalone testcase?\u0026rdquo; Ok, I will try to reproduce it this weekend.\nAm suspecting that LayeredPane components conflicts with GlassPane components in the same Form.\nThanks.\nShai Almog — July 23, 2016 at 4:50 am (permalink) Shai Almog says:\nLayered pane and glass pane are very different but if you placed major components in the layered pane this might produce a conflict as we sometimes use the layered pane for various effects. We now support a multi-layered pane which should work better with less conflicts but haven’t really migrated to that.\nChibuike Mba — July 23, 2016 at 11:57 pm (permalink) Chibuike Mba says:\nI modified the StickyHeader class and it worked for me.\nI changed from GlassPane used by StickyHeader class to LayeredPane and my 2 challenges where solved:\n1)No more overlapping with Toolbar(sticks below Toolbar as expected).\n2)The StickyHeader is now interactive(can respond to events when it sticks below Toolbar).\nHere is the modified StickyHeader class code:\n/*\nTo change this license header, choose License Headers in Project Properties. To change this template file, choose Tools | Templates and open the template in the editor.\n*/\npackage com.codename1.ui; import com.codename1.ui.events.ScrollListener;\nimport com.codename1.ui.layouts.BorderLayout;\nimport java.util.ArrayList;\n/**\n*\n@author Chen\n*/\npublic class StickyHeader extends Container implements ScrollListener { private int previousPosition;\nprivate boolean needToCheck = false;\nprivate Component comp = null;\npublic StickyHeader() {\n}\n@Override\nprotected void initComponent() {\nsuper.initComponent();\nContainer p = getParent();\np.addScrollListener(this);\npreviousPosition = getParent().getAbsoluteY() – getAbsoluteY();\n}\n@Override\nprotected void laidOut() {\nif(getY() == 0){\nneedToCheck = true;\n}\n}\n@Override\npublic void scrollChanged(int scrollX, int scrollY, int oldscrollX, int oldscrollY) {\nint position = getParent().getAbsoluteY() + scrollY – getAbsoluteY();\nif(position \u0026gt;= 0){\nif(previousPosition \u0026lt; 0){\nneedToCheck = true;\n}\n}else{\nif(previousPosition \u0026gt; 0){\nneedToCheck = true;\n}\n}\nif (scrollY – oldscrollY \u0026gt;= 0) {\nif(needToCheck){\npushToHeader();\n}\n}else{\nArrayList stack = (ArrayList) getParent().getClientProperty(\u0026ldquo;sticky\u0026rdquo;);\nif (stack != null \u0026amp;\u0026amp; !stack.isEmpty()\u0026amp;\u0026amp; stack.get(0) == this \u0026amp;\u0026amp; position\u0026lt;0) {\npopFromHeader();\n}\n}\npreviousPosition = position;\nneedToCheck = false;\n}\n@Override\nvoid paintGlassImpl(Graphics g) {\n}\nprivate void popFromHeader() {\nArrayList stack = (ArrayList) getParent().getClientProperty(\u0026ldquo;sticky\u0026rdquo;);\nstack.remove(0);\nif(!stack.isEmpty()){\nStickyHeader h = (StickyHeader)stack.get(0);\nh.installSticky();\n}else{\ngetComponentForm().getLayeredPane().removeComponent(comp);\naddComponent(comp);\n}\n}\nprivate void pushToHeader() {\nArrayList stack = (ArrayList) getParent().getClientProperty(\u0026ldquo;sticky\u0026rdquo;);\nif (stack == null) {\nstack = new ArrayList();\ngetParent().putClientProperty(\u0026ldquo;sticky\u0026rdquo;, stack);\n}\nif(!stack.isEmpty()){\nStickyHeader h = (StickyHeader) stack.get(0);\nif(getY() \u0026lt; h.getY()){\nreturn;\n}\n}\nstack.add(0, this);\ninstallSticky();\n}\nvoid installSticky() {\nif(getComponentCount()\u0026lt;1)\nreturn;\ncomp = getComponentAt(0);\nremoveComponent(comp);\ngetComponentForm().getLayeredPane().addComponent(BorderLayout.NORTH, comp);\n}\n}\nThe changes:\nAdded comp variable (to hold component added to StickyHeader before removing the component from the parent form and adding to layered pane).\nModified popFromHeader() method (precisely, the else statement)\nModified installSticky() method\nRemoved createPainter() method (as is no longer needed)\nNB: The modified StickyHeader class assumes that the layered pane has borderlayout and that not component is already added to the north.\nNB: The multi-layered pane you mentioned will be handy to make sure that the StickyHeader component remains in its own layered pane.\nThe image bellow shows my UI as I expect.\nThanks for your guide.\nShai Almog — July 24, 2016 at 3:45 am (permalink) Shai Almog says:\nLooks great. I really like the floating folded button, what did you do there?\nChibuike Mba — July 24, 2016 at 2:27 pm (permalink) Chibuike Mba says:\nThanks Shai.\nI have FAB class (Floating Action Button – custom component) that accept 3 arguments (bg image, icon and title)\nIn some of the screens above with single FAB button (with menu icon), I just added the button to the layered pane of the Form class and when clicked, I add other FAB buttons to Dialog class layered pane and show it, as can be seen above.\nThe code for add FAB buttons to Dialog is as below:\nContainer con = BoxLayout.encloseY(fabNewsletter, fabAdd, fabMark, fabClear);\nDialog f = new Dialog();\nf.setDialogUIID(\u0026ldquo;Container\u0026rdquo;);\nf.getLayeredPane().removeAll();\nf.showPacked(BorderLayout.CENTER, false);\nf.getLayeredPane().setLayout(new BorderLayout());\nf.getLayeredPane().add(BorderLayout.SOUTH, new Container(new BorderLayout()).add(BorderLayout.EAST, con));\ncon.animateLayoutAndWait(10);\nKind Regards.\nShai Almog — July 25, 2016 at 4:36 am (permalink) Shai Almog says:\nThanks, that looks very similar to some of the code I wrote that does the same. We didn’t publish it because we’d like to get a lot of the nuance of that component into place before we bring out official support.\nCh Hjelm — September 18, 2016 at 9:57 am (permalink) Ch Hjelm says:\nHi Chen or Shai,\nThe StickyHeaders are a really great addition to the UI, do you think you might consider incorporating them into the CN1 platform?\nRight now, as Chen wrote, you need to copy the StickyHeader.java file into your local copy of CN1 sources, which as far as I understand means that you cannot use them when you build for a device.\nI’ve also noticed that the StickyHeader is shown on top of the ToolBar instead of on top of the scrollable list, so not quite useable as-is.\nFinally, if you do incorporate them, it would be a neat touch to add an animation when one header replaces another.\nHoping for the best 🙂\nShai Almog — September 19, 2016 at 3:54 am (permalink) Shai Almog says:\nHi,\nno you use it in your own project which means you can use it when building for devices. Chen’s implementation depends on internal package protected behavior which means that one of the classes must reside within the com.codename1.ui package.\nThis doesn’t require any modification to the Codename One sources.\nBecause this class isn’t as mature as some other classes we don’t have any short term plans to incorporate this into Codename One. It is also pretty difficult to implement this in a generic way.\nAlso check out alternative implementations mentioned in the comments below.\nCh Hjelm — September 20, 2016 at 8:43 pm (permalink) Ch Hjelm says:\nThanks, but on Chen’s github page (https://github.com/chen-fis…) it says \u0026ldquo;Important – make sure the class stays in the com.codename1.ui package.\u0026rdquo; And when I put the StickyHeader.java file there (in my copy of the CN1 sources), I can compile on my machine, but the build for devices fails, saying that StickyHeaders.java is missing. So, I don’t understand how it can be used?\nI also tried Chibuike’s version below, but it caused some other problems. And I’d obviously prefer to benefit from the existing implementation to not have to get into the source code myself 🙂\nShai Almog — September 21, 2016 at 4:23 am (permalink) Shai Almog says:\nYou can create that package within your project. You shouldn’t modify our sources to do that. In your project create a new package with the right name and place it there.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/sticky-headers/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/sticky-headers/sticky-headers.png\"\u003e\u003c/p\u003e\n\u003cp\u003eSticky headers was one of the first big requests we said no to. Back in the day a lot of people asked for\u003cbr\u003e\nit but we always shot it down because it was too hard to implement on top of our Swing inspired lists.\u003cbr\u003e\nThis predated our Container improvement, \u003ca href=\"/javadoc/com/codename1/ui/InfiniteContainer/\"\u003eInfiniteContainer\u003c/a\u003e\u003cbr\u003e\nand \u003ca href=\"/javadoc/com/codename1/components/InfiniteScrollAdapter/\"\u003eInfiniteScrollAdapter\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eWhile our preference for lists has waned we never got around to show how easy it is to do sticky headers with \u003ccode\u003eContainer\u003c/code\u003e\u003cbr\u003e\nuntil last week when \u003ca href=\"https://twitter.com/CFishbein/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eChen\u003c/a\u003e released the\u003cbr\u003e\n\u003ca href=\"https://github.com/chen-fishbein/stickyheaders-codenameone\" target=\"_blank\" rel=\"noopener noreferrer\"\u003esticky headers demo\u003c/a\u003e.\u003c/p\u003e","title":"Sticky Headers"},{"content":"\nOne of our support emails drew my attention to a glaring ommission in our icon font support…​\nWhen we create an icon for a Button it’s color matches the unselected color of the button which might not\nlook as attractive when the Buton is selected or pressed!\nThe thing is that with an icon font this is trivial to accomplish and requires literally no code changes. So starting with\nthe the next update calling\nFontImage.setMaterialIcon(Label l, char icon)\nor\nFontImage.setMaterialIcon(Label l, char icon, float size)\nwith a Button will implicitly set the pressed/selected \u0026amp; disabled icons for the button.\nE.g.:\nForm f = new Form(\u0026quot;Buttons\u0026quot;, BoxLayout.y()); CheckBox pressed = CheckBox.createToggle(\u0026quot;Pressed\u0026quot;); pressed.setUIID(\u0026quot;Button\u0026quot;); FontImage.setMaterialIcon(pressed, FontImage.MATERIAL_THUMB_UP, 5); pressed.setSelected(true); Button unselected = CheckBox.createToggle(\u0026quot;Unselected\u0026quot;); unselected.setUIID(\u0026quot;Button\u0026quot;); FontImage.setMaterialIcon(unselected, FontImage.MATERIAL_THUMB_UP, 5); Button disabled = CheckBox.createToggle(\u0026quot;Disabled\u0026quot;); disabled.setUIID(\u0026quot;Button\u0026quot;); FontImage.setMaterialIcon(disabled, FontImage.MATERIAL_THUMB_UP, 5); disabled.setEnabled(false); f.add(pressed). add(unselected). add(disabled); f.show(); PSA – Always Use UTF-8 Everyone has their \u0026ldquo;pet peeve\u0026rdquo; about Java and mine is the encoding support. In a typical Sun way the Java API\nchose the wrong defaults aligning itself with the system instead of aligning itself with whats right.\nUTF-8 works for pretty much everyone and using it universally would solve many of the problems we see frequently.\nHowever, Java defaults to platform native encoding and so minor mistakes like calling the String.getBytes() method\ncan be devastating and hard to track. To make matters even more annoying the correct method String.getBytes(encoding)\nthrows a checked exception for no real reason making it far more painful to use than the default…​\nI was reminded of this just the other day, it seems our Properties\nclass used ISO-8859-1 encoding. This is pretty much the most standard encoding and should be supported everywhere…​\nTurns out it doesn’t work in the JavaScript port which uses UTF-8. Since UTF-8 makes more sense we just fixed the\nProperties instead of fixing the encoding which is apparently challenging. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChibuike Mba — May 25, 2016 at 6:03 pm (permalink) Chibuike Mba says:\nHi Shai, does Toolbar Command support this button icon capability?\nShai Almog — May 26, 2016 at 4:10 am (permalink) Shai Almog says:\nNo \u0026amp; sort of…\nThis is a bit problematic. Commands support the pressed/selected/disabled icon styles but since you don’t normally call the set icon method on them thru the FontImage class this won’t work well…\nWe’ll add to the next update a version of setMaterialIcon that accepts a command and UIID. And we’ll also try to add a few methods to toolbar that should do effectively this e.g. addMaterialCommandToSideMenu(…)\nChibuike Mba — May 26, 2016 at 7:10 am (permalink) Chibuike Mba says:\nOK. Great. Will be looking forward for that.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/pressed-selected-icon-font-utf-8/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/pressed-selected-icon-font-utf-8/unselected-pressed-disabled-buttons.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of our support emails drew my attention to a glaring ommission in our icon font support…​\u003cbr\u003e\nWhen we create an icon for a \u003ccode\u003eButton\u003c/code\u003e it’s color matches the unselected color of the button which might not\u003cbr\u003e\nlook as attractive when the \u003ccode\u003eButon\u003c/code\u003e is selected or pressed!\u003c/p\u003e\n\u003cp\u003eThe thing is that with an icon font this is trivial to accomplish and requires literally no code changes. So starting with\u003cbr\u003e\nthe the next update calling\u003cbr\u003e\n\u003ca href=\"/javadoc/com/codename1/ui/FontImage/#setMaterialIcon-com.codename1.ui.Label-char-\"\u003eFontImage.setMaterialIcon(Label l, char icon)\u003c/a\u003e\u003cbr\u003e\nor\u003cbr\u003e\n\u003ca href=\"/javadoc/com/codename1/ui/FontImage/#setMaterialIcon-com.codename1.ui.Label-char-float-\"\u003eFontImage.setMaterialIcon(Label l, char icon, float size)\u003c/a\u003e\u003cbr\u003e\nwith a \u003ccode\u003eButton\u003c/code\u003e will implicitly set the pressed/selected \u0026amp; disabled icons for the button.\u003c/p\u003e","title":"Pressed/Selected Icon Font \u0026 UTF-8"},{"content":"\nIt’s been quite a busy week with many changes and updates, some of those were in line for a couple of tools we\nplan to introduce over the next few weeks. This week I also placed an interesting thread from the discussion group.\nNormally I try to keep this focused on stackoverflow but if a good thread comes up in the discussion group\nthat raises an interesting topic I think this is a good place for it too.\nThe removeCommand is not working for the toolbar commands Removing a command from the Toolbar requires that we revalidate the layout, that isn’t as intuitive sometimes\nbut it helps when more than one command is changed.\nRead on stackoverflow…​\nHow to verify that X509TrustManager is correctly implemented on iOS/Android We don’t hide or change the default SSL behavior in mobile OS’s at this time, you can do it if you want to go into\nthe native functionality but the default should be reasonably secure.\nRead on stackoverflow…​\nWhat are the differences between CodenameOne getCurrentLocation methods This question didn’t get much of an answer as much as \u0026ldquo;for your use case you should use neither\u0026rdquo;…​\nRead on stackoverflow…​\nCross-platform Project and Techniques Dimitar raised a point that he considered about missing platform specific details in our documentation, this isn’t\nsomething that’s missing in the documentation as much as a conceptual difference between Codename One and\ntools such as Xamarin/React Native etc…​\nHe raised some interesting points that highlight the advantages and disadvantages of our approach to portability:\nRead in the discussion group…​\nData upload works on Android phone but fails on Iphone 4 While I answered that one the submitter pretty much investigated the whole thing on his own and mostly used\nstack overflow to line up his thought process. That’s a good way to ask a question…​\nRead on stackoverflow…​\nHow intercept the \u0026ldquo;Cancel\u0026rdquo; and \u0026ldquo;OK\u0026rdquo; actions belonging to the native IOS picker component? One of the problems with native widgets is that they differ so much both in subtle and obvious ways. I can’t think of\na component that gave us more grief than the picker.\nRead on stackoverflow…​\nWarning paint queue size exceeded, please watch the amount of repaint calls Error This is a warning call we wrote when we coded LWUIT back in 2007. It was one of those failsafe \u0026ldquo;no one will ever\nget this warning\u0026rdquo; things…​\nRead on stackoverflow…​\nAnimate a gif file only once We don’t use a lot of animated gifs in our apps and focus more on layout animations/transitions but we know\nquite a few people still use such effects and might find this useful.\nRead on stackoverflow…​\nMessage.setAttachment is silently failing It’s sometimes hard to track edge case device specific behaviors especially with the shifting ground of mobile\nOS targets.\nRead on stackoverflow…​\nDifferent response codes between ipa and source code Building on our servers vs. building from the source code they generate should be nearly identical but we can’t\nguarantee that because our server OS/xcode versions might differ.\nRead on stackoverflow…​\nHow to set FacebookUrlSchemeSuffix build hint Some things we just never tried to do on our own so it’s great to find out that it’s possible to have two separate accounts\nwith the same facebook app.\nRead on stackoverflow…​ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAndreas Grätz — May 23, 2016 at 7:14 am (permalink) Andreas Grätz says:\nI have several questions:\n1. very simple: I want to create a fullscreen app, without any appearence of a toolbar, but at start and sometimes during running the toolbar appears although I called hideToolbar() (this works only AFTER the toolbar was initially shown.\n2. When do you support iOS9 split view and master-detail splitview on iPads?\n3. When do you support iPad Pro 12 inch native resolution?\nShai Almog — May 24, 2016 at 4:08 am (permalink) Shai Almog says:\n1. Is this on iOS devices or everywhere? If you don’t want anything to appear set the title to \u0026quot;\u0026quot; and make sure there are no commands.\n2/3. Good questions. We already support everything in terms of the code but we are currently still compiling on an older version of xcode due to logistical reasons that would require a painful migration. We’re announcing a migration process to the newest version of xcode this week so keep an eye on the blog. Once we have the newest version of xcode in the new build servers we’ll be able to address a lot of feature requests.\nAndreas Grätz — May 25, 2016 at 11:11 pm (permalink) Andreas Grätz says:\n1. Thanks! I have found a solution. I have to set the margins in the theme to 0, too.\n2. I’m writing a business app and this app needs a master/detail view on tablets like this: https://apppie.files.wordpr… and this https://developer.xamarin.c…\n\u0026ldquo;Translated\u0026rdquo; to Codename One I need to place two \u0026ldquo;forms\u0026rdquo; side by side each with a title and actions/menus. The left form is the masterview and must have a constant(!) width on both landscape and portrait-mode. The problem is, that placing two forms in a (super-)form, it is not possible to set the widths and the menus don’t work.\nShai Almog — May 26, 2016 at 3:57 am (permalink) Shai Almog says:\nI would not recommend using two forms. Probably the best approach for this specific UI is to go with the Toolbars side menu. Right now the permanent side menu isn’t toggleable and doesn’t have an orientation sensitive setting both of which are things it should have.\nYou can also use an approach similar to the kitchen sink demo where we used containers for all the views in tablet mode and forms for phone modes.\nIdeally we want to have a more generic approach for this, we actually have an old attempt at a generic master detail API but it was pretty awful as it predated a lot of the newer ideas we have in the framework such as Toolbar. We might take a stab at that again as we are rewriting the kitchen sink demo.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-vi/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-vi/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIt’s been quite a busy week with many changes and updates, some of those were in line for a couple of tools we\u003cbr\u003e\nplan to introduce over the next few weeks. This week I also placed an interesting thread from the discussion group.\u003cbr\u003e\nNormally I try to keep this focused on stackoverflow but if a good thread comes up in the discussion group\u003cbr\u003e\nthat raises an interesting topic I think this is a good place for it too.\u003c/p\u003e","title":"Questions of the Week VI"},{"content":"\nWe’re all pretty jaded when it comes to software but when I first saw yHomework I was completely floored by it!\nWhere was this tool when I was in junior high?\nIf you haven’t seen yHomework in action I suggest you give it a try right now on your\nAndroid or\niOS device.\nIn a nutshell the app accepts several types of math equations starting with the basic algebra e.g 3(x+5)=6 and then\nshows you the process of solving it as if a human teacher solved it for you. Including text explanation of every step\nthat you can just read thru and understand!\nThis is ideal for students picking up the higher level math subjects who might struggle with an exercise, why does\nthe answer in the book differ from my result?\nIn Codename One yHomework was one of the first major Codename One apps ever written, some of\nour features were explicitly built to help this app. Originally the author wrote an entire implementation in JavaScript\nand scrapped the whole thing our of concern for IP issues \u0026amp; a personal preference for Java.\n__ | Despite obfuscation JavaScript apps (e.g. PhoneGap/Cordova) can be unzipped and resold which is a\ncommon practice in some markets The app makes use of many Codename One features including in-app-purchase, cn1libs for the ads, push notification etc.\nIn fact the app was so successful that it brought down our old push notification servers back in the day.\nPortability yHomework benefited greatly from it’s portability as a few years ago a competing iOS app went on a media blitz.\nyHomework saw it’s marketshare rise both on iOS and Android thanks to that competitors campaign. The rise\nwas especially pronounced on Android (where the competitor wasn’t present) but also carried into iOS thanks\nto the social sharing effect.\nWith installs in the millions and great reviews yHomework shows that cross platform can be a fan favorite\nwhere the complaints users have are more around the fact that the app isn’t completely free than anything else…​\nIf I had to pick a favorite Codename One app I would pick yHomework. It shows that content and functionality\nis still king \u0026amp; the most important thing an app can deliver. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — May 19, 2016 at 3:48 pm (permalink) Chidiebere Okwudire says:\nI remember downloading the app over a year ago and the graphics on my phone were pretty poor… Maybe I’ll check it out again.\nBy the way, how do you make the app showcase images like the one at the top of this post? I’m looking for a tool to be able to do similar stuff.\nbryan — May 19, 2016 at 11:46 pm (permalink) bryan says:\nThat’s a very slick looking app. Any idea what sort of time it took to develop ?\nShai Almog — May 20, 2016 at 4:15 am (permalink) Shai Almog says:\nThe UI was designed before flat design took over, the general design was around the idea of familiarity to 7th-10th grade kids (notebook, calculator motif). My one complaint about the UI is it’s performance which I think could be improved significantly.\nSince this app is so old by now it was developed before there were \u0026ldquo;best practices\u0026rdquo; for Codename One and a lot of things could probably be accomplished in a more efficient way.\nShai Almog — May 20, 2016 at 4:16 am (permalink) Shai Almog says:\nThe core UI was written in a few months but overall this app has been in production since 2013 or so. The current level of functionality and UI evolved over time.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/featured-app-yhomework/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/featured-app-yhomework/yhomework.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’re all pretty jaded when it comes to software but when I first saw yHomework I was completely floored by it!\u003c/p\u003e\n\u003cp\u003eWhere was this tool when I was in junior high?\u003c/p\u003e\n\u003cp\u003eIf you haven’t seen \u003ca href=\"http://www.yhomework.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eyHomework\u003c/a\u003e in action I suggest you give it a try right now on your\u003cbr\u003e\n\u003ca href=\"https://play.google.com/store/apps/details?id=com.MathUnderground.MathSolver\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eAndroid\u003c/a\u003e or\u003cbr\u003e\n\u003ca href=\"https://itunes.apple.com/us/app/yhomework/id604715759\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eiOS device\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eIn a nutshell the app accepts several types of math equations starting with the basic algebra e.g \u003ccode\u003e3(x+5)=6\u003c/code\u003e and then\u003cbr\u003e\nshows you the process of solving it as if a human teacher solved it for you. Including text explanation of every step\u003cbr\u003e\nthat you can just read thru and understand!\u003c/p\u003e","title":"Featured App – yHomework"},{"content":"\nOne of the often requested features in Codename One is zip support, we had some issues with it until a couple\nof years back when we added tar and gzip support. But people still asked for standard zip file support which was\nmissing.\nWe’re working on a tool that we hope to share next week that needs zip to work. Initially we thought about doing\nthis natively as zip works on most native OS’s but one of the true benefits of the tool is if we can get it to work in\nthe JavaScript port live on the web…​\nSo I \u0026ldquo;ported\u0026rdquo; the zipme project to Codename One\nhere. I’m quoting the word \u0026ldquo;ported\u0026rdquo; because I did almost nothing.\nI just copied the sources into a new cn1lib project and it \u0026ldquo;just worked\u0026rdquo; for the most part.\nI did have to fix one thing in the iOS builds though. Some hackers use String objects to store binary data in\nrather creative ways to save a bit of syntax. This practice is rather inefficient when compared to just using arrays\nbut it is still widely practiced. In this case this code was used:\nString bitReverse = \u0026quot;\u000000\u000010\u000004\u000014\u000002\u000012\u000006\u000016\u000001\u000011\u000005\u000015\u000003\u000013\u000007\u000017\u0026quot;; That is the exceedingly rare octal notation in Java strings…​ Unfortunately because the data includes many \u0026ldquo;invalid\u0026rdquo;\ncharacters translating this into a C string is really hard. So our VM choked on that.\nNormally we’d fix something like this but since it’s both rare and slow when compared to just using an array\nwe chose to just fix the code and be done with it.\nToastBar Messages My code is littered with code that looks like:\n// error handling code block... Dialog.show(\u0026quot;Error\u0026quot;, \u0026quot;Generic error message\u0026quot;, \u0026quot;OK\u0026quot;, null); return; This is in catch blocks, if statements etc.\nI’m sure your code is full of that too and this was getting on my nerves. It’s great to have an error message but why\ndo we need to dismiss it or even have it in a Dialog?\nSo I wrote some code that shows it in a ToastBar\nand then it dawned on me that this should really replace Dialog\nfor this specific use case.\nSo we added these two static methods:\nToastBar.showErrorMessage(String msg, int timeout) ToastBar.showErrorMessage(String msg) These methods effectively make showing an error message stupid trivial. they also include a nice error icon on\nthe side from the material font…​\nThis cuts down on the boilerplate code and shows something that is \u0026ldquo;pretty\u0026rdquo; \u0026amp; modern by default which is\nimportant. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — May 18, 2016 at 9:41 pm (permalink) bryan says:\nThe ToastBar error is neat. When will this be available ?\nShai Almog — May 19, 2016 at 3:33 am (permalink) Shai Almog says:\nThanks. On Friday as usual 😉\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/zip-and-toast/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/zip-and-toast/toastbar-error.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the often requested features in Codename One is zip support, we had some issues with it until a couple\u003cbr\u003e\nof years back when we added tar and gzip support. But people still asked for standard zip file support which was\u003cbr\u003e\nmissing.\u003c/p\u003e\n\u003cp\u003eWe’re working on a tool that we hope to share next week that needs zip to work. Initially we thought about doing\u003cbr\u003e\nthis natively as zip works on most native OS’s but one of the true benefits of the tool is if we can get it to work in\u003cbr\u003e\nthe JavaScript port live on the web…​\u003c/p\u003e","title":"Zip and Toast"},{"content":"\nWhen we initially launched Codename One it was pretty hard to imagine todays apps. Menus and back navigation\nwere miles apart when comparing Android 2.x and iOS 4.x…​ So we created a very elaborate set of abstractions\n(command behavior) that served as a set of patch framework we could live with for a while.\nBut like any patch framework this started crumbling under its shear weight and this lead us to the\nToolbar API. The reason we\ncould do that is that a lot of the platform differences have converged, in 2012 it was blasphemy to have\na back button in Android title area and now it’s the official material design guideline.\nSo while platforms are still different their differences are more refined an less conceptual and that is the perfect\nenvironment for the Toolbar API. Toolbar solved most of these differences in a very portable and robust way but\none thing it didn’t codify was back button behavior, this was mostly due to the many nuances within this functionality\nand due to our bad experience with abstracting it in the old command behavior framework.\nBack Command In the previous implementation we would just call:\nform.setBackCommand(cmd); This would implicitly place the command in the title for iOS and wouldn’t do it for other platforms.\nWhen you use this with the Toolbar API\nyou would only get the hardware back button behavior and the command wouldn’t map to the title area leaving\niOS users with no other means to navigate.\nTo solve this in a more generic way we now added 4 new methods to Toolbar:\npublic Command setBackCommand(String title, ActionListener\u0026lt;ActionEvent\u0026gt; listener) public void setBackCommand(Command cmd) public Command setBackCommand(String title, BackCommandPolicy policy, ActionListener\u0026lt;ActionEvent\u0026gt; listener) public void setBackCommand(Command cmd, BackCommandPolicy policy) The default setBackCommand(cmd) and setBackCommand(String, ActionListener\u0026lt;ActionEvent\u0026gt;) will set the\nhardware back command and always set the material design back arrow to the left title area. This will allow you\nto keep a consistent look across platforms.\nYou will notice the usage of BackCommandPolicy, that is an enum with the following possible values:\nALWAYS – Show the back command always within the title bar on the left hand side. This will add the command\nsupplied \u0026ldquo;as is\u0026rdquo; but will give it the BackCommand UIID\nAS_REGULAR_COMMAND – this is effectively the same as calling addCommandToLeftBar and setting the\nhardware back command. This is identical to the ALWAYS option with the exception of using the TitleCommand\nUIID instead of the BackCommand UIID\nAS_ARROW – this is the default behavior for setCommand. Uses the material design arrow icon for the back\nbutton which will always appear on all platforms\nONLY_WHEN_USES_TITLE – this will only place the back command when the theme constant backUsesTitleBool\nis set to true. By default only the iOS themes have it set to true so the back command will only appear on the title\nfor iOS devices\nWHEN_USES_TITLE_OTHERWISE_ARROW – this option combines the logic of AS_ARROW and ONLY_WHEN_USES_TITLE.\nIt will use the command to show the back button on iOS devices but will use the material design arrow icon\nfor other devices\nNEVER – this adds nothing to the title bar. It only sets the hardware button. Effectively this option is here mostly\nfor completeness.\nGUI Builder Apps The old GUI builder has a navigation stack that automatically adds back buttons. Thus apps built with the old\nGUI builder had a problem mapping to back behavior with the Toolbar.\nWe now fixed that so the UIBuilder\nchecks if a Toolbar is installed and if so calls its version of setBackCommand effectively using the AS_ARROW\nback behavior.\nIf this isn’t what you had in mind but you still want to use the Toolbar with an old GUI builder app you can override the\nmethod:\nprotected void setBackCommand(Form f, Command backCommand) You can then set the command as you see fit to the parent form.\nSimpler Icon Font One of the minor annoyances with using icon fonts is the need to adapt them to a given style. This works nicely\nwhen we have a component like a button where we can use the buttons style as the basis for the UI but it\nbecomes painful with features such as commands where we don’t have a reference to the style object.\nTo make this a bit easier we made this code simpler:\nStyle s = UIManager.getInstance().getComponentStyle(\u0026quot;TitleCommand\u0026quot;); FontImage icon = FontImage.createMaterial(FontImage.MATERIAL_SEARCH, s, 3); As this:\nFontImage icon = FontImage.createMaterial(FontImage.MATERIAL_SEARCH, \u0026quot;TitleCommand\u0026quot;, 3); This will create a 3mm icon with the search icon and the foreground/background scheme of the TitleCommand\nUIID. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nLukman Javalove Idealist Jaji — May 20, 2016 at 8:25 am (permalink) Lukman Javalove Idealist Jaji says:\nThanks Shai for this post. I am particularly happy with the new Material Icon Code …. Means I don’t have to create several UIIDS in the designer which sometimes slows me down….\nMo — May 28, 2016 at 6:19 pm (permalink) Mo says:\nI am on 3.4.0 plugin but unable to use the Toolbar.setBackCommand, which version of the lib the above function is available on?? should the lib be updated manually or via the Plugin??\nShai Almog — May 29, 2016 at 3:12 am (permalink) Shai Almog says:\nGo to the preferences, under the Codename One section select \u0026ldquo;Update Client Libs\u0026rdquo;.\nMo — May 31, 2016 at 9:01 pm (permalink) Mo says:\nHi Shai, many thanks for your earlier reply, and having updated the Project Libs via the project properties, I came across strange and unexpected behavior while using the TextField, which can be seen/reproduced on the Simulator with the Kitchen Sink Input demo after updating the libs, please verify at your end and advice if something was overlooked on my end or with the latest libs?\nI am using Netbeans 8.1 with JDK1.8 and CodenameOnePlugin 3.4.0.\nShai Almog — June 1, 2016 at 3:46 am (permalink) Shai Almog says:\nHi,\nwhat’s the unexpected behavior?\nMo — June 1, 2016 at 11:30 am (permalink) Mo says:\nThank you for the speedy reply, and indeed, some of the strange behavior can be seen on the Kitchen Sink Input Demo via the Simulator after \u0026ldquo;updating the Project Libs\u0026rdquo; such as:\n1.On the Text Field, if you use the Tab key and returned , the original text cannot be removed and any new input will be visibly written on top of the previous.\nPlease try a few times and you will see this behavior,\n2. On the Text Field With Hint, if you type any text and press the Tab, the text will be replicated to the Multi-Line Text Field and cannot be removed.\nTry a couple of times and you will see that, it’s written on top of the previous!!\nI have already shared the screenshots along with the updated jar!\nPlease keep in mind that, this behavior is not happening on the previous version and before updating the Project Libs,\nPlease let me know if you would like any additional clarification on this?\nShai Almog — June 2, 2016 at 3:34 am (permalink) Shai Almog says:\nI didn’t see that but looking at the commit history I see Chen committed a fix that looks to be related to that so I guess it will be resolved this Friday. You can easily follow commits as explained here: https://www.codenameone.com…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/toolbar-back-easier-material-icons/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/toolbar-back-easier-material-icons/back-arrow.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen we initially launched Codename One it was pretty hard to imagine todays apps. Menus and back navigation\u003cbr\u003e\nwere miles apart when comparing Android 2.x and iOS 4.x…​ So we created a very elaborate set of abstractions\u003cbr\u003e\n(command behavior) that served as a set of patch framework we could live with for a while.\u003c/p\u003e\n\u003cp\u003eBut like any patch framework this started crumbling under its shear weight and this lead us to the\u003cbr\u003e\n\u003ca href=\"/javadoc/com/codename1/ui/Toolbar/\"\u003eToolbar API\u003c/a\u003e. The reason we\u003cbr\u003e\ncould do that is that a lot of the platform differences have converged, in 2012 it was blasphemy to have\u003cbr\u003e\na back button in Android title area and now it’s the official material design guideline.\u003c/p\u003e","title":"Toolbar Back \u0026 Easier Material Icons"},{"content":"\nThis week we chose to modernize the very outdated Chrome Demo. This demo\nis one of our early demos developed during the iOS 4.x era. We licensed it’s original design from\napp design vault and created a Codename One version\nof that original template. While the guys in app design vault modernized most of their templates to iOS 7\nflat design they didn’t do this for the Chrome demo.\nCheck out a live preview of the demo on the right here thanks to our JavaScript port!\nWe were a bit conflicted on whether this demo should be kept or discarded but we eventually decided to keep\nit due to two major reasons:\nThe calculator portion of the demo is pretty cool\nIt customizes the calendar widget and makes it look pretty decent.\nGUI Builder The Chrome demo was built using the GUI builder which we are now de-emphasizing in favor of the upcoming\nnew GUI builder. We converted the demo to use the new GUI builder code using the\nmigration wizard and this was a relatively smooth process\nalthough we needed to do some work to cleanup the old state machine and event handling. Since the demo\ndidn’t have much navigation logic and is relatively small the process was pretty easy.\nDesign We removed a lot of the brushed metal effects in the design to make the app feel more modern, we updated the\nfonts and replaced some of the icons with icon fonts. Specifically we used the builtin material design icons.\nThis improved the design considerably but this is probably not our most refined demo.\nThe Source Check out the full source code for the demo in the\ngithub repository for the Chrome demo.\nThis demo will be integrated into the upcoming new project wizards in the various IDEs.\nUp Next So far so good for our demo walkthru but these are still relatively simple demos, we hope to start tackling the\nmore challenging and interesting demos that might be harder to adapt to newer conventions. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nRoss Taylor — May 17, 2016 at 4:35 pm (permalink) Ross Taylor says:\nNice demo! However I wonder why it takes a while to load the app (around 15 – 30 seconds) is it line speed (I have 10Mbps), browser (Firefox v46) or your Javascript Port itself? What happens if the app is large around 23MB? Will it affect the load time in the browser?\nShai Almog — May 18, 2016 at 3:54 am (permalink) Shai Almog says:\nThe demo runs locally so once it’s downloaded everything is here. There are several large files it needs to download in advance e.g. the theme is 800kb but the biggest problem is http://codenameone.com/demo… which is 1.7mb.\nI think our current server doesn’t gzip the JavaScript file so that might be a problem.\n1.7MB is pretty small for what is effectively a full application with the JVM included but it does have a startup time overhead. This isn’t huge when compared to the many existing sites on the internet today in terms of data volume, but unlike those sites we need the whole thing to download before we can startup the VM.\nShai Almog — May 18, 2016 at 5:09 am (permalink) Shai Almog says:\nActually looking at this again it seems our CDN does gzip the file so it’s really 300kb or so which is pretty impressive… Looking at the firefox logs I think this might be the time taking to load the javascript and the resource files which are pretty large for this application (around 1.2mb). I think a lot of the resources can be optimized to reduce startup time further.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/chrome-demo/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/chrome-demo/chrome-demo.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThis week we chose to modernize the very outdated \u003ca href=\"/chrome/\"\u003eChrome Demo\u003c/a\u003e. This demo\u003cbr\u003e\nis one of our early demos developed during the iOS 4.x era. We licensed it’s original design from\u003cbr\u003e\n\u003ca href=\"http://www.appdesignvault.com/shop/chrome/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eapp design vault\u003c/a\u003e and created a Codename One version\u003cbr\u003e\nof that original template. While the guys in app design vault modernized most of their templates to iOS 7\u003cbr\u003e\nflat design they didn’t do this for the Chrome demo.\u003c/p\u003e","title":"Chrome Demo"},{"content":"\nWe talked about the\nnew Android 6 (Marshmallow) permissions in Codename One last week\nand so far we’ve been pretty happy with the result. We had some build regressions on the older Ant based build\npath but those were fixed shortly after and it’s been smooth sailing since then. As part of the transition to the new\npermissions system we added two features to the simulator and the AndroidNativeUtil class.\nSimulate Permission Prompts You can simulate permission prompts by checking that option in the simulator menu.\nFigure 1. Simulate permission prompts menu item in the simulator\nThis will produce a dialog to the user whenever this happens in Android and will try to act in a similar way to the\ndevice. Notice that you can test it in the iOS simulator too.\nAndroidNativeUtil’s checkForPermission If you write Android native code using our native interfaces you are probably familiar with the AndroidNativeUtil\nclass from the com.codename1.impl.android package.\nThis class provides access to many low level capabilities you would need as a developer writing native code.\nSince native code might need to request a permission we introduced the same underlying logic we used namely:\ncheckForPermission.\nTo get a permission you can use this code as such:\nif(!com.codename1.impl.android.AndroidNativeUtil.checkForPermission(Manifest.permission.READ_PHONE_STATE, \u0026quot;This should be the description shown to the user...\u0026quot;)){ // you didn't get the permission, you might want to return here } // you have the permission, do what you need This will prompt the user with the native UI and later on with our fallback option as described in\nthe previous blog post. Notice that\nthe checkForPermission method is a blocking method and it will return when there is a final conclusion\non the subject. It uses invokeAndBlock and can be safely invoked on the event dispatch thread without concern.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/marshmallow-permissions-in-the-simulator-and-native-code/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/marshmallow-permissions-in-the-simulator-and-native-code/marshmallow.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe talked about the\u003cbr\u003e\n\u003ca href=\"/blog/switching-on-android-marshmallow-permission-prompts.html\"\u003enew Android 6 (Marshmallow) permissions in Codename One last week\u003c/a\u003e\u003cbr\u003e\nand so far we’ve been pretty happy with the result. We had some build regressions on the older Ant based build\u003cbr\u003e\npath but those were fixed shortly after and it’s been smooth sailing since then. As part of the transition to the new\u003cbr\u003e\npermissions system we added two features to the simulator and the \u003ccode\u003eAndroidNativeUtil\u003c/code\u003e class.\u003c/p\u003e","title":"Marshmallow Permissions in the Simulator and Native Code"},{"content":"\nIt has been a very busy week around here with a lot going on. We’ve just sent out the Friday release update\nand we are gearing up for some other interesting things…​ These weekly question posts are really convenient\nas they help us center on what’s truly important – user support.\nWe had a lot of great questions on stack overflow this week:\nSaving Files in CodenameOne File systems on mobile are really complex/limited beasts, this often hits desktop developers hard when they\ntry to figure out how to adapt desktop paradigms like file pickers etc.\nRead on stackoverflow…​\nImage Viewer swipe vertically Some questions don’t have an answer other than you will have to hack the sources in some way to enable this\nfunctionality…​\nRead on stackoverflow…​\nCallback for Google Play Ads This question wasn’t answered as much as pointed in a better direction to provide user rewards for ad viewing\nas there is no callback for the Google Play ads.\nRead on stackoverflow…​\nReplacing an image in generated Android source code Codename One doesn’t store images into the standard Android DPI hierarchy as you might have multiple res files\nand download them dynamically in your app. You can however, update a specific multi-image entry as explained\nin the answer below.\nRead on stackoverflow…​\nApp walkthrough/tutorial when first open This is a feature we should probably refresh in Codename One and maybe add in one of the demos. The old code\nused the glass pane but it predated the existence of the layered pane which should help significantly. We’ll keep\nthat in mind as we are reviewing the demos.\nRead on stackoverflow…​\nDate Time Picker issue Picker is implemented natively on the device. The DateTime picker is a platform specific concept in iOS. Every\ntime I need to deal with the Picker class\nI’m reminded on how good we have it thanks to lightweight architecture.\nRead on stackoverflow…​\nSet path to look for java.exe in the intellij codename plugin This is a weird IntelliJ IDEA behavior, some oddities still exist in the plugin for IntelliJ in part because the rewrite\nis so new and in part because of our restrictions to project structure.\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-v/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-v/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIt has been a very busy week around here with a lot going on. We’ve just sent out the Friday release update\u003cbr\u003e\nand we are gearing up for some other interesting things…​ These weekly question posts are really convenient\u003cbr\u003e\nas they help us center on what’s truly important – user support.\u003c/p\u003e\n\u003cp\u003eWe had a lot of great questions on stack overflow this week:\u003c/p\u003e\n\u003ch3 id=\"saving-files-in-codenameone\"\u003eSaving Files in CodenameOne\u003c/h3\u003e\n\u003cp\u003eFile systems on mobile are really complex/limited beasts, this often hits desktop developers hard when they\u003cbr\u003e\ntry to figure out how to adapt desktop paradigms like file pickers etc.\u003c/p\u003e","title":"Questions of the Week V"},{"content":"\nLast time around we compared Codename One to QT and this\ntime around I’d like to compare Codename One to the 800 pound gorilla: Xamarin. Xamarin is an amazing product\nthat I contrasted with Codename One in the past\nbut this is worth repeating.\nOn it’s surface Xamarin might seem like a similar tool to Codename One using C# used instead of Java, but this\nis misleading as the tools are so different conceptually they have very little in common.\n__ We updated this comparison after the initial publication to include the additional Property Cross section Background Xamarin was founded by Nat Friedman and Miguel de Icaza famous for the GNOME desktop environment,\nMono and Ximian.\nXamarin launched in 2011, during those years xcode was a very primitive IDE. It didn’t have ARC and had quite\na few problems. Xamarin offered the ability to write native iOS apps in C# with garbage collection and the other\ngreat features allowed by C#.\nXamarin didn’t abstract the API much at the time and effectively provided mappings between C# and native\nAPI calls. It also produced a similar version for Android which did the same. In that sense Xamarin eschewed\nthe write once run anywhere mantra in favor of a common set of business logic coupled with separate UI/native\ncode/resources.\n__ | When we say \u0026ldquo;native code\u0026rdquo; in the Xamarin context that usually means C# code that uses the native OS API,\nthe Codename One context of native code refers to actual OS native languages e.g. Objective-C on iOS As the company grew it built the Xamarin Forms solution on top of the existing infrastructure which provides\nsomething closer to write once run anywhere. Since native widgets were used for Xamarin Forms this posed\na problem as there are inherent insurmountable differences between the iOS/Android widget API’s.\nMicrosoft Purchase Xamarin was purchased by Microsoft in February 2016 and integrated into visual studio. Most of\nit’s products were open sourced as part of this purchase.\nAt a Glance Category Xamarin Codename One Language C# Java IDE Visual Studio/Xamarin Studio NetBeans, Eclipse or IntelliJ IDEA Cloud Build No (requires Mac \u0026amp; Windows for full OS support) Yes (can work on Linux for iOS development) Web Deployment No Yes Widgets Heavyweight Lightweight Portability Strategy Cross platform, sub projects WORA + Native Interfaces (one project) __ | Xamarin requires a Mac for the iOS native app but you can develop on a Windows machine and have a Mac\nmachine in your office to which Xamarin will connect to do the actual native work In Detail Language \u0026amp; IDE I’m not a fan of C# or visual studio but C# is a decent language as is Java especially with version 8. Since both\nlanguages have similar core concepts the differences come down to personal taste more than anything.\nThe same is true for Visual Studio vs. any of the popular Java IDEs (Eclipse, IntelliJ \u0026amp; NetBeans). These are all\nmature, powerful IDE’s that include anything you might need.\nNative Language While as a language C# might be a decent option, it is an alien to the two leading mobile platforms.\nAndroid’s \u0026ldquo;native\u0026rdquo; language is Java. The UI widgets in Android are implemented in Java, which effectively means\nthat if you write code in C it will perform slower than Java code as it would need to pass thru JNI. C#\ncode can’t be implemented on top of the current Android VM and effectively needs to pass thru JNI\nback and forth repeatedly.\nThis overhead is very noticeable when working with heavyweight widgets as the communication between the widget\nand the logic needs to be very frequent. In that sense C# is less native than Codename One which is just implemented\ndirectly on top of the native layer.\nOn iOS the story is different, Xamarin implements the whole toolchain effectively hiding Apples tools\ncompletely. This is a very powerful abstraction but it sometimes creates another layer of complexity. E.g. when\nApple introduces a new idea such as bitcode or a new profiling tool Xamarin can’t fully leverage such a tool. It has\nit’s own set of tools but they will always be second class citizens on Apples platform.\nCodename One uses the open source ParparVM\nto translate Java bytecode to a native C xcode project on Mac OS. This effectively creates a native iOS project\nand allows you to write native Objective-C code write into that project. In a sense this is \u0026ldquo;more native\u0026quot;as it ends\nup using a greater portion of the \u0026ldquo;officially supported toolchain\u0026rdquo;.\nXamarin isn’t needed on Windows as Microsofts native tools can be used to provide portability to that platform, there\nMicrosoft is the true native leader by definition.\nCloud Build Codename One’s cloud build capability is unique. It allows developers to build a native application using the\nCodename One cloud servers (Macs for iOS, Windows machines for Windows etc.) This removes the need to\nown dedicated hardware and allows you to build native iOS apps from Windows and native Windows apps\nfrom your Mac or Linux machine.\nThis makes the installation of Codename One trivial, a single plugin to install. This isn’t true for development\nenvironments that don’t use that approach.\nXamarin is far more \u0026ldquo;low level\u0026rdquo; than Codename One. Xamarin assumes you have deep platform knowledge e.g.\nyou have to understand the Android activity API and lifecycle in order to build a Xamarin Android app. You need\nto understand the ViewController to build a Xamarin iOS app. You don’t need\nto understand either one of those in order to build a Codename One application.\nBoth platforms allow access to the underlying native code with a different underlying philosophy as explained below.\n__ | Knowledge of the native platform is less essential with Xamarin Forms but is still expected and deemed as\nan advantage by the Xamarin team. This highlights the core conceptual/philosophical differences between the platforms Web Deployment Xamarin supports almost all of Codename One’s supported platforms either directly or thru Microsofts Visual\nStudio tools. However, it doesn’t support building native JavaScript web applications.\nCodename One supports the process of compiling an application (threads and all) into a JavaScript application\nthat can be hosted on the web. This is done by statically translating the Java bytecode to JavaScript obfuscated\ncode.\n__ | There are some early stage efforts to bring XAML to JavaScript but none are at a mature stage of supporting\ncomplex notions like threads Widgets This is probably the biggest difference between Xamarin and Codename One.\nXamarin exposes the underlying UI API completely to the developer. This is exposed so completely that a developer\ncan literally use the native iOS/Android visual design tools to build layouts (that naturally won’t be portable).\nCodename One uses a lightweight widget approach where it draws the component hierarchy but allows embedding\nof native widgets for specific requirements (HTML, media, text etc.) this. The difference between these two approaches\nis highly documented and has been debated since the days of smalltalk (think Swing vs. SWT/AWT).\nHeavyweight architecture is closer to the way the native OS behaves and as a result is inherently less portable\nand not as flexible. This is a tradeoff that some developers are willing to accept in order to be \u0026ldquo;more native\u0026rdquo;.\nHeavyweight is sometimes deemed \u0026ldquo;faster\u0026rdquo; by its proponents but the technological basis for such claims is flawed as\nthese widgets are harder to measure realistically across platforms and optimize properly.\nXamarin Forms Xamarin also supports Xamarin Forms which uses XAML to allow sharing most UI code between various platforms\nby picking the lowest common denominator approach to the UI. Unlike Codename One the Xamarin Forms approach\nstill uses native code and assumes some native access.\nIt isn’t designed as a complete WORA (Write Once Run Anywhere) solution but rather as a middle ground solution.\nNotice that with Xamarin Forms you will not be able to use some native OS capabilities such as the native OS\nGUI builders for obvious reasons.\nPortability Strategy Codename One uses a single project that works everywhere. When you need access to native code this native\ncode is hidden by the native interfaces abstraction that allow that single project to remain \u0026ldquo;clean\u0026rdquo; of native code.\nBy default no native code of any type is necessary to build a Codename One application.\nXamarin requires a \u0026ldquo;pseudo native\u0026rdquo; project (still written in C#) to represent the lifecycle, resources and other elements\nof the various supported platforms. By default this will include a lot of the platform specific code such as UI etc.\nwith the exception of Forms apps where there will be less code in the separate projects.\nThese might seem like small differences but they hide a major core difference. Codename One tries to abstract the\naspect of platform native differences and Xamarin pushes it to the forefront.\nMicrosoft A big selling point for Xamarin is the Microsoft acquisition positioning it as a major player backed by the full weight\nof Microsoft. Microsoft has repeatedly abandoned technologies in which they invested a great deal of money\ne.g. Windows Phone 7, Silverlight etc. It also demonstrated this recently by discarding RoboVM without the\ncurtesy of opening its source code.\nXamarin is free in order to gain traction and serve Microsofts market goals. As long as those goals align with\nthe goals of developers using Xamarin this is a good thing. However, since this is a market MS competes in\nit is not an impartial player.\nNo one can tell at this time whether the purchase will have a negative effect on the future development of Xamarin.\nSo far the Microsoft purchase has been largely a positive thing with the exception of the RoboVM issue.\nProperty Cross Comparison The PropertyCross demo was built as a tool that allows us to compare two cross platform frameworks, as such\nthere are versions of the demo for many such platforms. You can check out details of the Codename One\nimplementation here. The github repository for this demo\nis here.\nXamarin has two cross platform implementations for property cross a\nregular app and a\nmvvm version.\nBoth don’t use Xamarin Forms which is a shame since it would probably be closer to what we offer with Codename\nOne but it’s still a good overview of the differences.\nLines of code are a pretty bad measurement of the overall quality of a framework, however having said that they\ndo provide some indication of the verbosity and Xamarin is far more verbose than Codename One. E.g.\nlooking at the\nMVVM model implementation alone\nwe can see that it has more lines of code than the entire Codename One implementation!\nThe Xamarin implementations are really 4 implementations for iOS, Android, Windows Phone \u0026amp; a portable common\nproject. This effectively means that the Xamarin implementation requires a deep understanding of the native platforms\nsince it’s in essence native programming.\n__ | The Xamarin Forms implementation would still require such a structure although a greater portion of the code\nwould reside in the common project This also means you will need to either use the iOS tools to build a UI or deal with the screenshots, icon resolutions\n\u0026amp; DPI changes for the various device types. E.g. on iOS you would need images using the @ notation but on\nAndroid you will need to divide the images to the DPI directories creating a lot of work on resource maintenence\nwhich just doesn’t exist in Codename One.\nIn that sense PropertyCross is probably a poor demo as it doesn’t contain many resources that need maintenence.\nFinal Word As usual our opinions are biased but I think we presented a reasonably fair evaluation. Xamarin is an\nimpressive tool that is quite different inherently from Codename One \u0026amp; we hope we highlighted those\ndifferences fairly.\nIf you are looking to write a native application you like C# \u0026amp; don’t mind dealing with platform differences it is a\ncompelling option. However, if you prefer Java and portability is key I think we have a far more compelling story.\nIf you think we misrepresented Codename One or Xamarin in any way let us know in the comments.\nFeel free to use the comments section for suggestions of future comparison segments. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJ Master — May 13, 2016 at 9:50 am (permalink) J Master says:\nInteresting, less than 300 stars for a github compare to 32,970 developers? Can it be compile to Swift code instead of C?\n120,000,000 is based from which figure?\nShai Almog — May 14, 2016 at 3:19 am (permalink) Shai Almog says:\nWe migrated from Google code at the last possible instance which explains the low star count.\nBy default we include device counting code in builds (this can be disabled) so we composed that number from verified installed which we then correlated to actual appstore installs and to apps/devices where we know this was developed to come up with a composite number. The number is actually much larger by now but we didn’t get around to go thru this process to update it.\nSiva Mamidi — June 2, 2016 at 8:32 pm (permalink) Siva Mamidi says:\nVery nice article and informative.\nBenjamin Hamilton — June 18, 2016 at 1:10 am (permalink) Benjamin Hamilton says:\nFrom your article\nAndroid’s \u0026ldquo;native\u0026rdquo; language is Java. The UI widgets in Android are implemented in Java, which effectively means that if you write code in C it will perform slower than Java code as it would need to pass thru JNI.\nFrom Google\nhttps://developer.android.c…\nJNI is the Java Native Interface. It defines a way for managed code (written in the Java programming language) to interact with native code (written in C/C++). It’s vendor-neutral, has support for loading code from dynamic shared libraries, and while cumbersome at times is reasonably efficient.\nShai Almog — June 18, 2016 at 4:56 am (permalink) Shai Almog says:\nThat’s a common misconception. Check out this article from Chet \u0026amp; Romain two brilliant ex-Sun guys who are very deep in the Android GUI system development: https://realm.io/news/romai…\nCopied from the source article:\nAvoid JNI\nSometimes you need JNI, but not if\nyou’re just using it out of convenience. Something interesting about JNI\ncode: every time you cross the boundary between Java runtime and native\nthere’s a cost because we need to validate the parameters and it has an\nimpact on the GC behaviors. It can be pretty expensive, so when you do a\nlot of JNI calls, you might spend more time in the overhead of JNI than\nin the actual code. If you have old JNI code, you might want to revisit\nit.\nMarcin — July 15, 2016 at 1:28 am (permalink) Marcin says:\nHello Shai, how about the Dependency Injection with Codename One?\nI tried to search for spec, examples or even searched for phrase \u0026ldquo;@Inject\u0026rdquo; through the Github examples.\nIs it possible to decouple code this way?\nAre there any other decoupling methods available like EventBus?\nIt would be also really great to have CDI like producers, I mean annotations @Produces . Also some scopes…\nIs it possible with Codename One?\nAnd finally how about writting testible code with Codename One?\nIt looks like I have to use lot of singletons like Display.getInstance()… or FaceBookAccess.getInstance()…. or static calls like LocationManager.getLocationManager().getCurrentLocation().\nCould I simply inject those instead? Something like @Inject LocationManager?\nSingleton objects definiton could be marked with @Singleton annotation. Unfortunately I don’t see it there (https://goo.gl/UhJDSY)).\nThe reason I wan’t to inject this stuf is that I prefer simple UnitTests over long running Integration Tests.\nRegards,\nMarcin\nShai Almog — July 15, 2016 at 4:00 am (permalink) Shai Almog says:\nHi,\nno we don’t support DI since we don’t support reflection and bytecode manipulation isn’t trivial since it must be done statically with great care. It’s possible to do bytecode manipulation as Steve did with the POJO mapper: http://www.codenameone.com/… but no one did it for DI.\nWe don’t support JUnit etc. so you will need to use our test framework which includes a test recorder etc. I think a lot of the problems solved by DI are server problems and not as pertinent to the front end developer landscape.\nMartin Grajcar — September 9, 2017 at 1:26 am (permalink) Martin Grajcar says:\nDagger 2 uses no reflection at all, so in theory it must work. As this is the only relevant search result for \u0026ldquo;codenameone\u0026rdquo; and \u0026ldquo;dependency injection\u0026rdquo;, I’m afraid that nobody has really tried it yet.\nShai Almog — September 9, 2017 at 7:13 am (permalink) Shai Almog says:\nSteve did POJO mapping which is pretty similar, if you use bytecode manipulation tools it can work but DI isn’t as helpful in mobile client as it is in server code so there wasn’t as much demand.\nIf you try it and run into difficulties just ask on stackoverflow (with the codenameone tag) or in the discussion forum. We’ll try to help.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/comparing-xamarin-and-codename-one/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/comparing-xamarin-and-codename-one/compare-to-xamarin.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eLast time around we compared \u003ca href=\"/blog/comparing-qt-and-codename-one.html\"\u003eCodename One to QT\u003c/a\u003e and this\u003cbr\u003e\ntime around I’d like to compare Codename One to the 800 pound gorilla: Xamarin. Xamarin is an amazing product\u003cbr\u003e\nthat I \u003ca href=\"https://forums.xamarin.com/discussion/55129/comparing-xamarin-to-other-cross-platfrom-frameworks-codename-one?\" target=\"_blank\" rel=\"noopener noreferrer\"\u003econtrasted with Codename One in the past\u003c/a\u003e\u003cbr\u003e\nbut this is worth repeating.\u003c/p\u003e\n\u003cp\u003eOn it’s surface Xamarin might seem like a similar tool to Codename One using C# used instead of Java, but this\u003cbr\u003e\nis misleading as the tools are so different conceptually they have very little in common.\u003c/p\u003e","title":"Comparing Xamarin and Codename One"},{"content":"\nPumpop is a social networking app in the spirit of tinder that is available globally and installed on many devices\nall over the world. One of its major draws is it’s portability which will soon extend to Windows Phone as well.\nPumpop uses social login controls such as native Facebook login as well as email activation.\n__ | If you are in a committed relationship I suggest notifying your spouse that you are \u0026ldquo;just testing this app for work\u0026rdquo;,\nto avoid unpleasantness and suspicion…​ You can see the app featured page here. You can check out the\nios version here and the\nandroid version here.\nChats list\nNearby\nLike Profile\nProfile Details\nContributions One of the things that should be mentioned about the guys from Pumpop is that they \u0026ldquo;walk the walk\u0026rdquo;.\nFabricio of pmovil (the company behind Pumpop) has contributed a great deal of code\nto the Codename One community most of which is shown in their github profile.\nFabricio contributed multiple cn1libs ranging in functionality from native Toast support\nto comscore analytics. But his biggest work has been his\ncustom Windows Phone/UWP port which served as a basis\nfor our newer port!\nThat is gumption in it’s true hacker sense and truly represents the open source spirit we try to foster within\nCodename One. If he hadn’t done all of that work we might not have even started with the UWP port effort\nso if you are looking forward to the new Windows support you have Fabricio and Pmovil to thank for that. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nRoss Taylor — May 12, 2016 at 2:56 pm (permalink) Interesting app. However I noticed an annoying bug though, for example when switching between other apps using the overview button (task switcher) while the chat form is showing, going back to this app again, the message input bar disappears only leaving the typed text visible (tested on android 4.3.1).\nFabrício Cabeça — May 13, 2016 at 1:14 pm (permalink) Thanks Ross for the feedback ! I didn’t find it that annoying but it was marked as a bug to be fixed in the next version.\nRoss Taylor — May 17, 2016 at 10:17 am (permalink) Hi Fabricio, thats great! Also would it be possible to add in paragraph support for typing in the text conversations? That would be nice :). Another lookout point is whether if its possible to make the UI more native looking to the OS (eg material design for Android etc) by sticking to their guidelines, while still preserving the fun. I also noticed a slight flickering in the background when menu actions are accessed and the action list box sometimes get stuck at the bottom when the keyboard is minimized and the screen maximized. Good luck! Looking forward to the next update..Ross.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/featured-app-pumpop/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/featured-app-pumpop/pumpop-landscape.png\"\u003e\u003c/p\u003e\n\u003cp\u003ePumpop is a social networking app in the spirit of tinder that is available globally and installed on many devices\u003cbr\u003e\nall over the world. One of its major draws is it’s portability which will soon extend to Windows Phone as well.\u003c/p\u003e\n\u003cp\u003ePumpop uses social login controls such as native Facebook login as well as email activation.\u003c/p\u003e\n\u003cp\u003e__ |  If you are in a committed relationship I suggest notifying your spouse that you are \u0026ldquo;just testing this app for work\u0026rdquo;,\u003c/p\u003e","title":"Featured App – Pumpop"},{"content":"\nWith the 3.4 release we discussed the process of modernizing the demos and the first one we picked\nfor this task is the camera demo which is probably the easiest one of all the demos…​\nThe demo is trivial and doesn’t really demonstrate anything other than capturing and showing an image captured\nfrom the camera/retrieved from the gallery but this is where it gets interesting. It even works in the\nJavaScript port so you can even run this in the browser and it works as you’d expect!\nNotice that since browsers don’t have anything quite like a \u0026ldquo;gallery\u0026rdquo; that feature won’t be very useful but capture\nworks really well.\nThe Source Check out the full source code for the demo in the\ngithub repository for the CameraDemo notice that\nas we announced yesterday we are\nmoving the demos to separate repositories and will retire the monolithic\ncodenameone-demos repository. This will allow\nus to be more nimble and will also simplify the process of working with these demos.\nThis demo will be integrated into the upcoming new project wizards in the various IDEs. This plays into the\nmove to Java 8 in the plugins which we also announced yesterday.\nMoving Forward There are many demos in the codenameone-demos\nrepository and some outside of it. Most of them are out of date and \u0026ldquo;abandoned\u0026rdquo; we’ll try to make this a weekly\nsegment of moving demos to the newer API’s and refining them. Some of these demos will take more effort (e.g Kitchen Sink)\nbut others should be simpler.\nIdeally all demos should be included in the IDE plugins and should be accessible by everyone easily.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/camera-demo/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/camera-demo/camera-demo-blog.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWith the 3.4 release we discussed the process of modernizing the demos and the first one we picked\u003cbr\u003e\nfor this task is the \u003ca href=\"/camera-demo/\"\u003ecamera demo\u003c/a\u003e which is probably the easiest one of all the demos…​\u003cbr\u003e\nThe demo is trivial and doesn’t really demonstrate anything other than capturing and showing an image captured\u003cbr\u003e\nfrom the camera/retrieved from the gallery but this is where it gets interesting. It even works in the\u003cbr\u003e\nJavaScript port so you can even \u003ca href=\"/demos/CameraDemo/\"\u003erun this in the browser and it works as you’d expect\u003c/a\u003e!\u003c/p\u003e","title":"Camera Demo"},{"content":"\nWith the 3.4 release we discussed the process of modernizing the demos and also mention that we would\ncontinue the trend of building Codename One on top of itself. We now have a rough outline of what we are\ngoing to do possibly starting with the next plugin update.\nJava 8 Switch New builds will use Java 8 by default for all projects. In the past we needed you to define the build hint\njava.version=8 and if you left it out we defaulted to java.version=5.\nWith the this will now be the exact opposite where the default will assume Java 8 unless you are using\nversioned builds.\nThis is a part of a wider switch that we will carry into the IDE plugin and into the Codename One libraries.\nThe Codename One plugins will require Java 8 to install starting with the next update, we’re not sure if there\nis a way to enforce this with the IDE dependencies but we will start assuming that Java 8\nNew Preferences UI One of the hard things about maintaining the plugin for 3 platforms is the preferences UI which we need to\nupdate across all platforms. With new changes coming up to the Windows UWP build we will need to make\nchanges to the preferences and carrying them to all IDE’s might be challenging.\nSo we are focusing around one UI which is the one we introduced with the IntelliJ IDEA plugin.\nThis UI is written in Codename One and solves a lot of bugs in the old preferences UI’s both in Eclipse \u0026amp; NetBeans.\nFigure 1. Preferences UI written in Codename One\nThis will allow us to map functionality to UI preferences more smoothly as we move Codename One forward.\nOld Preferences For now we won’t remove the old preferences UI as the new interface might still be unstable. However, we will\npost a notice that the UI is deprecated and will remove it in a future iteration.\nYou will find the new preferences option under the Codename One section in an upcoming plugin update.\nNew Demo Structure We decided to move the demos to separate repositories and retire the monolithic\ncodenameone-demos repository.\nThis will allow us to be more nimble and will also simplify the process of working with these demos.\nWe will recreate the individual demos one by one in separate repositories and integrate them into the\nnew plugin implementation. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMaaike Z — May 10, 2016 at 9:07 am (permalink) Can we also use the Java 8 Date/Time functions or is this just for running the plugin etc?\nShai Almog — May 11, 2016 at 5:40 am (permalink) Shai Almog says:\nNo. This applies to the plugin and the default behavior which uses the current Java 8 retrolambda based support.\nThere is an open source implementation of JSR 310 (date time) which we could possibly add (I already filed an RFE on that a while back) but I’m not sure how practical it is to add that.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/java-8-switch-new-preferences-demo-structure/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/java-8-switch-new-preferences-demo-structure/java-8-lambada.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWith the 3.4 release we discussed the process of modernizing the demos and also mention that we would\u003cbr\u003e\ncontinue the trend of building Codename One on top of itself. We now have a rough outline of what we are\u003cbr\u003e\ngoing to do possibly starting with the next plugin update.\u003c/p\u003e\n\u003ch3 id=\"java-8-switch\"\u003eJava 8 Switch\u003c/h3\u003e\n\u003cp\u003eNew builds will use Java 8 by default for all projects. In the past we needed you to define the build hint\u003cbr\u003e\n\u003ccode\u003ejava.version=8\u003c/code\u003e and if you left it out we defaulted to \u003ccode\u003ejava.version=5\u003c/code\u003e.\u003c/p\u003e","title":"Java 8 Switch, New Preferences \u0026 Demo Structure"},{"content":"\nUp until Marshmallow (version 6) Android used a rather obtuse permission system that very few end users understood.\nWith API level 23 (Marshmallow) Android finally shifted to a structure that makes more sense similarly to iOS.\nMarshmallow asks a users permission the first time an API is used e.g. when accessing contacts the user will\nreceive a prompt whether to allow contacts access.\n__ Permission can be denied and a user can later on revoke/grant a permission via external settings UI This is really great as it allows apps to be installed with a single click and no permission prompt during install\nwhich can increase conversion rates!\nThe Transition Starting today all compilations will be done with SDK level 23 but not with target level 23!\nThis means that by default the new permission mode is still off and you won’t see any of the effects mentioned below.\nWe will probably change this to be the default in the future but at the moment the target SDK defaults to 21. To\nactivate this functionality you will need to set the target SDK to level 23 by using the\nbuild hint\nandroid.targetSDKVersion=23.\nHow Does This Look? To test this API I’ve created a simple contacts app:\nForm f = new Form(\u0026quot;Contacts\u0026quot;, BoxLayout.y()); f.add(new InfiniteProgress()); Display.getInstance().invokeAndBlock(() -\u0026gt; { Contact[] ct = Display.getInstance().getAllContacts(true, true, false, true, true, false); Display.getInstance().callSerially(() -\u0026gt; { f.removeAll(); for(Contact c : ct) { MultiButton mb = new MultiButton(c.getDisplayName()); mb.setTextLine2(c.getPrimaryPhoneNumber()); f.add(mb); } f.revalidate(); }); }); f.show(); When I try to install it without changing anything on my Android 6 OPO device I see this UI:\nFigure 1. Install UI when using the old permissions system\nWhen I set android.targetSDKVersion=23 in the build hints and try to install again the UI looks like this:\nFigure 2. Install UI when using the new permissions system\nWhen I launch the UI under the old permissions system I got to the contacts instantly in the new system I’m presented\nwith this UI:\nFigure 3. Native permission prompt first time\nIf I accept and allow all is good and the app loads as usual but if I deny then Codename One gives the user another\nchance to request the permission. Notice that in this case you can customize the prompt string as explained\nbelow.\nFigure 4. Codename One permission prompt\nIf I would select don’t ask then I will get a blank screen since the contacts will return as a 0 length array. This makes\nsense as the user is aware he denied permission and the app will still function as expected on a device where\nno contacts are available. However, if the user realizes his mistake he can double back and ask to re-prompt for\npermission in which case he will see this native prompt:\nFigure 5. Native permission prompt second time\nNotice that denying this second request will not trigger another Codename One prompt.\nCode Changes For native Android developers this transition was painful requiring developers to rewrite API access with\ncallbacks to respect the cases where permission is denied or revoked. When adding the support to Codename\nOne we chose to make this as seamless as we always strived to be. The respective API’s will work just like they\nalways worked and will prompt the user seamlessly for permissions.\n__ | Some behaviors that never occurred on Android but were perfectly legal in the past might start occurring with\nthe switch to the new API. E.g. the location manager might be null and your app must always be ready to deal\nwith such a situation When permission is requested a user will be seamlessly prompted/warned, we have builtin text to control such\nprompts but you might want to customize the text. You can customize permission text via the Display properties\ne.g. to customize the text of the contacts permission we can do something such as:\nDisplay.getInstance().setProperty(\u0026quot;android.permission.READ_CONTACTS\u0026quot;, \u0026quot;MyCoolChatApp needs access to your contacts so we can show you which of your friends already have MyCoolChatApp installed\u0026quot;); This is optional as there is a default value defined. You can define this once in the init(Object) method but for some\nextreme cases permission might be needed for different things e.g. you might ask for this permission with one reason\nat one point in the app and with a different reason at another point in the app.\nThe following permission keys are supported: \u0026ldquo;android.permission.READ_PHONE_STATE\u0026rdquo;\nandroid.permission.WRITE_EXTERNAL_STORAGE,\nandroid.permission.ACCESS_FINE_LOCATION,\nandroid.permission.SEND_SMS,\nandroid.permission.READ_CONTACTS,\nandroid.permission.WRITE_CONTACTS,\nandroid.permission.RECORD_AUDIO.\nShould you Switch? We suggest you test target level 23 with your app and see how it performs. Verify that nothing breaks and that\nthe app maintains usability.\n__ You will need a Marshmallow level device to test this properly as the app will look the same on older devices Testing this is crucial as we would flip the switch to make this the default in the near future. The timing when\nthis is switched on might not be as convenient as trying this option now. Due to the way Android works it is very\npossible that Google will promote target level 23 apps more aggressively to encourage developers to update\ntheir apps so it is prudent to update now rather than later.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/switching-on-android-marshmallow-permission-prompts/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/switching-on-android-marshmallow-permission-prompts/marshmallow.png\"\u003e\u003c/p\u003e\n\u003cp\u003eUp until Marshmallow (version 6) Android used a rather obtuse permission system that very few end users understood.\u003cbr\u003e\nWith API level 23 (Marshmallow) Android finally shifted to a structure that makes more sense similarly to iOS.\u003cbr\u003e\nMarshmallow asks a users permission the first time an API is used e.g. when accessing contacts the user will\u003cbr\u003e\nreceive a prompt whether to allow contacts access.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003ePermission can be denied and a user can later on revoke/grant a permission via external settings UI\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eThis is really great as it allows apps to be installed with a single click and no permission prompt during install\u003cbr\u003e\nwhich can increase conversion rates!\u003c/p\u003e","title":"Switching on Android Marshmallow Permission Prompts"},{"content":"\nI’d like to open this weeks post by covering some things we do and try to avoid on stackoverflow. I try to upvote\nyour questions/answers whenever I can and most of us should upvote questions that are decent especially\nfrom a person who has low ranking and might not have the stack overflow experience to phrase their question\nproperly.\nPoints in stackoverflow are important as they provide you with more capabilities and allow you to place bounties\non questions that need assistance. In that regard it’s important that if you ask a question and get the right answer\nyou should accept that answer, this provides points both to you and to the person who asked it.\n__ | When a person answered a question before me and gave an incomplete answer I try to edit his question\ninstead of posting my own answer. I have enough points and I’d rather that person who did most of the effort\nwill get the points This week saw a lot of interesting questions and activity on stack overflow:\nHow to make Multilist conponent allow only one item selected? Manipulating the MultiList programmatically isn’t always intuitive but it’s possible.\nRead on stackoverflow…​\nToolbar components Normally you shouldn’t change the Toolbar\ndirectly as this relies on some internal implementation details that might change.\nRead on stackoverflow…​\nGenerate SHA1 hash function This question is probably more valuable for the question than the answer. Signing \u0026amp; encryption code samples\nare sorely missing and that question contains a great sample of using SHA1. This is something we need to improve\nin our docs moving forward and intend to…​\nRead on stackoverflow…​\nScreen shrinkage This question was marked as a duplicate which happens occasionally, it does ask a very common question though\nwhich always warrants a reminder. When you edit a text field on Android the screen resizes to allow space for\nthe virtual keyboard, this is different from the iOS interpretation of this functionality…​\nRead on stackoverflow…​\nOpen app installation page in AppStore or PlayStore Asks a very common question about sharing your app.\nRead on stackoverflow…​\nWhy doesn’t my TableLayout center my components? The defualt behavior of table layout works with preferred/available size and might not take up all available space.\nRead on stackoverflow…​\nEnabling TLS 1.2 on Codename one App for Android 4.0.X , 4.1.X and 4.2.X Some questions can only be answered with a \u0026ldquo;you will need to implement this natively\u0026rdquo; although this specific\nnative implementation looks like one line of code…​\nRead on stackoverflow…​\nUpload to Cloudinary using REST API in CN1 Steve’s cloudinary library\nhas picked up some followers, here is a question answered the guys at Cloudinary\ncovering image upload.\nRead on stackoverflow…​\nAndroid push notifications not registering for push Sometimes an answer just needs to be a visual aid…​\nRead on stackoverflow…​\nTime Picker doesn’t render correctly in landscape This is an issue I can’t reproduce and I didn’t hear further from the guy who submitted it. However, to get a sense\nof the amount of work I do check out the second screenshot from my Android device. Notice I have two mailboxes\nand their unread count is apparent…​\nI don’t mind this being public information but I just noticed it now and it was unintentional, make sure to check\nyour screenshots well before submitting as they might include stuff like that.\nRead on stackoverflow…​\nList scrollbar questions We don’t have scrollbars but they are actually quite easy to add if you want to, a while back we\nwrote about building a scrollbar and\nI mentioned that link in this response.\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-iv/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-iv/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’d like to open this weeks post by covering some things we do and try to avoid on stackoverflow. I try to upvote\u003cbr\u003e\nyour questions/answers whenever I can and most of us should upvote questions that are decent especially\u003cbr\u003e\nfrom a person who has low ranking and might not have the stack overflow experience to phrase their question\u003cbr\u003e\nproperly.\u003c/p\u003e\n\u003cp\u003ePoints in stackoverflow are important as they provide you with more capabilities and allow you to place bounties\u003cbr\u003e\non questions that need assistance. In that regard it’s important that if you ask a question and get the right answer\u003cbr\u003e\nyou should accept that answer, this provides points both to you and to the person who asked it.\u003c/p\u003e","title":"Questions of the Week IV"},{"content":"\nThe NetBeans plugins.netbeans.org site has been down for another weekend and\nhas been down again today. This isn’t ideal as we like the convenience the official plugin center affords in our\nupdate process. However, this blocks installs and updates of our plugin most of which originate from NetBeans.\nAs a workaround we decided to relaunch our own update center which we will manually update with each plugin\nto allow you to install the plugin even when NetBeans is down. The URL for this update center is\nhttps://www.codenameone.com/files/netbeans/updates.xml\nSetting Up The New Update Center Figure 1. Select Tools → Plugins in the menu\nFigure 2. Select the Settings tab and click Add\nFigure 3. Type in Codename One as the name and enter the update center URL https://www.codenameone.com/files/netbeans/updates.xml\nFigure 4. You can now proceed to install Codename One just like in the getting started video\nShould I Use This or The Update Center? We prefer you use the update center from NetBeans. We think having one official source for plugins is convenient\nand the fact that the install process is simpler (just type codename) is a huge plus. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMohasin — June 14, 2016 at 2:51 pm (permalink) I have followed the procedure and i am not getting CodenameOne listen in available plugins. I tested the connections and tried again. It didnt work for me\nShai Almog — June 15, 2016 at 4:00 am (permalink) I’m not sure what is the issue but you can download the nbm directly from https://www.codenameone.com…\nlinnet maruve — June 18, 2018 at 2:10 pm (permalink) how can l update my netbeans plugin. when ever l run my project it writes it seems like you are using an old version l have tried the procedure but l can not find a way to update it\nShai Almog — June 19, 2018 at 5:11 am (permalink) The latest version of the plugin is 4.0. Codename One Settings includes its own update system under Basic -\u0026gt; Update Client Libs.\nlinnet maruve — June 19, 2018 at 6:39 am (permalink) linnet maruve says:\nthat is the one l downloaded but its still saying its an old version of codenameone whenever l execute a program\nlinnet maruve — June 19, 2018 at 9:58 am (permalink) linnet maruve says:\nhttps://uploads.disquscdn.c…\nShai Almog — June 20, 2018 at 4:15 am (permalink) Shai Almog says:\nOnce you send a build for the first time or update via Codename One Settings this message will go away.\nlinnet maruve — June 20, 2018 at 6:48 am (permalink) linnet maruve says:\nl have tried to update it but its not working\nShai Almog — June 21, 2018 at 6:07 am (permalink) Shai Almog says:\nWhat’s the error message you get when you update?\nlinnet maruve — June 21, 2018 at 2:14 pm (permalink) linnet maruve says:\nhttps://uploads.disquscdn.c… https://uploads.disquscdn.c…\nlinnet maruve — June 21, 2018 at 2:15 pm (permalink) linnet maruve says:\nwhen click update project libs where l have highlighted the written words on the button will only turn grey and nothing ever happens\nShai Almog — June 22, 2018 at 7:30 pm (permalink) Shai Almog says:\nTry running this from command line to see if there are errors printed there when you try to update. Are you running possibly as a user without administrator privilege?\nTo do this do something such as:\njava -jar path-to-your-user-directory.codenameoneguibuilder.jar -settings path-to-cn1-projectcodenameone_settings.proper…\nlinnet maruve — June 25, 2018 at 1:42 pm (permalink) linnet maruve says:\nhttps://uploads.disquscdn.c… https://uploads.disquscdn.c…\nlinnet maruve — June 25, 2018 at 1:44 pm (permalink) linnet maruve says:\nl have updated using cmd but its still not updated\nShai Almog — June 26, 2018 at 9:02 am (permalink) Shai Almog says:\nIt should popup another dialog when downloading the update. Your image is cropped so I can’t see the version of Codename One Settings. Its version should be 4.2. If it isn’t that’s the problem.\nlinnet maruve — June 26, 2018 at 9:07 am (permalink) linnet maruve says:\nthere is only version 4 on the update there is no version 4.2\nlinnet maruve — June 26, 2018 at 9:11 am (permalink) linnet maruve says:\nthose uploads\nlinnet maruve — June 26, 2018 at 9:35 am (permalink) linnet maruve says:\nhow can l make it 4.2 its only showing 4\nShai Almog — June 27, 2018 at 5:41 am (permalink) Shai Almog says:\nThe plugin version is 4.0. The version of Codename One Settings should update after you do an update client libs to 4.2.\nlinnet maruve — June 27, 2018 at 10:15 am (permalink) linnet maruve says:\nwhen l go to basics it shows update project libs there is no update client libs. where can find that client libs\nShai Almog — June 28, 2018 at 6:09 am (permalink) Shai Almog says:\nProject libs. This went through renames a couple of times I don’t recall the latest name.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/netbeans-plugin-update-center/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/netbeans-plugin-update-center/hello-codenameone-revisited.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe NetBeans \u003ca href=\"http://plugins.netbeans.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eplugins.netbeans.org\u003c/a\u003e site has been down for another weekend and\u003cbr\u003e\nhas been down again today. This isn’t ideal as we like the convenience the official plugin center affords in our\u003cbr\u003e\nupdate process. However, this blocks installs and updates of our plugin most of which originate from NetBeans.\u003c/p\u003e\n\u003cp\u003eAs a workaround we decided to relaunch our own update center which we will manually update with each plugin\u003cbr\u003e\nto allow you to install the plugin even when NetBeans is down. The URL for this update center is\u003cbr\u003e\n\u003ca href=\"https://www.codenameone.com/files/netbeans/updates.xml\"\u003ehttps://www.codenameone.com/files/netbeans/updates.xml\u003c/a\u003e\u003c/p\u003e","title":"NetBeans Plugin Update Center"},{"content":"\nFor years we treated support with a \u0026ldquo;we’ll meet our developers where they are\u0026rdquo; attitude which is problematic\nnow that we have more than 6 free support channels!\nNotice that we didn’t include the email/phone support for pro/enterprise users in the list of 6 channels…​\nWe try to respond to every query within 24 hours in stack overflow and the discussion group:\nStackOverflow – please try asking any technical question here.\nWe know it’s sometimes challenging but the payout is great as the site is very searchable and provides a\ntreasure trove of Codename One information thanks to your questions!\nGithub issue tracker – If you are new to Codename One I would\nsuggest asking in the discussion group first and reading the blog post linked here\nThis blog – the comments section in the blog posts and even in the developer guide is a\ngood place for questions relevant to a specific entry\nDiscussion Group – Our venerable Google group isn’t an ideal tool but it works as\na last resort. We prefer stack overflow but we still provide support there\nIntercom – You can chat with our moderately technical support team live by clicking the chat button at the bottom\nright side of the screen. If you have problems with the site, your account or similar issues/requests please send\nthem thru there. Notice that it’s not a good place for technical questions about programming e.g. \u0026ldquo;how\ndo I do X\u0026rdquo; in Codename One\nFacebook, Twitter \u0026amp;\nLinkedIn – While you can ask some things in these channels\nthe structure of the response makes it very hard to answer. We occasionally get questions on twitter and fitting the\nanswer into a tweet is impractical. LinkedIn recently updated the group interface and\nour group on LinkedIn might become more active but currently\nit doesn’t see much interaction\n__ | Often Googling things like Codename One followed by your question would produce answers, you can\nalso search stack overflows codenameone tag by prefixing your query with the tag in brackets e.g. [codenameone] my search query What you Shouldn’t Do Please don’t send us personal emails.\nThe reason we provide free support is to help the community as a whole. When you send us a personal email\nyou are undermining that.\n__ Since pro \u0026amp; enterprise users effectively subsidize our free version one of the benefits they get is private support Please don’t post/send attachments that aren’t images: APK’s, IAP’s or whole projects. We can’t really run these\napps as our devices aren’t jailbroken, even if they were it probably wouldn’t tell us much…​\nIt’s hard dealing with all of these projects, in the past we used to let pro users send us their project sources but\neven this is now impractical as our community grew larger.\nIf you need to send us a test case you should do this thru git as explained here.\n__ | Please keep in mind that what you see in terms of our support is the tip of the iceberg. Besides dealing with all\nof these channels we spend a great deal of support resources on pro/enterprise \u0026amp; corporate accounts. So if our\nresponses are brief or hasty it’s due to the work overload What about Pro Support? Pro developers also have the ability to send private support email.\nSome pro developers started submitting their questions to stack overflow and just sending us a support email\nwith a link to the question. This is great as we can answer the question quickly but still provide the community\nwith information that might be important to other developers.\nIf you can do that as a pro/enterprise developer that’s great but it’s not required.\nPlease Ask for Help This is a bit of a long post so it might be intimidating to some but that is not it’s goal!\nWe want to help as much as we can which is why we have so many open channels and we understand that this\nmight be confusing.\nDon’t be afraid to ask in the wrong place!\nAt most we’ll just refer you to the right location for your question.\nWe think support is the most important thing we can do as a company and I hope that’s the message that we\nare getting thru. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAquila CodenameOne — July 19, 2016 at 1:13 pm (permalink) Aquila CodenameOne says:\nfor orientation I am using orientation-listener in my app and also put Logger code in orientation-listener some time orientation listener is not called when I rotate screen in my android tablet\nShai Almog — July 20, 2016 at 4:31 am (permalink) Shai Almog says:\nAs the article above states, these things should be asked in StackOverflow or in a relevant blog post or in the discussion forum. I see you did the former which is great: http://stackoverflow.com/qu…\nmadhu thestudent — August 19, 2016 at 9:10 am (permalink) madhu thestudent says:\nMy applicaiton need to show the notifications,So i used localnotification in codename one.But it supports only for android mobiles not for tablets,what should i do to support for tablets also?\nmadhu thestudent — August 19, 2016 at 9:15 am (permalink) madhu thestudent says:\ncan you please tell ,from which version of android tablets does the codename one notification support .\nShai Almog — August 20, 2016 at 4:21 am (permalink) Shai Almog says:\nThis isn’t a generic question and answer section. Please read the above article…\nI’m guessing you don’t have an Android tablet. You probably have a Kindle or some other clone without Google Play services. Some features aren’t available when that is missing.\nPeter Hric — September 5, 2016 at 2:43 pm (permalink) Peter Hric says:\nHi, Can I change and use the template project with Leather theme and Tab Application template ?\nCuz the GUI builder just does not let me change anything 🙁\nlooks like its locked\nI have learned many important informations from your chat-support, but they could not definitely state how to edit those sample app themes.\nMany thanx in advance !\nShai Almog — September 6, 2016 at 3:53 am (permalink) Shai Almog says:\nYes, this should work fine. You won’t be able to delete elements that are currently being used.\nOther than that everything should work fine.\nEmmanuel Njoku — September 22, 2016 at 7:51 pm (permalink) Emmanuel Njoku says:\nThis is an error:\njava.net.URISyntaxException: Illegal character in path at index 9: showForm(\u0026ldquo;Main\u0026rdquo;, null)\nat java.net.URI$[Parser.fail](http://Parser.fail)([URI.java](http://URI.java):2848)\nat java.net.URI$Parser.checkChars(URI.java:3021)\nat java.net.URI$Parser.parseHierarchical(URI.java:3105)\nat java.net.URI$Parser.parse(URI.java:3063)\nat java.net.URI.(URI.java:588)\nat com.codename1.impl.javase.JavaSEPort.execute(JavaSEPort.java:5630)\nat com.codename1.ui.Display.execute(Display.java:2858)\nat com.codename1.ui.util.UIBuilder$FormListener.actionPerformed(UIBuilder.java:2854)\nat com.codename1.ui.util.EventDispatcher.fireActionEvent(EventDispatcher.java:349)\nat com.codename1.ui.Form.actionCommandImplNoRecurseComponent(Form.java:1593)\nat com.codename1.ui.Button.fireActionEvent(Button.java:407)\nat com.codename1.ui.Button.released(Button.java:442)\nat com.codename1.ui.Button.pointerReleased(Button.java:530)\nat com.codename1.ui.Form.pointerReleased(Form.java:2623)\nat com.codename1.ui.Form.pointerReleased(Form.java:2559)\nat com.codename1.ui.Component.pointerReleased(Component.java:3223)\nat com.codename1.ui.Display.handleEvent(Display.java:2022)\nat com.codename1.ui.Display.edtLoopImpl(Display.java:1067)\nat com.codename1.ui.Display.mainEDTLoop(Display.java:996)\nat [com.codename1.ui.RunnableWr…](http://com.codename1.ui.RunnableWrapper.run)([RunnableWrapper.java](http://RunnableWrapper.java):120)\nat [com.codename1.impl.Codename…](http://com.codename1.impl.CodenameOneThread.run)([CodenameOneThread.java](http://CodenameOneThread.java):176)\nShai Almog — September 23, 2016 at 4:35 am (permalink) Shai Almog says:\nIt looks like you set the \u0026ldquo;execute\u0026rdquo; value in the GUI builder command to something that isn’t a URL.\nRaghu vasa — September 29, 2016 at 7:53 am (permalink) Raghu vasa says:\nHi,\nI am loading html pages using Codenameone BrowserComponent. And My app is already in play store and installed in android device. Now i want to open play store with my appid as Installed. But it is opening play store in browser with \u0026ldquo;Install \u0026quot; option. If I click on Install option it is asking for my account credentials. Now if I sign in it is opening play store with \u0026ldquo;Installed\u0026rdquo; option.\nWhy it is asking again for sign in. I want to open the play store with Installed option. How Can I achieve this functionality.\nThanks,\nRaghu\nShai Almog — September 30, 2016 at 6:50 am (permalink) Shai Almog says:\nHi,\nthe web login is different from the phone login. A web session you embed in the app doesn’t have the login credentials of the device since that will violate device isolation policies. Just to be clear this is a security measure from Google that we can’t control.\nAquila CodenameOne — October 19, 2016 at 12:18 pm (permalink) Aquila CodenameOne says:\nHi,\nI am installed a Codename one App in my mobile device, I would like to know the app version number in app startup,\nif it is possible how to write the code in Codename one.\nThanks,\nSateesh.\nShai Almog — October 20, 2016 at 2:11 am (permalink) Shai Almog says:\nHi,\nit’s in Display.getProperty()\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/clarifying-our-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/clarifying-our-support/support-channels.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eFor years we treated support with a \u0026ldquo;we’ll meet our developers where they are\u0026rdquo; attitude which is problematic\u003cbr\u003e\nnow that we have more than 6 free support channels!\u003c/p\u003e\n\u003cp\u003eNotice that we didn’t include the email/phone support for pro/enterprise users in the list of 6 channels…​\u003c/p\u003e\n\u003cp\u003eWe try to respond to every query within 24 hours in stack overflow and the discussion group:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"http://stackoverflow.com/tags/codenameone\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eStackOverflow\u003c/a\u003e – please try asking any technical question here.\u003cbr\u003e\nWe know it’s sometimes challenging but the payout is great as the site is very searchable and provides a\u003cbr\u003e\ntreasure trove of Codename One information thanks to your questions!\u003c/p\u003e","title":"Clarifying our Support"},{"content":"\nWe are thrilled to announce the immediate availability of Codename One 3.4!\nVersion 3.4 brings with it refinement and stability as its core features, this is a trend that we are very pleased with\nand intend to carry on to version 3.5.\nHighlights of this Release Rewritten documentation – the developer guide was\nwritten from the ground up\nand the JavaDocs were significantly improved\nIntelliJ IDEA Plugin rewrite – the new IntelliJ IDEA support is\nas good as the NetBeans plugin\nShape Clipping – it is now possible to clip a graphics context based on an arbitrary shape\nToastBar – allows posting \u0026ldquo;hints\u0026rdquo; visually to a hint area\nToolbar is now the default \u0026amp;\nhas a refined implementation/usage\nSignatureComponent – allows us to accept user signatures\nGaussian Blur – supported on images and dialogs\nParparVM – now has better performance in micro-benchmarks\nYou can see the full list of changes to Codename One in the github repository.\nLowlights The following are things we are still working on or failed to bring to the front for this release. We are aware of\nthem and are working on improving them:\nDemos – We were supposed to modernize our demos. Almost all of them still use Java 5 and old themes. None\nuse the new material design icon fonts. This makes them feel antiquated, we hope to fix this early in the 3.5 cycle\nWindows port – We actually made great progress on this \u0026amp;\nalso posted the full source code.\nJust yesterday we posted additional good news on the subject!\nHowever, it’s still incomplete for release and needs quite a bit of work as it is a huge task. We are making a lot\nof progress though and we are optimistic that 3.5 could have UWP support.\nGUI Builder – This is the biggest failure of this release. One of our core goals was to get the GUI builder\nto production grade in 3.5 and we failed with that. It’s much stabler but we can’t call it 1.0 at this time…​\nThis is our highest priority right now. We will try to get the GUI builder to 1.0 well before 3.5 is ready and will\nhopefully release/announce it separately.\nOnwards to 3.5 Besides the lowlights above which must be addressed, there are several other things we are looking at for 3.5:\nJava 8 all the way – we will make Java 8 into the default build mode. Once that is in order we will experiment\nwith \u0026ldquo;only\u0026rdquo; Java 8 mode for newer builds.\nAssuming this will work we will switch to Java 8 thru our entire stack and Codename One builtin code will be able\nto use Java 8 language features.\nVideos \u0026amp; Even Better Docs – We will increase our video output now that our documentation has improved. We\nare still working on even better documentation than what we have right now. We’re not ready for announcements\nyet but we have some interesting ideas\nWe will continue the trend of using Codename One to build everything. This trend started with the\ncertificate wizard which is one of our most popular features. It continued with the new GUI builder and preferences\ndialog for our IntelliJ IDEA support.\nSchedule Codename One 3.5 is scheduled for Tuesday August 2nd 2016. Version 3.6 is currently scheduled for December of\n2016. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nKyri Ioulianou — May 3, 2016 at 8:33 am (permalink) Kyri Ioulianou says:\nWhen I check for updates in Netbeans it says the latest version available is only 3.3.4\nShai Almog — May 3, 2016 at 10:57 am (permalink) Shai Almog says:\nWe released the update last week so libraries should be up to date. The Eclipse and IDEA plugins should be at the right version, however since NetBeans goes thru manual verification by the NetBeans team it sometimes take a while for the update (which we submitted almost a week ago) to go thru that process.\nGeertjan — May 3, 2016 at 11:08 am (permalink) Geertjan says:\nI just had a look in the Plugin Manager in NetBeans IDE 8.1. The latest version of Codename One available is 3.4.0.\nGareth Murfin — May 3, 2016 at 11:24 am (permalink) Gareth Murfin says:\nGreat news!!! What an update, shame about the GUI builder, Im looking forward to that. I may even swap to IntelliJ plugin see what its like! Also when will cocoa pods be fully supported on iOS side ?\nShai Almog — May 3, 2016 at 11:25 am (permalink) Shai Almog says:\nNotice Geertjans comment that 3.4 is already up on NetBeans. We have a cocoa pods announcement coming soon…\nChen Fishbein — May 3, 2016 at 12:36 pm (permalink) Chen Fishbein says:\nHi Geertjan,\nI think I see an issue with the plugin center. is it possible that the plugin center won’t return the most latest plugin version if a user haven’t updated for a while? for example if a User was on version 3.3.3 and he haven’t updated the plugin for a while and in the meantime we uploaded 3.4.0 version. when he search for updates the plugin center will updated him to 3.3.4 instead of skipping that version and offering 3.4.0. is this a known issue?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-3-4-now-live/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-3-4-now-live/release3.4.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are thrilled to announce the immediate availability of Codename One 3.4!\u003c/p\u003e\n\u003cp\u003eVersion 3.4 brings with it refinement and stability as its core features, this is a trend that we are very pleased with\u003cbr\u003e\nand intend to carry on to version 3.5.\u003c/p\u003e\n\u003ch3 id=\"highlights-of-this-release\"\u003eHighlights of this Release\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eRewritten documentation\u003c/strong\u003e – the \u003ca href=\"https://www.codenameone.com/manual/\"\u003edeveloper guide\u003c/a\u003e was\u003cbr\u003e\n\u003ca href=\"https://www.codenameone.com/files/developer-guide.pdf\"\u003ewritten from the ground up\u003c/a\u003e\u003cbr\u003e\nand the \u003ca href=\"https://www.codenameone.com/javadoc/\"\u003eJavaDocs\u003c/a\u003e were significantly improved\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eIntelliJ IDEA Plugin rewrite\u003c/strong\u003e – the new \u003ca href=\"/blog/a-new-idea.html\"\u003eIntelliJ IDEA support\u003c/a\u003e is\u003cbr\u003e\nas good as the NetBeans plugin\u003c/p\u003e","title":"Codename One 3.4 Now Live"},{"content":"\nHistorical note: Codename One\u0026rsquo;s UWP target was discontinued in release 7.0.229. This post is preserved for historical context only, and its build/setup instructions no longer apply to current Codename One projects.\nFabricio just\nsubmitted a pull request that Steve\nmerged to provide support for Windows Phone 8.1 in our new UWP (Universal Windows Platform) port of Codename One.\nThis is huge news as it means we can fully migrate to the new port without leaving developers behind!\nThis means we’ll be able to make the migration to the new Windows port quicker\nand throw away the old port without losing much.\nNew Migration Plan Up until now we were working under the assumption that UWP would be similar to Windows Phone in terms of\nauthorization and build process. This doesn’t seem to be the case.\nUWP requires a certificate file to authorize a build similarly to iOS/Android builds, this is probably a good thing\nas it might mean that sideloading over the air might finally be supported on Windows devices.\n__ Windows Phone is the only mobile platform we worked with that didn’t support installing files over the air! This means we will need to make some changes to all IDE plugins and to the build.xml file in order to support the\nUWP target, these changes will allow us to make the migration process much smoother and phase out the old\nWindows phone target gradually. This also means the Windows section in the IDE will also include more options\nsuch as the certificate required for UWP. We’ll keep you posted on this process as we setup the build servers\nand get the IDE plugin updates out of the door.\nWhen will this be Out? This is probably the main question here and we still don’t have a final answer.\nUntil we start seeing builds going thru it’s hard to say what would work and what wouldn’t. We had a big issue with\niKVM this past week and needed help from Microsoft to resolve that (they were quite helpful here). We have\nno way of knowing if this is the \u0026ldquo;last issue\u0026rdquo; we will run into. Setting up a Windows build server is the equivalent\nof a root canal without the pleasant bits or anesthesia!\nWe literally had to get Microsoft tech support to help with basic things and are still struggling to get the build\ntools to run there.\nWe hope to have a beta version out for developers before the 3.6 release which is currently slated to August. However,\nthis is a tentative date and until we actually see everything working for elaborate apps we won’t commit to anything. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — May 2, 2016 at 1:40 pm (permalink) Chidiebere Okwudire says:\nThis is good progress! Hopefully things will work according to schedule (read: pleasant bits and anesthesia for the rest of the ‘surgery’, haha) and we’ll finally be able to confidently make decent WP apps.\nGareth Murfin — May 3, 2016 at 11:27 am (permalink) Gareth Murfin says:\nThis sounds promising, although I have not targeted win phone because I assumed their market share was almost 0 🙂\nShai Almog — May 4, 2016 at 5:04 am (permalink) Shai Almog says:\nI think Windows Phone is dead but some companies need to support \u0026ldquo;everything\u0026rdquo;. The value isn’t Windows on phones as much as on tablets/PC’s which the UWP already supports. Windows 10 store was already available on 250M devices quite a while back so it’s one of the bigger target markets out there and has a strong enterprise presence.\nLana — March 27, 2017 at 1:48 am (permalink) Lana says:\nHi Shai,\nI looked it up but couldn’t keep track, are windows phone builds supported or not? It seems that our builds fail but I can’t tell if that’s a bug or if you aren’t supporting windows phone builds for lack of corporate clients.\nIt’d be very cool if you could write a one-line summary about whether it’s currently supported or not on the main page.\nshannah78 — March 27, 2017 at 5:28 pm (permalink) shannah78 says:\nWP 8.1 is not supported. WP 10 (UWP) is supported.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/windows-phone-8-1-uwp-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/windows-phone-8-1-uwp-support/universal-windows-apps_thumb.jpg\"\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003eHistorical note:\u003c/strong\u003e Codename One\u0026rsquo;s UWP target was discontinued in release \u003cstrong\u003e7.0.229\u003c/strong\u003e. This post is preserved for historical context only, and its build/setup instructions no longer apply to current Codename One projects.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e\u003ca href=\"https://twitter.com/ravnos_kun\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFabricio\u003c/a\u003e just\u003cbr\u003e\n\u003ca href=\"https://github.com/codenameone/CodenameOne/pull/1757\" target=\"_blank\" rel=\"noopener noreferrer\"\u003esubmitted a pull request\u003c/a\u003e that Steve\u003cbr\u003e\nmerged to provide support for Windows Phone 8.1 in our new UWP (Universal Windows Platform) port of Codename One.\u003c/p\u003e\n\u003cp\u003eThis is huge news as it means we can fully migrate to the new port without leaving developers behind!\u003c/p\u003e","title":"Windows Phone 8.1 \u0026 UWP Support"},{"content":"\nWe finally uploaded the last of the 3 hello world videos covering\nEclipse,\nwhich now joins the ranks of the\nNetBeans and\nIntelliJ/IDEA\nvideos.\nCheck out the Eclipse version here:\nThese are probably the three most important videos we have which is why we decided to start with them as\npart of our restructuring of our video tutorials \u0026amp; guides. Now that we got them out of the way we need to decide\non the next high priority video?\nShould we focus on re-doing one of our existing videos that is badly done or create a completely new video?\nCurrently I’m leaning towards the latter as I think we are missing a \u0026ldquo;How does Codename One work?\u0026rdquo; video\nwhich might go a long way to explain some basic concepts that are hard to explain with the current set\nof materials. If you have other thoughts or things you would like to see featured in future videos please let us know.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-getting-started-video-eclipse-version/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-getting-started-video-eclipse-version/hello-codenameone-eclipse.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe finally uploaded the last of the 3 hello world videos covering\u003cbr\u003e\n\u003ca href=\"/how-do-i---create-a-basic-hello-world-application%e2%80%94%e2%80%8bsend-it-to-my-device-using-eclipse.html\"\u003eEclipse\u003c/a\u003e,\u003cbr\u003e\nwhich now joins the ranks of the\u003cbr\u003e\n\u003ca href=\"/how-do-i---create-a-basic-hello-world-application%e2%80%94%e2%80%8bsend-it-to-my-device-using-netbeans.html\"\u003eNetBeans\u003c/a\u003e and\u003cbr\u003e\n\u003ca href=\"/how-do-i---create-a-basic-hello-world-application%e2%80%94%e2%80%8bsend-it-to-my-device-using-intellij-idea.html\"\u003eIntelliJ/IDEA\u003c/a\u003e\u003cbr\u003e\nvideos.\u003c/p\u003e\n\u003cp\u003eCheck out the Eclipse version here:\u003c/p\u003e\n\u003cp\u003eThese are probably the three most important videos we have which is why we decided to start with them as\u003cbr\u003e\npart of our restructuring of our video tutorials \u0026amp; guides. Now that we got them out of the way we need to decide\u003cbr\u003e\non the next high priority video?\u003c/p\u003e","title":"New Getting Started Video – Eclipse Version"},{"content":"\nWe’re releasing new plugins today in for the 3.4 release, if there are major regressions we’ll push out new\nversions for the release itself but if they are stable they will be the actual release versions. We had a great\nweek on stackoverflow as well with many excellent questions. As usual this post isn’t exhaustive and doesn’t cover\nall the questions asked, but it should provide a sense of the top discussions of the week.\nTurning off android.permission.INTERNET in CodenameOne Codename One includes two default permissions on Android, Internet and storage. We turned them on by default\nsince detecting an actual need for one of those permissions is really hard.\nRead on stackoverflow…​\nIs there a companion to the Form.onShow() method I can use when a Form is hidden? This is often confusing to new Codename One developers. Unlike desktop developers don’t explicitly dispose a\nwindow and so the lifecycle isn’t clear. Since the old GUI builder handles things differently from regular applications\nthis gets even more confusing…​\nRead on stackoverflow…​\nRotate image in CodeNameOne? Using a gesture to rotate an image in the ImageViewer is something we don’t support at the moment but this\nis easily doable by deriving the component. This demonstrates the power and customizability of Codename One.\nRead on stackoverflow…​\nCan’t get setScrollVisible() to work Scroll behavior is a painful subject we should simplify, one of the confusing parts is the scrollability of a Form\nwhich is really the scrollability of the content pane.\nRead on stackoverflow…​\nanimateLayout on expanding component is not working Layout animations conflict with revalidate() calls, it’s important to use one or the other and not both.\nRead on stackoverflow…​\nHow to get a circular layout in codenameone I recall that someone posted a circular layout a while back, if you have it please add a better answer.\nRead on stackoverflow…​\ndifferent colors on ComboBox ComboBox UIID’s are some of the more confusing style elements we have.\nRead on stackoverflow…​\nGetting Codenameone to respect the proxy settings on a windows desktop build This is a great idea I wasn’t aware of this setting in Java. We should use it for all of our tools including the build\nclient tools to simplify proxy issues.\nRead on stackoverflow…​\nCodename one Facebook login email = null Facebook login works in a very inconsistent way, e.g. sometimes you will get an email login and sometimes you won’t.\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-iii/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-iii/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’re releasing new plugins today in for the 3.4 release, if there are major regressions we’ll push out new\u003cbr\u003e\nversions for the release itself but if they are stable they will be the actual release versions. We had a great\u003cbr\u003e\nweek on stackoverflow as well with many excellent questions. As usual this post isn’t exhaustive and doesn’t cover\u003cbr\u003e\nall the questions asked, but it should provide a sense of the top discussions of the week.\u003c/p\u003e","title":"Questions Of The Week III"},{"content":"\nWe get a lot of requests to compare Codename One to other technologies and while we do have a comparison\npage it is somewhat static. Doing a comparison within a blog post does have the advantage of focusing on\none technology and allowing comments. In this segment we’ll compare the venerable QT to Codename One.\nWhen developers started asking for this comparison I was of the opinion that it made no sense. The technologies\nare so far apart from one another that they defy any sensible comparison. I still think the conceptual difference is\na bit too great but I’ll try to bridge some of the gap.\n__ We updated this comparison after the initial publication to include the additional Property Cross section __ We updated this again to reflect pricing, terms \u0026amp; lightweight/heavyweight mixing Background QT went thru a lot over it’s many years. It’s the basis of the excellent KDE Linux desktop environment which in\nmy humble opinion was always superior to gnome. It’s a C++ library \u0026amp; toolchain developed by a company called\nTrolltech that was purchased by Nokia.\nNokia purchased Trolltech with the goal of taking QT into mobile, this went thru many iterations over the years\nbut the product that’s available today is radically different to everything available since.\nAt a Glance Table 1. QT vs. Codename One Category QT Codename One Language C++/QML-JavaScript Java Cloud Build No (requires Mac \u0026amp; Windows for full OS support) Yes (can work on Linux for iOS development) IDE QT Creator or Visual Studio NetBeans, Eclipse or IntelliJ IDEA Web Deployment No Yes Widgets Lightweight Lightweight Pricing (Monthly no discounts) 350 USD 19 USD – 399 USD + Free App Distribution Only with active subscription Perpetual In Detail Language While QT supports QML (an XML flavor) with JavaScript bindings. QT at it’s base is C based. If you need to integrate a native widget like Googles native maps or similar capabilities you need to do this via C.\nThis might be challenging as most of the integration documentation for various libraries is in Java, Objective-C.\nBinding an iOS/Android SDK to QT might not be trivial. C++ isn’t garbage collected or \u0026ldquo;safe\u0026rdquo; and is a challenging\nlanguage for novices.\nCodename One uses Java for everything with all of the typical Java advantages (GC, safe memory etc.). When\nintegrating with native code Codename One generates \u0026ldquo;stubs\u0026rdquo; for the various platforms allowing developers to\nwrite native Objective-C, Java (Android flavor), C# etc. code.\nThis makes integrating with native OS capabilities far simpler as developers can literally copy and paste sample\ncode from the SDK vendor.\nPricing \u0026amp; Rights QT is free for open source GPL projects. For every other case it’s priced at 295USD per developer.\nCodename One has a free commercial license and a full license starts at 19USD.\nCodename One sees the apps as owned by you, once built you are free to sell and redistribute them even after canceling a subscription. QT requires licensing fees for distribution. If you stop paying the monthly licensing fee you need to stop distributing the applications you’ve already built.\nCloud Build Codename One’s cloud build capability is unique. It allows developers to build a native application using the\nCodename One cloud servers (Macs for iOS, Windows machines for Windows etc.) This removes the need to\nown dedicated hardware and allows you to build native iOS apps from Windows and native Windows apps\nfrom your Mac or Linux machine.\nThis makes the installation of Codename One trivial, a single plugin to install. This isn’t true for development\nenvironments that don’t use that approach.\nIDE QT has its own custom IDE with GUI builder. It also has a plugin to support Visual Studio which is quite popular\nin the C++ developer community.\nCodename One integrates with all major Java IDE’s thru a standard plugin. The plugin delivers the simulators\nand visual tools for Codename One as well as the device building capabilities.\nWeb Deployment QT is very portable and so is Codename One. Both support many platforms but there is one that Codename One\ncan support that QT might find unreachable: JavaScript.\nCodename One supports the process of compiling an application (threads and all) into a JavaScript application\nthat can be hosted on the web. This is done by statically translating the Java bytecode to JavaScript obfuscated\ncode.\nWidgets The one point of similarity between QT and Codename One is that both frameworks take the lighweight widget\napproach for greater flexibility and portability. However, as far as I can tell only Codename One supports lightweight/heavyweight mixing.\nIntegrating a component like Goolge Maps into QT and drawing on top of it will require a lot of work. This is seamless in the current version of Codename One.\nProperty Cross Comparison The PropertyCross demo was built as a tool that allows us to compare two cross platform frameworks, as such\nthere are versions of the demo for many such platforms. You can check out details of the Codename One\nimplementation here. The github repository for this demo\nis here.\nThe QT version of property cross includes 3 projects:\n– The main application QML UI – this includes code that is mostly declarative but quite a lot of it. It defines the UI\nof the application and not much more\n– The lib directory includes the CPP files and header files for the project\n– A special test project that we’ll ignore for now as this isn’t covered in other discussions\nIt’s pretty great that QT doesn’t require separate projects for every OS. It does have some theme directories but\nmost of the code including the UI is common. This is because QT and Codename One share a lightweight\narchitecture that increases portability.\nThe code isn’t as verbose as some other implementations it is roughly 2x-3x larger than the Codename One\nproject in lines of code. The project seems to be missing the application launcher screenshots and the icon files\nfor the various supported DPI’s. While most of the resources would probably be adaptable in a portable way\nicons and splash screens probably won’t be.\nThis is something that Codename One can handle seamlessly thanks to the build servers but QT might have an\nissue with.\nFinal Word Our opinions are obviously biased but I think we did a reasonably fair comparison. I actually like and respect QT\nwhich makes it a great candidate for comparison.\nIf you think we misrepresented Codename One or QT in any way let us know in the comments.\nPlease use the comments section for suggestions of future comparison segments. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — April 30, 2016 at 8:37 am (permalink) bryan says:\nGluon vs CN1\nShai Almog — May 1, 2016 at 4:39 am (permalink) Shai Almog says:\nI won’t blog about Gluon right now. It’s\nnot a \u0026ldquo;real\u0026rdquo; product with shipping mobile apps. Comparing it to us would\npresent it in a light where real apps can be built with it where in\nfact it is so inherently broken that I can’t find a single good thing to\nsay about it.\nI don’t want to write a comparison to a\nproduct that I can’t say anything positive about. Gluon is so\nproblematic I can’t even call it a real product as much as a mish mash\nsalad of half baked technologies. It’s a proof of concept based on\nhugely complex 3rd party code that can’t possibly be understood by the\nguys shipping it.\nIt is based on Java FX, the only reason\nthat still exists is because Oracle is a corporate hoarder incapable of\nthrowing anything away. FX is dead on the desktop and Oracle made the\nsmart business move of not releasing it to mobile as it is technically\nunworkable in mobile. This was proven by Adobe who had a similar\narchitecture fail on mobile regardless of Apple (it failed on Android\ntoo). 3rd party Scene Graph implementations are REMARKABLY hard to tune\nin a performant way and integrate with mobile GPUs/native widgets.\nOracle who had some of the most amazing graphics developers ever\nunderstood that this is impratical.\nTheir VM used to be\nRoboVM on which performance still sucked and it was a VERY FAST AOT VM.\nNow that RoboVM is dead their alternative is OpenJDK which is\ninterpreter based… How can someone who even suggest an interpreter for\nsomething as complex and slow as a graphics intensive mobile\nscene-graph engine be taken seriously?\nWhile\nthey are focused on re-inventing this HUGE amount of code that they\ncan’t possibly test properly (e.g. java.net can’t be implemented\ncorrectly on iOS, sqlite on Android/iOS is totally different etc.) they\nare also picking up the scene builder, custom widgets and IDE plugins…\nThey will have to also pick up a VM as none of the existing options can\ncompete with RoboVM in terms of speed/breadth. RoboVM was too big for\none company to maintain and Gluon is already over stretched by a few\nmiles so what’s another insurmountable challenge to the pile…\nThis\nshows lack of focus and understanding of the scope of work required. I\ncan’t possibly take a company that takes up something clearly\nimpractical and unworkable as serious.\nTo make matters\nworse they have no viable business model. This means they rely on\nconsulting fees and nag screens which is a very problematic method of\nbuilding a sustainable business. RoboVM took a similar path of\nunsustainable business practice and that ended in the only place it\ncould end. We like to think that those things don’t matter but if you\nwant your technology to exist tomorrow you need it to be open,\naccessible, understandable and have a viable long term business model.\nbryan — May 1, 2016 at 12:49 pm (permalink) bryan says:\nThat’s a pretty good comparison 🙂\nJohan Vos — May 2, 2016 at 9:14 am (permalink) Johan Vos says:\nIf you want an answer without lies and FUD, feel free to contact us (Gluon) directly.\nShai Almog — May 2, 2016 at 9:17 am (permalink) Shai Almog says:\nFUD is subjective but which part of my response is untruthful?\nFelix Bembrick — May 2, 2016 at 11:15 am (permalink) Felix Bembrick says:\nWhich part is untruthful? Just the bit after \u0026ldquo;I won’t blog about Gluon right now\u0026rdquo; which even itself was a lie.\nUnderestimating Gluon and the passionate people like me who support what they are doing will be your own downfall.\nPride comes before a fall and given the humungous amount of pride that’s on display here I would anticipate your fall will be of nuclear proportions.\nJavaFX rules and Gluon is making it rule even better.\nShai Almog — May 2, 2016 at 11:24 am (permalink) Shai Almog says:\nNot blog, comment. Big difference.\nI’ve worked in this industry and at Sun for quite a while (90’s). Seen these things come and go and I know the complexities involved in both JavaFX on mobile and in mobile Java in general (not to mention Sun/Oracle politics). You are conflicting pride and expertise.\nI know my stuff and I advocate it, that’s pride. You are looking at my expert opinion and discarding it as \u0026ldquo;just pride\u0026rdquo; well… That’s the kettle…\nIt’s true that I am discounting you just like I did RoboVM which ended pretty much where I predicted which is the exact reason we chose not to go with them in 2013.\nWhen you say JavaFX \u0026ldquo;rules\u0026rdquo; you might as well spell that with a Z. That is not a fact and shows the level of thought you put into this. Please feel free to disprove a single factual point I made above…\nE.g. let me give you a nugget, FX fans constantly talk about FX going into VW and making a splash. Guess what, Codename One has shipped in millions of cars for years and we didn’t even mention that ONCE!\nIf you think FX will pick up because of one deal or another I suggest you take your emotional attachment. Put it in a box and take a step backwards. You might like FX, it’s an elegant API designed by brilliant people for whom I have the utmost respect. But that doesn’t change one iota of the facts I wrote above. I’m waiting anxiously for an itemized list of \u0026ldquo;lies\u0026rdquo;.\nFelix Bembrick — May 2, 2016 at 11:25 am (permalink) Felix Bembrick says:\nBTW, just to fill those massive voids known as ignorance, are you even aware that there are already 2 forks of RoboVM so the technology is actually more alive than ever?\nAnd, gosh, of course Gluon never realised that a fully interpreted version of Java will never be viable on mobiles!\nYou are basically calling Johan an idiot and the one thing that I am more certain about him than anything else is that he ain’t no idiot!\nShai Almog — May 2, 2016 at 11:28 am (permalink) Shai Almog says:\nOne minor thing I forgot to mention. I actually worked with the JavaFX\nScript team to get JavaFX onto mobile. I know a thing or two here. Also\nconsulted to the JavaFX embedded team lead on graphics and GPU usage…\nI’m well aware of these forks. I’m also well aware that the RoboVM team claimed that Java 9 compatibility which came after the forks was the hardest thing they worked on since building RoboVM itself. So you are saying they lie?\nI’m calling Johan ignorant and arrogant. A desktop developer walking into mobile expecting things to work in the same way and picking up a HUGE pile of code expecting it to \u0026ldquo;work\u0026rdquo; in production.\nFelix Bembrick — May 2, 2016 at 11:29 am (permalink) Felix Bembrick says:\nOh well, all I can say to you is \u0026ldquo;keep digging\u0026rdquo;. That’s already a mighty big sink hole that your life’s investment is about to fall into…\nFelix Bembrick — May 2, 2016 at 11:31 am (permalink) Felix Bembrick says:\nDo you even know that Gluon products are already working and working very well on mobiles? I mean never let the truth get in your way of dissing a Java Champion or a vastly superior technology to whatever it is that you’re peddling…\nShai Almog — May 2, 2016 at 11:34 am (permalink) Shai Almog says:\nBeing a Java champion (I’m only a rockstar as I don’t suck up to Jim) I couldn’t care one iota.\nRunning something on a device is miles away from shipping a product or passing a TCK.\nI’m invested but you still fail to show one thing that was a \u0026ldquo;lie\u0026rdquo; in my post.\nFelix Bembrick — May 2, 2016 at 11:35 am (permalink) Felix Bembrick says:\nAnd I am sorry, I admit that cannot disprove any factual comments you have made.\nBut that’s because i cannot disprove something which is yet to exist.\nFelix Bembrick — May 2, 2016 at 11:39 am (permalink) Felix Bembrick says:\nGosh, did I use the word \u0026ldquo;pride\u0026rdquo;? I should have used \u0026ldquo;arrogance\u0026rdquo;, \u0026ldquo;delusion\u0026rdquo; and/or \u0026ldquo;narcissism\u0026rdquo;.\nShai Almog — May 2, 2016 at 11:44 am (permalink) Shai Almog says:\nSo let me get this strait.\nJohan comes on our blog. Calls me a liar for posting a factual true opinion made by myself with my bias clearly evident and displayed…\nAnd you then come off and claim that I somehow am unaware of \u0026ldquo;facts\u0026rdquo; that I am clearly aware of and I’m not OK?\nI’m biased true… I might have a cognitive dissonance. That is always true…\nNarcissism?\nYou would laugh if you actually knew me.\nArrogance?\nYou betcha I’m arrogant. Comes with being an expert too.\nDelusion?\nI can’t possibly tell that about myself. However, I suggest you take a step backwards and evaluate if maybe the roles are reversed here.\nFX couldn’t succeed with all the resources of Sun/Oracle behind it, you can claim that I’m arrogant and delusional… But you are insane if you don’t take up these mantles yourself….\nGluon is taking up not Just FX, but the whole ecosystem and is now also picking up the VM work, IDE integration and all the slack left by RoboVM. We have people who know every piece of Codename One inside out. We worked on it since 2007 and we know everything there is to know. You guys are dealing with a HUGE black hole of software some of which still doesn’t exist and you are trying to sell it as if it’s a sellable product. But I’m arrogant and delusional?\nFelix Bembrick — May 2, 2016 at 12:29 pm (permalink) Felix Bembrick says:\nWell, you have still failed to even concede that your very first statement \u0026ldquo;I am not going to blog about Gluon right now because the babbling that follows is commenting, not blogging as the two are radically different polar opposite concepts\u0026rdquo; was a lie.\nAnd that was the high point of your babbling.\nIt was all downhill from there, just like your company’s future bottom line.\nAnd to say that I would laugh if I actually met you is a given as I have basically been laughing my head off since you started firing blanks at Johan.\nAnd, you might think you are the smartest and most experienced person with these technologies on the planet but that’s only true because you’re on some other planet than the rest of us.\nLet me just say you have no idea who you are feebly trying to trade blows with. I too worked at Sun (but that wasn’t challenging enough). I have also worked on what was recently voted the second best animated film of all time in terms of the rendering and animation quality. I have optimised scene graphs before. I know more about GPU technology than you do about how to behave like a tool. Johan and I could together take down your entire company all by ourselves if you continue to motivate us to do just that.\nShai Almog — May 2, 2016 at 1:23 pm (permalink) Shai Almog says:\nGreat to hear that you worked at Sun. Did you do mobile too?\nGood luck to you guys with gluon, I’m sure you will reach the same level of market success as FX.\nNotice that if we fail you will fail too but the opposite isn’t true. We are the established leader in the Java mobile WORA tools but to take that position you need to surpass in acquisitions not take business from us. I hope you have someone who understands how the business side of things works at your company.\nWe are not your competitor just like you are no threat to us. At most you could in theory slow our growth but if we go down in sales it means the market is shrinking which is bad for us but horrible for you as you aren’t yet established.\nI suggest you focus first on understanding \u0026ldquo;what the market is\u0026rdquo;, it sounds like a \u0026ldquo;stupid business speak\u0026rdquo; but I suggest you understand these concepts if you want to succeed. Then take a step back and objectively compare the end user/developer proposition of our respective tools. You will notice that you guys target a very different demo/value proposition. If you carry that analysis to its full extent you will also see what I saw in my first meeting with Niklas at JavaOne 2013. There is no business model for your approach other than consulting.\nConsulting can be moderately profitable, but you can’t sustain long term platform development on consulting fees. Eventually you need to pick and choose if you are a consulting shop or a startup and at that point you need to sit down with someone who understands business and try to imagine the growth that’s achievable in realistic scenarios.\nFelix Bembrick — May 2, 2016 at 6:31 pm (permalink) Felix Bembrick says:\nThanks for your advice. It’s mostly very accurate and worth reading. It’s just the bit after \u0026ldquo;Glad to hear that you worked at Sun\u0026rdquo; that has that \u0026ldquo;babbling\u0026rdquo; quality you do so well that I will wisely ignore.\nWould you appreciate me endorsing you for the skill of babbling? You are clearly at the elite level.\nYou know, I am fairly sure Johan is a lot like me in one aspect. The more people tell us that something \u0026ldquo;can’t be done\u0026rdquo;, the more motivated we become to prove such people wrong (which seems a little superfluous in your case).\nSo, let the Hunger Games begin. I’ll play the part of Katniss and you can continue in your role as Snow (or Coin).\nThe very name of your company suggests you are so narrow minded that you think you are the only technology that anyone ever needs. One size fits all. You are so disrespectful and arrogant to your competitors that I am surprised if there’s room in your office space for anything more than just your ego.\nBut I love to see this. You are such a classic example of the kind of CEO that thinks their business model is \u0026ldquo;Competitors? What competitors?\u0026rdquo;.\nYou will only see them when you are broke, unemployed and living in a trailer park.\nShai Almog — May 2, 2016 at 7:16 pm (permalink) Shai Almog says:\nLike I said before takes one to know one but I get that you don’t like me and I don’t mind one bit.\nNotice a big difference about our approaches, you are writing in our\nblog deriding me with insults on a personal level. Yet I don’t kick you\nout. That’s pretty evil of me. I’m just mean in that way….\nCodename One is about unifying everything to a single technology that hides the complexity not using a single technology for everything. But feel free to concentrate all your anger at me and use me as your motivation.\nYou didn’t get what I said at all. You don’t compete with us. If you do then you are in big trouble.\nWe are profitable but we’re not the leader in cross platform by a long shot. We are not even the leader in mobile Java (that’s Android). If you are going after us then you are going after a small market share relatively and that’s \u0026ldquo;stupid\u0026rdquo;. I know business books are boring but I suggest picking a few up and learning about \u0026ldquo;go to market\u0026rdquo; strategies. But obviously you treat everything I say as evil and malicious so I’m just trying to waste your time with an understanding of how business works and how to define your competitors properly to confuse you.\nBut if it helps you work at night with the dream of somehow putting the big bad me and my family into the streets because I’m such an awful human being who dares to think you are wrong and is wasting his time in his own blog post explaining that to you then feel free to concentrate your anger and contempt at me 😉\nFelix Bembrick — May 2, 2016 at 8:19 pm (permalink) Felix Bembrick says:\nIf I offered you a tissue, would that make you feel any better?\nAnd please stop assuming you know stuff that neither I nor seemingly anyone else could possibly know.\nI don’t need lectures from you on business, strategic planning or on anything for that matter (except of course on babbling mastery where I admit you have me beaten).\nAnd insults? Have a look at where they started. It was only then that I even decided to get involved (regrettably).\nBut thanks for showing such extraordinary tolerance and generosity for not booting me out of your forum. I mean, it’s not like that would appear as a concession of defeat or anything like that\nEveryone knows it’s just because you’re such a kind hearted, polite, respectful and open minded person who knows more about business than Warren Buffet and has an IQ of 250.\nOh, and who doesn’t suck up to Jim 😉\nShai Almog — May 2, 2016 at 8:38 pm (permalink) Shai Almog says:\nDespite your attitude towards me I wish you no harm, on the contrary I honestly do hope that you guys do well. I don’t think it will hurt our business just like RoboVM didn’t impact our business much neither when they launched nor when they left (just made CPM and SEO slightly more expensive).\nI think you need to re-evaluate your words and the line between a strong disagreement and animosity.\nI didn’t \u0026ldquo;start\u0026rdquo; I wrote a factual opinion in a comment response to a question posted to our blog. Your colleague came in, called me a liar without basis. You then come in with name calling and repeated assaults on what you perceive as my personality flaws.\nNo I don’t suck up to Jim and never have which is why we never got free publicity from Oracle despite paying full price for a booth at J1 a couple of years ago and speaking for years.\nUnlike you I don’t think you guys are stupid, I think you are wrong but not stupid.\nYou obviously ignore everything I say so lets cut it here.\nKyri Ioulianou — June 15, 2016 at 5:36 pm (permalink) Kyri Ioulianou says:\nYou destroyed this guy\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/comparing-qt-and-codename-one/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/comparing-qt-and-codename-one/compare-to-qt.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe get a lot of requests to compare Codename One to other technologies and while we do have a comparison\u003cbr\u003e\npage it is somewhat static. Doing a comparison within a blog post does have the advantage of focusing on\u003cbr\u003e\none technology and allowing comments. In this segment we’ll compare the venerable QT to Codename One.\u003c/p\u003e\n\u003cp\u003eWhen developers started asking for this comparison I was of the opinion that it made no sense. The technologies\u003cbr\u003e\nare so far apart from one another that they defy any sensible comparison. I still think the conceptual difference is\u003cbr\u003e\na bit too great but I’ll try to bridge some of the gap.\u003c/p\u003e","title":"Comparing QT and Codename One"},{"content":"\nOne of the best things in running an open source project is the high quality issues, we don’t always respond\nimmediately and sometimes things get lost under our piles of work but we do appreciate the time you\ntake to file issues.\nWe’d like to define some guidelines for issue submission, this will make our job easier in processing/assigning \u0026amp;\nresolving issues as soon as possible. We don’t want this post to deter you from submitting an issue, it’s here to help.\nIf something is unclear in this post just go ahead and submit or ask a question in the comments section below.\nShould I Submit an Issue? If you aren’t sure this is a bug we suggest googling and asking on stackoverflow\nor in the discussion forum.\nIf it’s a question, it probably doesn’t belong in the issue tracker and should go in the support channels.\nWhere to Submit an Issue? If you have an issue with any codenameone project they should all go into the\nmain Codename One issue tracker.\nThis even includes issues with the codenameone.com website, the plugins \u0026amp;\neven the cn1libs hosted under the codenameone user account.\nHowever, other cn1libs that are hosted under different user accounts should use their respective issue trackers!\nShould I Edit the Issue or Just Post Comments? When we read an issue we usually start with the top description (the first comment). It needs to be as up to date\nas possible and include the elements described in the next question. So please edit it with new information\nrelated to the test case.\nTwo things you should keep in mind:\nDon’t edit the question in a way that removes/changes previous meaning. E.g. if you remove information from\nthe issue this will create a situation where comments might become unclear. Try to cleanup \u0026amp; elaborate without\ndistorting too much meaning\nAfter editing is done post a comment. Editing doesn’t trigger a notification to people watching the project\nand so developers might be unaware that you made an edit\nWhat Should an Issue Include? The issue should obviously include a description of the problem and ideally a test case to reproduce it.\nMake sure to highlight if the issue occurs on a device (include OS versions tested), simulator or both!\nUnless the issue is specifically related to the GUI builder we prefer the issue will be a small handcoded application coded\nfrom the bare bones template. Ideally only the start() method should be included if that is possible.\n__ | The reason we prefer it this way is that we already have test case apps with the right provisioning/certificates etc.\nin this way we can just paste your code directly into our existing test app and deploy Source should be embedded using a backtick notation into the question followed by the word java on the first line e.g.\n````java Your source goes here... ```` Should produce Java syntax highlighted code in place.\nIf you have a really complex project and there is no way to simplify it you can use either gist\nor github itself and post a link to a project you committed.\nThe reason we prefer this is that we can then browse the source quickly to find issues without downloading it and\ninstantly determine the right person to deal with a given issue.\nScreenshots \u0026amp; Videos Screenshots are often crucial pieces in describing some issues, if there is any visual aspect to your issue please include\na screenshot!\nYou can grab a screenshot off of any device, please don’t use a camera to grab a device screenshot…​\n__ | You can capture the screen on your iOS device using the Sleep/Wake and Home buttons. Press and hold\nthe Sleep/Wake button on the top or side of your iPhone, iPad, or iPod touch, then immediately press and release\nthe Home button. You can find the screenshot in your Photos app __ You can grab a screenshot of an Android device by holding the volume down button and the power button Elements such as animations or artifacts require video you can grab a video of an iOS device using one\nof the techniques described here.\nAndroid 4.4 or newer requires the Android SDK to achieve a similar result using\nthis technique.\nUsing these techniques will allow a non-grainy video that’s easy to understand even for elaborate/refined issues.\nWe recommend uploading the video to youtube as \u0026ldquo;unlisted\u0026rdquo; video and embedding the link into the issue.\nThis allows anyone to view the video almost instantly even on mobile while wading thru issues. This also\nResources/Images Some issues require a resource file or image files. These can be added as attachments to the issue but we’d appreciate\nif issues can be reproduced without such files if possible.\nIn Closing Issues are probably the best way most of us can do to help a project like Codename One or any other open\nsource project move forward. They are a great help and we really appreciate the effort that goes into them even\nwhen they are not up to the standards above.\nHowever, if you follow the guidelines above it will make our work easier and it will make resolution of such\nissues faster. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJérémy MARQUER — April 27, 2016 at 4:31 pm (permalink) Jérémy MARQUER says:\nHi,\nCan you help me with this issue please : https://github.com/shannah/…\nI can’t build anymore for Android until library with andlib format is included in this cn1lib. Thanks.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/issue-submission-guideline/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/issue-submission-guideline/how-to-use-the-codename-one-sources.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the best things in running an open source project is the high quality issues, we don’t always respond\u003cbr\u003e\nimmediately and sometimes things get lost under our piles of work but we do appreciate the time you\u003cbr\u003e\ntake to file issues.\u003c/p\u003e\n\u003cp\u003eWe’d like to define some guidelines for issue submission, this will make our job easier in processing/assigning \u0026amp;\u003cbr\u003e\nresolving issues as soon as possible. We don’t want this post to deter you from submitting an issue, it’s here to help.\u003cbr\u003e\nIf something is unclear in this post just go ahead and submit or ask a question in the comments section below.\u003c/p\u003e","title":"Issue Submission Guidelines"},{"content":"\nToday we are going into code freeze for Codename One 3.4 which is due one week from now, because of the\nfast release cycle we don’t need more than a week of code freeze to stabilize our current release.\nThe code freeze applies only to the Codename One libraries and ports as those are the parts that will be inherent\nto the release.\nHow does the Code Freeze Work? The pieces of Codename One that are frozen are effectively the entire github repository with the exception\nof the Codename One designer and JavaDoc comments. That means that we will avoid any non-critical\ncommits to that change anything other than the designer or docs until next Tuesday.\nNotice that plugins etc. move at their own pace and are a separate entity from the release cycle.\nWe introduce a 3.4 branch into the git repository so you can reference the 3.4 version in the future. For critical\nissues that must be introduced to the 3.4 release we review each commits and merge it into the 3.4 branch.\nCommits will not go directly into the 3.4 branch and will instead go into the trunk where they will be cherry picked\ninto the branch.\nBecause of this we will skip the Friday releases during the actual release phase and focus on getting 3.4 out\nof the door. Once that is out we will return to our regularly scheduled release cycle.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/code-freeze-for-3-4/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/code-freeze-for-3-4/release3.4.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eToday we are going into code freeze for Codename One 3.4 which is due one week from now, because of the\u003cbr\u003e\nfast release cycle we don’t need more than a week of code freeze to stabilize our current release.\u003c/p\u003e\n\u003cp\u003eThe code freeze applies only to the Codename One libraries and ports as those are the parts that will be inherent\u003cbr\u003e\nto the release.\u003c/p\u003e\n\u003ch3 id=\"how-does-the-code-freeze-work\"\u003eHow does the Code Freeze Work?\u003c/h3\u003e\n\u003cp\u003eThe pieces of Codename One that are frozen are effectively the entire github repository with the exception\u003cbr\u003e\nof the Codename One designer and JavaDoc comments. That means that we will avoid any non-critical\u003cbr\u003e\ncommits to that change anything other than the designer or docs until next Tuesday.\u003c/p\u003e","title":"Code Freeze for 3.4"},{"content":"\nWith the latest version of the Android port we fixed a long running\nbug in gradient drawing on Android.\nGradients should now work correctly and will also be performant potentially even faster than images on Android.\nOur standing recommendation is to\navoid gradients\nas they pose a memory/performance penalty on most platforms\nand so this change raises the question of using gradients back into the forefront.\nWe gave this some thought and decided to keep our existing recommendation to avoid gradients in favor of\nimages but soften it. Performance of gradients isn’t tested as extensively across platforms, we don’t use them\nat all in our themes and so they are just not as robust as other elements.\nIn order to get gradients to perform we implemented them natively on the host OS’s which means they might look\ndifferent on the target device. This might work reasonably well but might pose issues in some cases.\nTo make matters worse our gradients are really trivial in terms of functionality. They don’t support orientation, breaks,\nalpha, paint (shapes) or a multitude of other capabilities that make gradients into a powerful tool.\nSo Why Fix Gradients? We’d like to fix gradients completely, currently our graphics capabilities still lag behind those of Java2D/FX. That’s\nnot a horrible place to be in as both of these API’s weren’t designed for todays mobile environments and their\noddities.\n__ This is true for the most part but we do have at least one thing which Java2D doesn’t have: perspective transform Eventually we think the road for API maturity is paved with small steps, fixing gradients today is just such a step\nin a long road that might lead to gradient filled shapes with complex gradient rules. At that point the decision between\nusing a gradient and an image might not be as clear cut.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/should-we-use-gradients/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/should-we-use-gradients/gradients.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWith the latest version of the Android port we fixed a long running\u003cbr\u003e\n\u003ca href=\"https://github.com/codenameone/CodenameOne/issues/1696\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ebug in gradient drawing\u003c/a\u003e on Android.\u003cbr\u003e\nGradients should now work correctly and will also be performant potentially even faster than images on Android.\u003cbr\u003e\nOur standing recommendation is to\u003cbr\u003e\n\u003ca href=\"/how-do-i---improve-application-performance-or-track-down-performance-issues.html\"\u003eavoid gradients\u003c/a\u003e\u003cbr\u003e\nas they pose a memory/performance penalty on most platforms\u003cbr\u003e\nand so this change raises the question of using gradients back into the forefront.\u003c/p\u003e\n\u003cp\u003eWe gave this some thought and decided to keep our existing recommendation to avoid gradients in favor of\u003cbr\u003e\nimages but soften it. Performance of gradients isn’t tested as extensively across platforms, we don’t use them\u003cbr\u003e\nat all in our themes and so they are just not as robust as other elements.\u003c/p\u003e","title":"Should we use Gradients?"},{"content":"\nThe jat app is very similar to whatsapp in some regards but is more oriented towards group communication\nthan SMS replacement. Over the past couple of weeks we picked it up as a great communication tool in our team.\nIt uses push notifications to notify and activates accounts via SMS. This makes it very convenient for someone\nlike myself who moves between devices constantly.\nChat is a very common use case for developers in the Codename One community which is why I chose this app\nas one of our first highlighted apps. I highly recommend playing with the app to see some of the things you\ncan do in Codename One.\nYou can see the app featured page here. You can check out the\nios version here and the\nandroid version here.\nSide menu\nActivities\n__ If you want to add your app to the featured app list just let us know here or in the discussion forum Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nStefan Eder — April 25, 2016 at 7:17 am (permalink) Apparently the app is only available in the israel app store\nShai Almog — April 26, 2016 at 4:15 am (permalink) Thanks for the headsup. I didn’t notice this when I posted this, it seems they are still in tiered beta.\nI’ll try to update when this becomes available globally.\nFabrizio Grassi — June 15, 2016 at 4:45 pm (permalink) Fabrizio Grassi says:\nHi, I would like iJobClock to be in the a featured app list, is it possible? what should I do?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/featured-app-jat-communication/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/featured-app-jat-communication/jat.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe jat app is very similar to whatsapp in some regards but is more oriented towards group communication\u003cbr\u003e\nthan SMS replacement. Over the past couple of weeks we picked it up as a great communication tool in our team.\u003cbr\u003e\nIt uses push notifications to notify and activates accounts via SMS. This makes it very convenient for someone\u003cbr\u003e\nlike myself who moves between devices constantly.\u003c/p\u003e\n\u003cp\u003eChat is a very common use case for developers in the Codename One community which is why I chose this app\u003cbr\u003e\nas one of our first highlighted apps. I highly recommend playing with the app to see some of the things you\u003cbr\u003e\ncan do in Codename One.\u003c/p\u003e","title":"Featured App – JAT Communication"},{"content":"\nThis week felt slow as we were going thru it but as I was preparing this installment I was reminded just how much\nactivity we had in stackoverflow this week.\nCodenameone : Alternative to webBrowsers This question was triggered by the desire for dynamic rich UI elements coupled with concern about\nan issue with the web browser component. It turns out that we just fixed that specific issue as we are\nmoving into the final stretch before 3.4.\nHowever, I did mention an interesting project which didn’t get much attention there,\nSteves xml view. You might want to check that out.\nRead on stackoverflow…​\nAlternative Methods in CodenameOne This is a pretty common question: \u0026ldquo;Method X is missing what should I do\u0026rdquo;, in this case the methods that\nwere missing included Scanner (to which we have no direct parallel), File, Math.pow \u0026amp; String.format.\nRead on stackoverflow…​\nSearch TextField in TableLayout We have several samples of searching within a Container hierarchy but most of them rely on the behavior of\nthe BoxLayout what if we used the TableLayout and instead of narrowing only to a specific component we want\nto leave the entire row in place.\nWith a Table we can just modify the model dynamically but a TableLayout needs some creative code:\nRead on stackoverflow…​\nIOS intercepting URLs issue Intercepting URL callbacks is challenging and always painful regardless of the road you take. We tried\nto simplify it as much as possible but the Android/iOS ways differ too much.\nRead on stackoverflow…​\nHow to Create Background Service Through AlarmManager with Codename One Native Interface? This question is a great example on why you don’t always need to reach out to the native interface wrench. You\nshould usually check if there are other options and we do have such options today.\nThis shows the importance of asking as things also change a lot. Had he asked it 6 months ago the answer would\nhave been completely different…​\nRead on stackoverflow…​\nHow to fix CodenameOne build upload error? This is a remarkably common forum question, I gave the generic answer which seemed to be incorrect in this\nparticular case!\nTurns out that this was one of those cases where caches in our servers got corrupted, so a note to developers\nwho run into this, there is a chat button on the bottom right side of all pages. Try to contact us and one of our\nsupport engineers can help with issues like that. They don’t usually answer technical questions as these\nare interns who still don’t have that experience, but they can walk you thru resolving some of these issues.\nRead on stackoverflow…​\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-ii/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-ii/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis week felt slow as we were going thru it but as I was preparing this installment I was reminded just how much\u003cbr\u003e\nactivity we had in stackoverflow this week.\u003c/p\u003e\n\u003ch3 id=\"codenameone--alternative-to-webbrowsers\"\u003eCodenameone : Alternative to webBrowsers\u003c/h3\u003e\n\u003cp\u003eThis question was triggered by the desire for dynamic rich UI elements coupled with concern about\u003cbr\u003e\nan issue with the web browser component. It turns out that we just fixed that specific issue as we are\u003cbr\u003e\nmoving into the final stretch before 3.4.\u003c/p\u003e","title":"Questions Of The Week II"},{"content":"\nAs part of our continuing effort to squash bugs for the 3.4 release date we hit two major issues, the first of which is\na long time RFE to fix PDF viewing on iOS \u0026amp; Android to work consistently.\nThis also applies to any file opening in iOS/Android which should now be trivial with the Display.execute method.\nJust use that method on any file within your home directory in FileSystemStorage\nand it should launch the native app to view that file.\nA common use case is to see a PDF file for help or guide e.g. like this:\nForm hi = new Form(\u0026quot;PDF Viewer\u0026quot;, BoxLayout.y()); Button devGuide = new Button(\u0026quot;Show PDF\u0026quot;); devGuide.addActionListener(e -\u0026gt; { FileSystemStorage fs = FileSystemStorage.getInstance(); String fileName = fs.getAppHomePath() + \u0026quot;pdf-sample.pdf\u0026quot;; if(!fs.exists(fileName)) { Util.downloadUrlToFile(\u0026quot;http://www.polyu.edu.hk/iaee/files/pdf-sample.pdf\u0026quot;, fileName, true); } Display.getInstance().execute(fileName); }); hi.add(devGuide); hi.show(); __ | The original demo used the Developer guide but since that is a 25MB download that’s probably not a good\nidea for a mobile app demo…​ Renderers On Android The other issue we tackled was with renderers\nin Android following issues with the new Android pipeline. The asynchronous\narchitecture of the newer Android pipeline made a lot of behaviors quite challenging especially for the renderer\nclass where we share the Style object for multiple component instances.\nAs part of that fix we also improved performance of scrolling further by improving caching behavior on Android.\nPart of the fix requires that all render components mark themselves properly as setCellRenderer(true). This also\napplies to nesting so if you used something like a Container renderer containing multiple child components\nyou need to call setCellRenderer(true) on all of the children. We don’t do it implicitly since that might lead to\nodd bugs where adding a child before and another child after will result in weird rendering…​\nWe intend to switch to the new Android pipeline a bit after the 3.4 release so be sure to update your renderer code\nif you use such an approach or better yet, avoid List and switch to InfiniteContainer\nor InfiniteScrollAdapter.\n__ | After publishing this Steve noted that I was quite unclear about a few of the things above so below\nare a couple of clarifications: The setCellRenderer call only applies to you if you implemented the ListCellRenderer or CellRenderer interfaces.\nIf you don’t use a List or used one of the standard lists (thru GUI builder etc.) this doesn’t apply as this is done\nimplicitly (so nothing should be done for GenericListCellRenderer, MultiList etc.).\nsetCellRenderer always improved performance in Codename One lists, however the performance improvement\nI mentioned above relates mostly to some cache misses in the rendering pipeline that we ran into while fixing\nthe issue.\nArchived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nYaakov Gesher — July 24, 2016 at 5:43 am (permalink) Yaakov Gesher says:\nHi Shai, I’ve been trying to use the execute() api and I’ve run into some unexpected behavior. It seems to try to open any local file as a pdf. It seemed from this post that it should work to open any file. If I try to open an mp3 file, for example, it should open with a media player app. But at least on Android (have yet to test on ios), even mp3 files get treated as pdfs (which obviously causes an error).\nShai Almog — July 25, 2016 at 4:38 am (permalink) Shai Almog says:\nLooking at the code I think it should work for MP3’s and I know people use it for video so it should be fine. Make sure the file extension is correct as this is important for this API.\nChris — June 7, 2017 at 6:30 pm (permalink) Chris says:\nWhere is fs.getAppHomePath() in my project. How can I find the folder where should I place the PDF file to open from the App\nShai Almog — June 8, 2017 at 5:29 am (permalink) Shai Almog says:\nIt’s not in your project. It’s a device specific path that varies from device to device. You can use Util.copy() to copy a resource file to that directory though.\nChris — June 8, 2017 at 6:27 pm (permalink) Chris says:\nThank You Shai. I have the PDF in my default package of the src folder of CN1 package. I want to open the PDf on click of a button.I’m using the following code –\nFileSystemStorage fs = FileSystemStorage.getInstance();\nfinal String homePath = fs.getAppHomePath();\nString fileName = homePath + \u0026ldquo;abc.pdf\u0026rdquo;;\nUtil.copy(fs.openInputStream(fileName), fs.openOutputStream(fileName));\nDisplay.getInstance().execute(fileName);\nThis is not working as it suppose to. All the examples are given for image saving but none of them is for PDF. In the following statement input and output streams need to have the filename or there should be any change –\nUtil.copy(fs.openInputStream(fileName), fs.openOutputStream(fileName)).\nI have tried to save it to Storage as well – Util.copy(fs.openInputStream(fileName), Storage.getInstance().createOutputStream(fileName));\nShai Almog — June 9, 2017 at 4:38 am (permalink) Shai Almog says:\nUtil.copy(Display.getInstance().getResourceAsStream(getClass(), \u0026ldquo;/abc.pdf\u0026rdquo;, fs.openOutputStream(fileName));\nBut I suggest first checking if the file already exists or maybe even a version.\nChris — June 9, 2017 at 9:04 pm (permalink) Chris says:\nPerfect. It worked !! Thanks Shai.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/open-file-rendering/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/open-file-rendering/bug.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAs part of our continuing effort to squash bugs for the 3.4 release date we hit two major issues, the first of which is\u003cbr\u003e\na long time RFE to \u003ca href=\"https://github.com/codenameone/CodenameOne/issues/1651\" target=\"_blank\" rel=\"noopener noreferrer\"\u003efix PDF viewing on iOS \u0026amp; Android to work consistently\u003c/a\u003e.\u003cbr\u003e\nThis also applies to any file opening in iOS/Android which should now be trivial with the \u003ccode\u003eDisplay.execute\u003c/code\u003e method.\u003cbr\u003e\nJust use that method on any file within your home directory in \u003ca href=\"/javadoc/com/codename1/io/FileSystemStorage/\"\u003eFileSystemStorage\u003c/a\u003e\u003cbr\u003e\nand it should launch the native app to view that file.\u003c/p\u003e","title":"Open File \u0026 Rendering"},{"content":"\nAs part of the bug fixes for the 3.4 release we fixed issue\n#1725 which was surprisingly difficult to fix…​ As part of that fix we also added a new method to TextArea\nby the name of setActAsLabel which we now implicitly call in the SpanLabel \u0026amp; SpanButton classes.\nSo why do we need that and why not just use the text area as it is?\nThere are two basic challenges in multiline strings, the first is related to the way layout managers work. Layout managers\nset the X/Y/Size of the components dynamically based on available space. This seems simple enough until we get\ninto the notion of nesting \u0026amp; changes.\nE.g. if I have a layout manager on the Form it knows that it can has the width/height of the screen to place components\nso it can arrange them based on that constraint. However, when nesting starts things start to get tricky…​\nA child container needs its parent to allocate space for it before it knows the amount of available space. But here\nlies the paradox, how much space does it need?\nFor that we have the preferred size, in the case of an image this is trivial: \u0026ldquo;the image size\u0026rdquo;. In case of a Label\nthis is trivial: \u0026ldquo;the string width\u0026rdquo;. In the case of multi-line this is hard!\nPreferred size for multi-line text depends on the size we are given. E.g. if we have enough width available we won’t\nneed to break another line but if we don’t then we’d want more height. The problem is that we decide on the space\nbefore layout is done so we don’t know the available space yet. This is called \u0026ldquo;reflow\u0026rdquo;, we ask for a specific amount of\nspace and have to \u0026ldquo;reflow\u0026rdquo; to fit what is given us.\nBrowsers handle reflow accurately which is a major reason for their slow performance as reflow is pretty\nexpensive since we have to recursively re-allocate space based on parents siblings etc.\nCodename One expects you to explicitly reflow using revalidate() or animateLayout(int) if you change the\nlayout after it is shown.\n__ Don’t invoke revalidate() on UI that isn’t shown, it’s redundant and an expensive operation! Deciding where a line of text should break is one of the most delicate tasks in terms of performance!\nString Width is Slow So up to here we understood how hard it is to do layout properly…​ But the kicker is that just calling an API like\nstringWidth in pretty much every platform on earth is surprisingly slow…​\nTo be fair this isn’t \u0026ldquo;horribly\u0026rdquo; slow but if you invoke the code as many times as you need to it becomes a problem.\nThe complexity of font rendering is tremendous and while we do cache a lot of values related to text width\nin the various implementations it is challenging since this varies a lot based on font, size and content.\nE.g. say I want to render the phrase: \u0026ldquo;Mary had a little lamb\u0026rdquo; over multiple lines. A stupid algorithm\nwould do something like checking the width of \u0026ldquo;M\u0026rdquo; then of \u0026ldquo;Ma\u0026rdquo; and \u0026ldquo;Mar\u0026rdquo; etc.\nA slightly smarter algorithm would have a simple optimization to check if \u0026ldquo;Mary had a little lamb\u0026rdquo; fits in the space\navailable and go backwards but that might be an advantage for only some of the cases.\nWe have a lot of optimizations to deal with those computational complexities and they mostly hide that issue while\nproviding some benefits but also some penalties.\n\u0026ldquo;Faking\u0026rdquo; Preferred Width TextArea effectively fakes preferred width.\nThis isn’t a bad thing as normally we want the text area to take up a decent amount of space and not necessarily the\nreal amount it needs. So when we construct a text component in Codename One we usually give it the number of\ncolumns/rows and these are used to indicate the correct preferred size value that is later used for calculations.\nThis isn’t what we want for SpanLabel. We’d like it to have the actual preferred size based on it’s text.\nSo the setActAsLabel does exactly that, provides the size based on stringWidth and it tries to ignore the row/column\nvalues when the text just occupies one line.\nNormally all of the information above shouldn’t matter to you in your day to day programming tasks,\nhowever if you run into issues such as line breaks in multi-line text areas this should give you a general understanding\nof the complexities involved. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJacques Koorts — April 28, 2016 at 3:25 pm (permalink) Jacques Koorts says:\nIn HTML they introduced width by percentage to help with this problem. So if I have two multiline labels next to each other and give them a weight (android) or percentage (html) then you help the algorithm get there faster.\nYou look at the problem from a ui designer point of view\nShai Almog — April 29, 2016 at 4:06 am (permalink) Shai Almog says:\nNope. You can specify the width in Codename One too (e.g. table layout) and it isn’t designed to help in this situation (for HTML or our case).\nWidth is in box model units (e.g. percentage) and isn’t required which means you need the hierarchy size. If you actually specify the width in pixels you are effectively disabling resolution independence.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/the-challenge-of-multiline-strings/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/the-challenge-of-multiline-strings/setActAsLabel.png\"\u003e\u003c/p\u003e\n\u003cp\u003eAs part of the bug fixes for the 3.4 release we fixed \u003ca href=\"https://github.com/codenameone/CodenameOne/issues/1725\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eissue\u003cbr\u003e\n#1725\u003c/a\u003e which was surprisingly difficult to fix…​ As part of that fix we also added a new method to \u003ccode\u003eTextArea\u003c/code\u003e\u003cbr\u003e\nby the name of \u003ccode\u003esetActAsLabel\u003c/code\u003e which we now implicitly call in the \u003ccode\u003eSpanLabel\u003c/code\u003e \u0026amp; \u003ccode\u003eSpanButton\u003c/code\u003e classes.\u003c/p\u003e\n\u003cp\u003eSo why do we need that and why not just use the text area as it is?\u003c/p\u003e\n\u003cp\u003eThere are two basic challenges in multiline strings, the first is related to the way layout managers work. Layout managers\u003cbr\u003e\nset the X/Y/Size of the components dynamically based on available space. This seems simple enough until we get\u003cbr\u003e\ninto the notion of nesting \u0026amp; changes.\u003c/p\u003e","title":"The Challenge of Multiline Strings"},{"content":"\nAs I mentioned last week we are redoing a lot of our videos and this video will serve as a benchmark to where we\nwant to be in terms of production. We just released a modified version of the video geared towards IntelliJ/IDEA\nusers here.\nWe are really excited about the new IntelliJ/IDEA plugin we released a couple of weeks\nago and this video shows off some of it’s capabilities.\nIn other news we are getting ready for the 3.4 release which is rapidly approaching. This will be a very conservative\nrelease that won’t feature any big changes as much as a refinement of the product. Having said that I’m still\nvery excited about this release as I think refinement is probably the most important feature we need bar none!\nWe will enter code freeze next week, this will still allow for some changes e.g. bug fixes etc.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-getting-started-video-intellij-idea-version/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-getting-started-video-intellij-idea-version/hello-codenameone-idea.png\"\u003e\u003c/p\u003e\n\u003cp\u003eAs I mentioned last week we are redoing a lot of our videos and this video will serve as a benchmark to where we\u003cbr\u003e\nwant to be in terms of production. We just released a modified version of the video geared towards IntelliJ/IDEA\u003cbr\u003e\nusers \u003ca href=\"/how-do-i---create-a-basic-hello-world-application%e2%80%94%e2%80%8bsend-it-to-my-device-using-intellij-idea.html\"\u003ehere\u003c/a\u003e.\u003cbr\u003e\nWe are really excited about the \u003ca href=\"/blog/a-new-idea/\"\u003enew IntelliJ/IDEA plugin\u003c/a\u003e we released a couple of weeks\u003cbr\u003e\nago and this video shows off some of it’s capabilities.\u003c/p\u003e","title":"New Getting Started Video – IntelliJ/IDEA Version"},{"content":"\nOne of the hard things to debug in Codename One is UIID/Padding/Margin placement which is often tricky to\nget \u0026ldquo;just right\u0026rdquo;. I use the Component Inspector quite a lot to\nreview a layout that misbehaves and gain further insight into what’s happening in runtime.\n__ | You can gain insight into the Codename One component hierarchy by running the simulator and selecting the\nSimulate → Component Inspector menu option. This will present the component hierarchy as a navigatable tree Up until now the Component Inspector was a \u0026ldquo;read only\u0026rdquo; tool, with the coming update it will gain the ability to edit\nthe UIID field!\nThis would make some things remarkably trivial as you could find if that pesky extra space is coming from the theme\nby just changing the UIID to Container. It also helps identify components more easily within the inspector and\nsee under the hood of Codename One (e.g. in the Toolbar\narea).\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/edit-udid-in-component-inspector/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/edit-udid-in-component-inspector/edit-udid.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the hard things to debug in Codename One is UIID/Padding/Margin placement which is often tricky to\u003cbr\u003e\nget \u0026ldquo;just right\u0026rdquo;. I use the \u003ca href=\"/manual/index/\"\u003eComponent Inspector\u003c/a\u003e quite a lot to\u003cbr\u003e\nreview a layout that misbehaves and gain further insight into what’s happening in runtime.\u003c/p\u003e\n\u003cp\u003e__ |  You can gain insight into the Codename One component hierarchy by running the simulator and selecting the\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eSimulate → Component Inspector menu option. This will present the component hierarchy as a navigatable tree\u003c/th\u003e\n          \u003cth\u003e\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eUp until now the Component Inspector was a \u0026ldquo;read only\u0026rdquo; tool, with the coming update it will gain the ability to edit\u003cbr\u003e\nthe UIID field!\u003c/p\u003e","title":"Edit UDID in Component Inspector"},{"content":"\nWhen we first started to present Codename One to investors a very prominent local investor said he’d commit\nto a round of funding if we allow Android developers to import native Android apps to Codename One. We passed\non that which in retrospect might have been a mistake but the technical challenges were the main reason for\nthat decision.\nShould we Support Android Native Code? Ignoring the technical issues involved this might seem like a \u0026ldquo;no brainer\u0026rdquo; for Android developers. But history teaches\nus otherwise…​\nQuite often when a platform offers compatibility it serves to make it irrelevant rather than promote it. A famous\nexample of such a platform is OS/2 which was marketed as: \u0026ldquo;Better Windows than Windows and better DOS than DOS\u0026rdquo;.\n__ It is debatable whether OS/2 failed because or despite its choice to focus on compatibility. The question becomes more muddled if we do a lousy job of importing. Compatibility to Android is not realistically\nfeasible for elaborate apps. Android is remarkably complex and nuanced, activities have no equivalent in other\nOS’s and the UI paradigms of Android are \u0026ldquo;unique\u0026rdquo;.\nWould an import that is \u0026ldquo;bad\u0026rdquo; be better than nothing? We are currently at the \u0026ldquo;probably mindset\u0026rdquo;.\nSo while we can’t say that this is a \u0026ldquo;good thing\u0026rdquo; we’d rather have something\nin place. Even if that \u0026ldquo;something\u0026rdquo; is broken, partial and problematic.\nWe already support importing Android string bundles into the localization section in the Codename One designer,\nthis is quite useful as you can send string bundles to localization services rather easily.\n__ | Most localization services also support Java properties files but do so badly as most of them didn’t really\nread the spec We think the \u0026ldquo;right thing\u0026rdquo; to do in the case of Android is to import only the XML files and resources and ignore\nthe Java code which you would need to migrate manually (as there are no activities etc.). Codename One has\nthe theoretically perfect destinations, the resource files can serve as a great destination for the res files.\nThe XML’s can be imported directly into the XML file format used by the new GUI builder.\nHowever, the technical aspects are challenging to say the least!\nThis is a REMARKABLY Difficult Task Codename One’s roots predated Android. We started working on the predecessor of Codename One at Sun in\n2007. This was before the iPhone announcement and before the Android announcement.\nWhile todays product looks completely different from its original version a lot of the API design decisions are\ndifferent and hard to adapt. Android’s layout system has many parallels to our layout system as both are inspired\nby previous work in the same field, but Android’s layouts are far more complex with many small nuances.\nSpecifically we chose to keep the layout system as simple as possible telling the users to \u0026ldquo;just nest\u0026rdquo;. Android\ndevelopers took the opposite approach of adding flags to customize layout behaviors deeply. This means that\na lot of Android layouts have no direct Codename One equivalents…​ So we would need to translate a flat layout\ninto a hierarchy which isn’t always trivial and might result in issues.\nBecause the Android implementation is so large supporting all of those nuances would be challenging.\nThe style system in Android is also quite different from our approach to theming and this also poses some challenges.\nWhile we do have some support for the Android style 9-patch borders (which differ from our 9-piece borders)\nthere is no UI tooling to edit such borders in Codename One.\nWill we Ever do This? We really want to do this. We think it will provide a lot of value to many developers and help us reach a larger\nmarket share even if it’s badly implemented.\nUnfortunately, a lot needs to happen first for this to be viable so it’s relatively low in the list of priorities at this time.\nSo before we see a stable version of Windows, GUI builder etc. this probably won’t happen. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nScott Turner — April 22, 2017 at 6:21 pm (permalink) Scott Turner says:\nI think that’s fair. Focus on the low hanging fruit first before tackling such a large and complex problem. This translation tool is probably something that would eat up all of your resources for the forseeable future, and isn’t a guaranteed return on investment. Good business sense to steer clear for now.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/why-we-dont-import-android-native-code/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/why-we-dont-import-android-native-code/android_studio.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen we first started to present Codename One to investors a very prominent local investor said he’d commit\u003cbr\u003e\nto a round of funding if we allow Android developers to import native Android apps to Codename One. We passed\u003cbr\u003e\non that which in retrospect might have been a mistake but the technical challenges were the main reason for\u003cbr\u003e\nthat decision.\u003c/p\u003e\n\u003ch3 id=\"should-we-support-android-native-code\"\u003eShould we Support Android Native Code?\u003c/h3\u003e\n\u003cp\u003eIgnoring the technical issues involved this might seem like a \u0026ldquo;no brainer\u0026rdquo; for Android developers. But history teaches\u003cbr\u003e\nus otherwise…​\u003c/p\u003e","title":"Why we Don't Import Android Native Code?"},{"content":"\nI’d like to start a new weekly installment for the blog: \u0026ldquo;questions of the week\u0026rdquo;. I hope to have this as a regular\nFriday post to coincide with the Friday release process. The general idea of this post is to bring to your attention\nour answers to some stack overflow questions that might be helpful for the general community.\nWe spend a lot of time answering stackoverflow questions and some of them are pretty elaborate, e.g\n\u0026ldquo;How Does Codename One Work?\u0026rdquo;\nis my highest rated answer and might be illuminating to many developers who are new to Codename One.\nA lot of us don’t have the time to follow all the questions and the answers but if presented with the questions/answers\nthis might be interesting and also raise new questions of your own. I hope it will also help you use stack overflow\nin a more productive way as it is a pretty powerful tool when used correctly.\nIs it possible to generate an app with different icons for iOS/Android? Notice that I asked/answered the question. When we get pro-support emails that we think would be of value\nto the community we try to give the answer in a way that will be useful for everyone.\nRead on stackoverflow…​\nios.includePush keeps resetting to false in NetBeans This long running issue relates to a simplification where we provided UI components instead of build hints to\nperform some tasks. Turns out that adding a GUI to do a task sometimes makes it harder…​\nRead on stackoverflow…​\nHow to share a link to your app? This is a very common use case, the native share functionality is crucial for viral application growth but it requires\nanother small step to scale reasonable for a cross platform framework.\nRead on stackoverflow…​\nHow can I dynamically change the UIID for the commands that go in the toolbar? The question is phrased against the stackoverflow standards, specifically you usually need to write what you tried\nfirst otherwise your question might be closed.\nThis is something that I’m guessing a lot of people don’t know which is why I chose to include it.\nRead on stackoverflow…​\nFriday Release We are updating both the IntelliJ/IDEA plugin and the\nNetBeans plugin this week with some minor bug fixes and\nenhancements.\nDon’t forget to give us a 5 star rating in the plugin page for your respective IDE \u0026amp; if you don’t think we earned a\n5 star rating then let us know why in the comments section below!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/questions-of-the-week-i-different-icons-setting-includepush-sharing-app-links-command-uiid/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/questions-of-the-week-i-different-icons-setting-includepush-sharing-app-links-command-uiid/qanda-friday.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’d like to start a new weekly installment for the blog: \u0026ldquo;questions of the week\u0026rdquo;. I hope to have this as a regular\u003cbr\u003e\nFriday post to coincide with the Friday release process. The general idea of this post is to bring to your attention\u003cbr\u003e\nour answers to some stack overflow questions that might be helpful for the general community.\u003c/p\u003e\n\u003cp\u003eWe spend a lot of time answering stackoverflow questions and some of them are pretty elaborate, e.g\u003cbr\u003e\n\u003ca href=\"http://stackoverflow.com/questions/10639766/how-does-codename-one-work/10646336\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u0026ldquo;How Does Codename One Work?\u0026rdquo;\u003c/a\u003e\u003cbr\u003e\nis my highest rated answer and might be illuminating to many developers who are new to Codename One.\u003c/p\u003e","title":"Questions Of The Week I"},{"content":"\nWe just published a new introduction to Codename One video, that we hope will set the bar for future videos from\nus (or at lease set the bar for the more important videos). This initial one is focused on NetBeans but we intend\nto publish similar videos for IntelliJ/Eclipse shortly. You can check out this video in the How Do I section\nright here.\nfor your convenience we also embedded the video below but the transcript is only within the\nvideo page\nVideos Moving Forward While we still have some work to do on the written docs we now consider them to be \u0026ldquo;done\u0026rdquo; in terms of base level\nquality which means we need to update our aging set of videos. We started with the hello world videos because\nthey serve as the first impression a developer gets from Codename One and should be sublime.\nIf there are specific videos you feel are missing or badly done and need a rework please let us know in the comments\nas this is probably the best time to ask for such work. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — April 19, 2016 at 3:26 pm (permalink) Chidiebere Okwudire says:\nNice. I’d love to see move video tutorials for GUI-builder based apps. Preferably, tutorials should highlight how things can be done in the GUI builder vs. manually in code.\nShai Almog — April 20, 2016 at 4:00 am (permalink) Shai Almog says:\nUs too. We are waiting on the GUI builder to be rock solid to focus more on tutorials that cover it.\nWe are trying to get it to that state for 3.4 which is a tall order for 2 weeks but we are working heavily on that. Once it’s done we’ll write a lot more about it.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-getting-started-video/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-getting-started-video/hello-codenameone-revisited.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe just published a new introduction to Codename One video, that we hope will set the bar for future videos from\u003cbr\u003e\nus (or at lease set the bar for the more important videos). This initial one is focused on NetBeans but we intend\u003cbr\u003e\nto publish similar videos for IntelliJ/Eclipse shortly. You can check out this video in the \u003ca href=\"/how-do-i.html\"\u003eHow Do I section\u003c/a\u003e\u003cbr\u003e\nright \u003ca href=\"/how-do-i---create-a-basic-hello-world-application%e2%80%94%e2%80%8bsend-it-to-my-device-using-netbeans.html\"\u003ehere\u003c/a\u003e.\u003cbr\u003e\nfor your convenience we also embedded the video below but the transcript is only within the\u003cbr\u003e\n\u003ca href=\"/how-do-i---create-a-basic-hello-world-application%e2%80%94%e2%80%8bsend-it-to-my-device-using-netbeans.html\"\u003evideo page\u003c/a\u003e\u003c/p\u003e","title":"New Getting Started Video"},{"content":"\nIn our original Java 8 support announcement post we specifically mentioned the\nlack of streams but completely missed the fact that default/static native interfaces didn’t work. This is now fixed\nthanks to an alert community member who pointed that out.\nIt seems that these features are turned off by default for retrolambda\ndue to limitations that require a clean build to get them to work. This is no limitation for the Codename One\nbuild server architecture so these features should work just fine for Codename One apps.\nWhat are Default Interface Methods? Default interface methods allow you to add new methods to an interface and provide a default implementation.\nThis effectively enables us to move an API forward without breaking compatibility with someone who implemented\nthis interface. E.g. :\npublic interface DefaultInterfaceTest { String method(); default String methodWithArg(String arg) { return method(); } } This isn’t as important for most developers as we normally can just add a new method and solve the issue.\nHowever, in the future as we move the implementation of Codename One to Java 8 syntax this will be a huge\nboost as it will allow us to add methods to older interfaces such as PushCallback.\nWhat are Static Interface Methods Static interface methods are generally just static methods. In many cases we just hide static methods within\nclases but sometimes that doesn’t make sense. E.g. the Push class\nis entirely composed of static methods and doesn’t make much sense as a standalone class. We could have\nrolled all the methods within the class into the interface as static methods and eliminated the class entirely.\nThis isn’t necessarily \u0026ldquo;good practice\u0026rdquo; but for some use cases this might be a better place to hold the method.\nE.g.:\npublic interface StaticInterfaceTest { String method(); static String getNotNull(StaticInterfaceTest it, String def) { String s = it.method(); if(s == null) return def; return s; } } You can read about default and static interface methods in the Java Tutorial.\nSwitch to Full Java 8? As implied above we would get quite a bit of value from switching the code base of Codename One itself to Java 8.\nRight now we still support building Java 5 apps and would probably not change that before 3.4 rolls out as our\ncurrent goals are stability more than anything else. However, once 3.4 rolls out we might implicitly make all\nbuilds use Java 8 features and switch the internal code base to use it.\nEven if you use an old Java 5 project the builds should still work fine after such a transition and you won’t be forced\nto switch, however, this will allow us to use features such as default methods to implement some capabilities we\nneed. It will also make out lives slightly easier by allowing us to use lambdas in our core implementation.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/default-static-methods-in-interfaces/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/default-static-methods-in-interfaces/java-8-lambada.png\"\u003e\u003c/p\u003e\n\u003cp\u003eIn our original \u003ca href=\"/blog/java-8-support.html\"\u003eJava 8 support announcement\u003c/a\u003e post we specifically mentioned the\u003cbr\u003e\nlack of streams but completely missed the fact that default/static native interfaces didn’t work. This is now fixed\u003cbr\u003e\nthanks to an alert community member who pointed that out.\u003c/p\u003e\n\u003cp\u003eIt seems that these features are turned off by default for \u003ca href=\"https://github.com/orfjackal/retrolambda\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eretrolambda\u003c/a\u003e\u003cbr\u003e\ndue to limitations that require a clean build to get them to work. This is no limitation for the Codename One\u003cbr\u003e\nbuild server architecture so these features should work just fine for Codename One apps.\u003c/p\u003e","title":"Default \u0026 Static Methods In Interfaces"},{"content":"\nSteve committed the upcoming Windows port to out github repository\nit’s still work in progress so you can’t physically target it as part of the build system although we hope to move\nthis port out relatively quickly. This should be more doable thanks to the iKVM route\n\u0026amp; the work from Fabricio both of which saved a lot of the effort in this port.\nYou can take a look at this port if you are Windows inclined and let us know what you think.\nIntelliJ IDEA Update So far the plugin rewrite went more smoothly than our worst fear. We did have to issue an update to a regression\nthat caused the wrong UI to load sometime for the designer/settings panel/gui builder. If you are using version\n3.3.1 at this time you are up to date.\nOne thing we neglected to mention in the announcement is that you need Java 8 or the plugin won’t even show up.\nWe only tested on IntelliJ 16 so please try to use that version with Java 8.\nEnum Values One of the long time ParparVM issues has been\nthe usage of enums in iOS. Enum compilation triggers some reflection code under the hood to support capabilities\nsuch as values() and those just didn’t translate into C code properly.\nSteve took on that issue and now code such as this:\nfor(MyEnum e : MyEnum.values()) { ... } Should work just fine for iOS compilation too.\nContactsManager Refresh We added a bit of a hack to solve an iOS issue with contacts based on a request from an enterprise developer.\nIt seems that in iOS when you have a list of contacts and you minimize the application to add a new contact,\nthe list won’t be refreshed even if you re-invoke getAllContacts().\niOS caches the data for the contacts and we need to explicitly refresh the list using\nContactsManager.refresh()\nwhich you can call in the start() method in case the app is being restored. This method won’t do anything\nin other platforms but if you need it then it’s pretty valuable.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/windows-idea-enum-values-contactsmanager-refresh/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/windows-idea-enum-values-contactsmanager-refresh/generic-java-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSteve committed the \u003ca href=\"https://github.com/codenameone/CodenameOne/tree/master/Ports/UWP/VSProjectTemplate\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eupcoming Windows port to out github repository\u003c/a\u003e\u003cbr\u003e\nit’s still work in progress so you can’t physically target it as part of the build system although we hope to move\u003cbr\u003e\nthis port out relatively quickly. This should be more doable thanks to the \u003ca href=\"/blog/new-windows-port/\"\u003eiKVM route\u003c/a\u003e\u003cbr\u003e\n\u0026amp; the \u003ca href=\"https://github.com/Pmovil/CN1WindowsPort\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ework from Fabricio\u003c/a\u003e both of which saved a lot of the effort in this port.\u003c/p\u003e\n\u003cp\u003eYou can take a look at this port if you are Windows inclined and let us know what you think.\u003c/p\u003e","title":"Windows, IDEA, Enum Values \u0026 ContactsManager Refresh"},{"content":"\nOur current IntelliJ/IDEA plugin is seriously behind the times. In our recent survey it was very easy to spot\nIDEA developers who were significantly less satisfied with Codename One than the rest of the developer community.\nThe IDEA plugin doesn’t include basic capabilities such as:\nJava 8 Support\nThe New GUI builder\nNew Default application look/themes/icon\nBuiltin demo apps\nThe Generate Native Access functionality\nThe certificate wizard and a lot of the UI within the preferences\nA New Direction The old plugin was developed by an excellent hacker who did a great job, but even the best code rots when\nit is unmaintained. Worse, Jetbrains made some big changes between version 12 and now. The old plugin couldn’t\nbe compiled on the newer versions and exhibits odd bugs when running on newer versions of IDEA.\nWe decided to rewrite the plugin from the ground up and discard a lot of the legacy both in terms of the plugin\nand in terms of Codename One functionality.\nThe main goal of this rewrite is reduction in code so we can have a very lean plugin with as much shared code\nas possible. For that purpose the templates and builtin files are literally taken from the NetBeans plugin to facilitate\nas much reuse as possible and allow for one release cycle to encapsulate everything.\nJava 8+ IntelliJ/IDEA 16+ The new plugin will only work on Java 8 or newer VM’s and will implicitly create Java 8 projects.\nSupporting legacy project structures doesn’t make sense for the new plugin although you could manually set that\nin the generated project, this is probably unnecessary.\nNew Preferences This might be the most controversial decision we’ve made with this plugin. Instead of using the native IDE\nmenu we chose to use the right click menu for a lot of features including our own preferences UI:\nFigure 1. The preferences as well as other options are in the right click menu instead of the native IDE menu\nThis launches a custom preferences UI written using Codename One that looks like this:\nFigure 2. Preferences UI written in Codename One\nFigure 3. Preferences UI under the basics section\nThe value of writing the preferences UI using the Codename One API is that it makes the maintenance of this\ncode far easier when compared to IDE specific code. A lot of features aren’t mapped to UI within the plugins\nat this time because it’s just too much of a hassle to do this 3x times for every OS/platform. Right now we\nhave an internal debate on whether this should be the approach we take for all platforms, in the long run I think\nthis would be superior to using the IDE native preferences UI.\nThe new preferences also allow us to integrate deeply with capabilities such as the iOS certificate wizard\nwhich has the best most fluent integration in IntelliJ/IDEA. Personally I think it looks modern and better than the\nIDE integrated approach.\nThe New GUI Builder Support for the new GUI builder is builtin, as the builder is still in beta I’ll leave this as a somewhat \u0026ldquo;undocumented feature\u0026rdquo;\nuntil we finish that work. I would like to mention though that the integration injects code directly to the AST and\ndynamically updates it when the gui XML file is saved.\nNormally the GUI builder updates the sources via the ant task but we could find no way to do this in IntelliJ that\ndidn’t break basic things.\nVideo I’ve made a quick walkthru video of the new plugin, check it out:\nMigration \u0026amp; Availability While we belive this should be maintained across versions we can’t be 100% sure about this. As with all rewrites\nregressions probably exist. We will release the new plugin this Friday as part of our standard Friday release cycle.\nIf you run into regressions we suggest creating a new project with the new plugin and migrating your code/settings\nby copying them to the new plugin. Be sure to let us know immediately if you run into such issues. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nTherk — April 13, 2016 at 11:42 pm (permalink) Thank you for improving the plugin. It is more intuitive even though it may not be consistent with other IntelliJ plugins. Unfortunately, I started to get a NullPointerException when setting up the Run configuration for a new sample application.\nI am not sure the best way to report such issues, but the stack trace is:\njava.lang.NullPointerException\nat com.codename1.plugin.intellij.run.CodenameOneRunConfigurationEditor.initComponent(CodenameOneRunConfiguration…:31)\nat com.codename1.plugin.intellij.run.CodenameOneRunConfigurationEditor.(CodenameOneRunConfiguration…:27)\nat com.codename1.plugin.intellij.run.CodenameOneRunConfiguration.getConfigurationEditor(CodenameOneRunConfiguration…:225)\nat com.intellij.execution.impl.ConfigurationSettingsEditor.(ConfigurationSettingsEditor…:220)\nat com.intellij.execution.impl.ConfigurationSettingsEditorWrapper.(ConfigurationSettingsEditor…:67)\nat com.intellij.execution.impl.SingleConfigurationConfigurable.(SingleConfigurationConfigur…:65)\nat com.intellij.execution.impl.SingleConfigurationConfigurable.editSettings(SingleConfigurationConfigur…:99)\nat com.intellij.execution.impl.RunConfigurable.a(RunConfigurable.java:1090)\nat com.intellij.execution.impl.RunConfigurable.createNewConfiguration(RunConfigurable.java:1123)\nat com.intellij.execution.impl.RunConfigurable$MyToolbarAddAction$2.consume(RunConfigurable.java:1161)\nat com.intellij.execution.impl.RunConfigurable$MyToolbarAddAction$2.consume(RunConfigurable.java:1158)\nat com.intellij.execution.impl.NewRunConfigurationPopup$1.onChosen(NewRunConfigurationPopup.java:82)\nat com.intellij.execution.impl.NewRunConfigurationPopup$1.onChosen(NewRunConfigurationPopup.java:48)\nat com.intellij.ui.popup.list.ListPopupImpl.a(ListPopupImpl.java:386)\nat com.intellij.ui.popup.list.ListPopupImpl.handleSelect(ListPopupImpl.java:346)\nat com.intellij.ui.popup.list.ListPopupImpl$MyMouseListener.mouseReleased(ListPopupImpl.java:476)\nat java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:290)\nat java.awt.Component.processMouseEvent(Component.java:6535)\nat javax.swing.JComponent.processMouseEvent(JComponent.java:3324)\nat com.intellij.ui.popup.list.ListPopupImpl$MyList.processMouseEvent(ListPopupImpl.java:542)\nat java.awt.Component.processEvent(Component.java:6300)\nat java.awt.Container.processEvent(Container.java:2236)\nat java.awt.Component.dispatchEventImpl(Component.java:4891)\nat java.awt.Container.dispatchEventImpl(Container.java:2294)\nat java.awt.Component.dispatchEvent(Component.java:4713)\nat java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)\nat java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)\nat java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)\nat java.awt.Container.dispatchEventImpl(Container.java:2280)\nat java.awt.Window.dispatchEventImpl(Window.java:2750)\nat java.awt.Component.dispatchEvent(Component.java:4713)\nat java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)\nat java.awt.EventQueue.access$500(EventQueue.java:97)\nat java.awt.EventQueue$[3.run](http://3.run)([EventQueue.java](http://EventQueue.java):709)\nat java.awt.EventQueue$[3.run](http://3.run)([EventQueue.java](http://EventQueue.java):703)\nat java.security.AccessController.doPrivileged(Native Method)\nat java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)\nat java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)\nat java.awt.EventQueue$[4.run](http://4.run)([EventQueue.java](http://EventQueue.java):731)\nat java.awt.EventQueue$[4.run](http://4.run)([EventQueue.java](http://EventQueue.java):729)\nat java.security.AccessController.doPrivileged(Native Method)\nat java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)\nat java.awt.EventQueue.dispatchEvent(EventQueue.java:728)\nat com.intellij.ide.IdeEventQueue.h(IdeEventQueue.java:857)\nat com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:654)\nat com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:386)\nat java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)\nat java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)\nat java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:109)\nat java.awt.WaitDispatchSupport$[2.run](http://2.run)([WaitDispatchSupport.java](http://WaitDispatchSupport.java):184)\nat java.awt.WaitDispatchSupport$[4.run](http://4.run)([WaitDispatchSupport.java](http://WaitDispatchSupport.java):229)\nat java.awt.WaitDispatchSupport$[4.run](http://4.run)([WaitDispatchSupport.java](http://WaitDispatchSupport.java):227)\nat java.security.AccessController.doPrivileged(Native Method)\nat java.awt.WaitDispatchSupport.enter(WaitDispatchSupport.java:227)\nat [java.awt.Dialog.show](http://java.awt.Dialog.show)([Dialog.java](http://Dialog.java):1084)\nat com.intellij.openapi.ui.impl.DialogWrapperPeerImpl$[MyDialog.show](http://MyDialog.show)([DialogWrapperPeerImpl.java](http://DialogWrapperPeerImpl.java):792)\nat [com.intellij.openapi.ui.imp…](http://com.intellij.openapi.ui.impl.DialogWrapperPeerImpl.show)([DialogWrapperPeerImpl.java](http://DialogWrapperPeerImpl.java):465)\nat com.intellij.openapi.ui.DialogWrapper.invokeShow(DialogWrapper.java:1661)\nat [com.intellij.openapi.ui.Dia…](http://com.intellij.openapi.ui.DialogWrapper.show)([DialogWrapper.java](http://DialogWrapper.java):1610)\nat com.intellij.openapi.options.ex.SingleConfigurableEditor.access$001(SingleConfigurableEditor.java:45)\nat com.intellij.openapi.options.ex.SingleConfigurableEditor$[1.run](http://1.run)([SingleConfigurableEditor.java](http://SingleConfigurableEditor.java):130)\nat com.intellij.openapi.project.DumbPermissionServiceImpl.allowStartingDumbModeInside(DumbPermissionServiceImpl.java:31)\nat com.intellij.openapi.project.DumbService.allowStartingDumbModeInside(DumbService.java:283)\nat [com.intellij.openapi.option…](http://com.intellij.openapi.options.ex.SingleConfigurableEditor.show)([SingleConfigurableEditor.java](http://SingleConfigurableEditor.java):127)\nat com.intellij.execution.impl.EditConfigurationsDialog.access$001(EditConfigurationsDialog.java:33)\nat com.intellij.execution.impl.EditConfigurationsDialog$[1.run](http://1.run)([EditConfigurationsDialog.java](http://EditConfigurationsDialog.java):57)\nat com.intellij.openapi.project.DumbPermissionServiceImpl.allowStartingDumbModeInside(DumbPermissionServiceImpl.java:37)\nat com.intellij.openapi.project.DumbService.allowStartingDumbModeInside(DumbService.java:283)\nat [com.intellij.execution.impl…](http://com.intellij.execution.impl.EditConfigurationsDialog.show)([EditConfigurationsDialog.java](http://EditConfigurationsDialog.java):54)\nat com.intellij.openapi.ui.DialogWrapper.showAndGet(DialogWrapper.java:1625)\nat com.intellij.execution.actions.ChooseRunConfigurationPopup$8.perform(ChooseRunConfigurationPopup…:974)\nat com.intellij.execution.actions.ChooseRunConfigurationPopup$ConfigurationListPopupStep$[2.run](http://2.run)([ChooseRunConfigurationPopup…](http://ChooseRunConfigurationPopup.java):500)\nat java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)\nat java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)\nat java.awt.EventQueue.access$500(EventQueue.java:97)\nat java.awt.EventQueue$[3.run](http://3.run)([EventQueue.java](http://EventQueue.java):709)\nat java.awt.EventQueue$[3.run](http://3.run)([EventQueue.java](http://EventQueue.java):703)\nat java.security.AccessController.doPrivileged(Native Method)\nat java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)\nat java.awt.EventQueue.dispatchEvent(EventQueue.java:726)\nat com.intellij.ide.IdeEventQueue.h(IdeEventQueue.java:857)\nat com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:658)\nat com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:386)\nat java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)\nat java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)\nat java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)\nat java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)\nat java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)\nat [java.awt.EventDispatchThrea…](http://java.awt.EventDispatchThread.run)([EventDispatchThread.java](http://EventDispatchThread.java):82)\nTherk — April 14, 2016 at 12:21 am (permalink) A few suggestion on improving the IDEA plugin:\n1. In the Codename One Preferences, tabbing between fields does not seem to work, requiring a mouse click into next fields. For example in the Login or iOS Certificate Wizard.\n2. It is unclear if user is logged in. It would be good to show login email under Login icon if login was successful.\n3. Adding certificate, revokes existing certificate. It prompts \u0026ldquo;Your iTunes account already has an iOS appstore certificate. Would you like to overwrite it?\u0026rdquo;. If I click ‘No’, then no certificate is used. It would also help to know that old certificate will be revoked in the message.\n4. The iOS Certificate Wizard, tried to create certificate for each device.\n5. In the device list of iOS Certificate Wizard, showing Identifier would be helpful.\n6. It should allow to select existing App ID and name for an application.\n7. Under Global Preferences and iOS Certificate Wizard, App ID and name should probably not be required, as I think Global Preferences are to be shared between other CodenameOne application.\nShai Almog — April 14, 2016 at 2:36 am (permalink) Thanks!\nThose are great issues/RFE’s.\nThe right place to file them so they don’t get lost under our workload is the issue tracker at http://github.com/codenameo…\nShai Almog — April 14, 2016 at 8:08 am (permalink) Shai Almog says:\nLooking a bit further on this:\n4. Are you sure about this? It just adds the device to the provisioning profile.\n6. It should have the existing app id from your app which must match the package name of your project.\n7. The global version of the wizard should allow you to customize the app id as it can be a * certificate but it can reside anywhere e.g. I can make a com.mycompany.* or just plain * as my default. This matters to the provisioning profile.\nShai Almog — April 14, 2016 at 8:14 am (permalink) Shai Almog says:\nHow do you set the run configuration?\nI see the problem but I can’t reproduce it to make sure the fix is correct.\nEric Coolman — April 28, 2016 at 9:50 pm (permalink) Eric Coolman says:\nGreat work, and thanks! 🙂\nJames van Kessel — May 20, 2016 at 3:56 pm (permalink) James van Kessel says:\nHi Shai, For someone with an existing project, are there any warnings or cautions you’d give someone still using an older CN1 plugin (i am still on 3.1) before clicking \u0026ldquo;update Plugin\u0026rdquo;?\nShai Almog — May 21, 2016 at 3:51 am (permalink) Shai Almog says:\nIf you update to the latest it will be the new plugin and there is no warning. Notice that on the plugin page at IDEA you can always download the older versions of the plugin if you need it while we fix a potential issue you might run into.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/a-new-idea/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/a-new-idea/a-new-idea.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOur current IntelliJ/IDEA plugin is seriously behind the times. In our recent survey it was very easy to spot\u003cbr\u003e\nIDEA developers who were significantly less satisfied with Codename One than the rest of the developer community.\u003cbr\u003e\nThe IDEA plugin doesn’t include basic capabilities such as:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eJava 8 Support\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eThe New GUI builder\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eNew Default application look/themes/icon\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eBuiltin demo apps\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eThe Generate Native Access functionality\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eThe certificate wizard and a lot of the UI within the preferences\u003c/p\u003e","title":"A New Idea"},{"content":"\nOur existing Windows Phone port has already gone thru 3 rewrites and a community rewrite and we are hard\nat work on the 4th rewrite (or 5th counting the community port). However, we decided to take a radically different\ndirection with the new port and with backwards compatibility to allow better scale.\nSo lets start with the \u0026ldquo;bad news\u0026rdquo; and follow by an explanation of why and how we plan to do that.\nDropping Windows Phone 8 Support We will focus on Windows 10 and Universal Windows platform.\nThis means applications will run seamlessly on\ntablets/desktops \u0026amp; phones within the \u0026ldquo;new UI\u0026rdquo; and would be sellable via the Windows Store without any special\ntrickery.\nHowever, this new packaging isn’t compatible with the old Windows Phone 8 API’s. Most newer devices are upgradable\nto 10 so this shouldn’t be a huge deal and the benefits far outweigh the pain.\nWhat to do If We Still Need Windows Phone 8 Support? If there is demand for building on top of the old port (e.g. for compatibility with the work from Fabricio)\nwe will include a special way to get the sources of a Windows Phone project built dynamically. You will need\na windows machine with visual studio to compile them and work with them.\nThe reason for this complexity is explained below.\nThe New Approach: iKVM Our existing Windows Phone port is based on a very experimental and partially broken branch of XMLVM. When\nwe originally developed this port we tried 4 different tools all of which failed completely and XMLVM was the\nleast broken among them.\nBack in those days (Windows Phone 7.5) only C# or .net managed languages were supported so using C or other\nlanguages for the VM wasn’t an option. Windows Phone 8 introduced some capabilities in this regard so we considered\na port of ParparVM. Up until recently it seemed like the only option.\nIn the past we briefly reviewed iKVM which translates Java bytecode to .net assemblies. This\nseemed like the ideal solution but due to the Windows environment restrictions it didn’t support Windows Phone.\nHowever, with Windows 10 we thought it’s a good time to re-evaluate that and saw some mentions of developers\nwho were successful in getting it to work. Thankfully over the weekend Steve made a break-thru and was able to\nget iKVM to work with universal windows applications. While this took a lot of effort this reduced the complexity\nof the overall port by at least 10 man months!\nThe work is far from done but we are on a solid path and once we have a stable build server process I think we would\nbe able to move really quickly.\nThe port itself (which is on top of the VM used) is based on the work that Fabcio did and will remain open source\ntogether with the forked changes we needed to get iKVM to work.\nHow Will it Differ From the Existing Port? iKVM generates assemblies (.nets DLLs). This effectively means that the port will look more like the Android port\nand less like the iOS port (or the existing Windows Phone port).\nThe old Windows Phone XMLVM port translated the bytecode into C# code so for every class file you had in the\njava bytecode you would have a C# file with all the same methods. This would produce a large project containing\nall your translated code.\niKVM translates the bytecode to .net and doesn’t include any source. So you will have a project you can run in the IDE\nbut you won’t be able to really debug it in the sense that you can debug iOS builds. This has some drawbacks but it\ndoes produce a very fast build process.\nReliability \u0026amp; Continuity One of the big problems with Windows support has been the long, slow queued builds. The reason for this is\nthat we were unable to install the Windows toolchains on Windows Server setups due to reliance on the virtualization\ninstruction set.\nThis put us into a problematic situation of hosting the Windows servers in our offices which is far from ideal.\nThe newer version of visual studio and the better build process might allow us to run on cloud hardware and\nget rid of our existing servers. Hosted solutions are, cheaper, faster and more reliable so this is something we’d\nlove to do as soon as possible!\nUnfortunately it means we would need to remove the original servers as they might grab builds intended for the new\nservers.\nFinal Word We’ll make the transition as gently as possible by providing a way for those of you who rely on Windows builds\nto try the new servers thru a build.xml edit. Once we confirm this approach we will flip the switch for everyone.\nKeep an eye on this blog and once we have the process in place be sure to try it right away to provide feedback.\nWe will provide a way to build on our old windows servers for a while to soften the migration but eventually\nwe’ll send them out to pasture. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFabrício Cabeça — April 4, 2016 at 6:40 pm (permalink) Fabrício Cabeça says:\nThis is great news indeed ! About supporting Windows 8.1 onwards we already accomplished this in our port, I will try to provide this support in your port. Many devices are still 8.1 and there are devices that are not going to receive the Windows 10 update.\nChidiebere Okwudire — April 5, 2016 at 7:33 am (permalink) Chidiebere Okwudire says:\nThis sounds promising. I hope there’ll be a way to stil support Windows 8.x devices in the long run but we’ll see.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-windows-port/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-windows-port/universal-windows-apps_thumb.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOur existing Windows Phone port has already gone thru 3 rewrites and a community rewrite and we are hard\u003cbr\u003e\nat work on the 4th rewrite (or 5th counting the community port). However, we decided to take a radically different\u003cbr\u003e\ndirection with the new port and with backwards compatibility to allow better scale.\u003c/p\u003e\n\u003cp\u003eSo lets start with the \u0026ldquo;bad news\u0026rdquo; and follow by an explanation of why and how we plan to do that.\u003c/p\u003e","title":"New Windows Port"},{"content":"\nChen just released a new cn1lib for circular progress indicators\nof various types. This is an often requested feature and there were many ways to implement this in the past\nbut it is now far easier to do this with shape clipping.\nYou can use the circular progress API using code such as:\nForm hi = new Form(\u0026quot;Circle Progress\u0026quot;); hi.setLayout(new BoxLayout(BoxLayout.Y_AXIS)); final CircleProgress p = new CircleProgress(); p.setProgress(100); p.setClockwise(true); p.setStartAngle(CircleProgress.START_9_OCLOCK); hi.add(p); final ArcProgress p2 = new ArcProgress(); p2.setProgress(70); hi.add(p2); final CircleFilledProgress p3 = new CircleFilledProgress(); p3.setProgress(70); hi.add(p3); Slider slider = new Slider(); slider.setEditable(true); slider.addDataChangedListener(new DataChangedListener() { @Override public void dataChanged(int type, int index) { p.setProgress(index); p2.setProgress(index); p3.setProgress(index); } }); hi.add(slider); hi.show(); Which results in this:\nFigure 1. Circle progress indicators in action\nIntelliJ/IDEA Rewrite This has been a very slow news week due to many reasons but a big chunk of that is our focus on some big\ntasks.\nI’m working on a complete rewrite of the IntelliJ/IDEA plugin, I hope to have it out next week. This\nshould bring IntelliJ/IDEA into par with the rest of the IDE’s and in my humble opinion it might leapfrog other IDE\nplugins. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMsizi — March 31, 2016 at 5:06 pm (permalink) Great work!!!! just a question, how to change the color of the circle. instead of blue maybe use red or any different color\nChen Fishbein — April 1, 2016 at 6:38 am (permalink) Chen Fishbein says:\nThanks, the colors are coming from the \u0026ldquo;Slider\u0026rdquo; theme entry, just modify the Slider colors on the theme to change the colors\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/around/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/around/circle-progress-blog-post.png\"\u003e\u003c/p\u003e\n\u003cp\u003eChen just released a \u003ca href=\"https://github.com/chen-fishbein/CN1CircleProgress\" target=\"_blank\" rel=\"noopener noreferrer\"\u003enew cn1lib\u003c/a\u003e for circular progress indicators\u003cbr\u003e\nof various types. This is an often requested feature and there were many ways to implement this in the past\u003cbr\u003e\nbut it is now far easier to do this with shape clipping.\u003c/p\u003e\n\u003cp\u003eYou can use the circular progress API using code such as:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eForm hi = new Form(\u0026quot;Circle Progress\u0026quot;);\nhi.setLayout(new BoxLayout(BoxLayout.Y_AXIS));\nfinal CircleProgress p = new CircleProgress();\np.setProgress(100);\np.setClockwise(true);\np.setStartAngle(CircleProgress.START_9_OCLOCK);\nhi.add(p);\n\nfinal ArcProgress p2 = new ArcProgress();\np2.setProgress(70);\nhi.add(p2);\n\nfinal CircleFilledProgress p3 = new CircleFilledProgress();\np3.setProgress(70);\nhi.add(p3);\n\nSlider slider = new Slider();\nslider.setEditable(true);\nslider.addDataChangedListener(new DataChangedListener() {\n\n    @Override\n    public void dataChanged(int type, int index) {\n        p.setProgress(index);\n        p2.setProgress(index);\n        p3.setProgress(index);\n    }\n});\nhi.add(slider);\n\nhi.show();\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWhich results in this:\u003c/p\u003e","title":"Around"},{"content":"\nClipping is one of the core tenants of graphics programming, you define the boundaries for drawing and when\nyou exceed said boundaries things aren’t drawn. Shape clipping allows us to clip based on any arbitrary Shape\nand not just a rectangle, this allows some unique effects generated in runtime.\nE.g. this code allows us to draw the image on the top of this post:\nImage duke = null; try { // duke.png is just the default Codename One icon copied into place duke = Image.createImage(\u0026quot;/duke.png\u0026quot;); } catch(IOException err) { Log.e(err); } final Image finalDuke = duke; Form hi = new Form(\u0026quot;Shape Clip\u0026quot;); // We create a 50 x 100 shape, this is arbitrary since we can scale it easily GeneralPath path = new GeneralPath(); path.moveTo(20,0); path.lineTo(30, 0); path.lineTo(30, 100); path.lineTo(20, 100); path.lineTo(20, 15); path.lineTo(5, 40); path.lineTo(5, 25); path.lineTo(20,0); Stroke stroke = new Stroke(0.5f, Stroke.CAP_ROUND, Stroke.JOIN_ROUND, 4); hi.getContentPane().getUnselectedStyle().setBgPainter((Graphics g, Rectangle rect) -\u0026gt; { g.setColor(0xff); float widthRatio = ((float)rect.getWidth()) / 50f; float heightRatio = ((float)rect.getHeight()) / 100f; g.scale(widthRatio, heightRatio); g.translate((int)(((float)rect.getX()) / widthRatio), (int)(((float)rect.getY()) / heightRatio)); g.setClip(path); g.setAntiAliased(true); g.drawImage(finalDuke, 0, 0, 50, 100); g.setClip(path.getBounds()); g.drawShape(path, stroke); g.translate(-(int)(((float)rect.getX()) / widthRatio), -(int)(((float)rect.getY()) / heightRatio)); g.resetAffine(); }); hi.show(); __ The original publication of this code was missing the second translate call which might have some on-device issues __ | Notice that this functionality isn’t available on all platforms so you normally need to test if shaped clipping is\nsupported using isShapeClipSupported(). Bubble Transition One of the reasons for adding shaped clipping is the new\nBubbleTransiton class.\nIt’s a transition that morphs a component into another component using a circular growth motion.\nThe BubbleTransition accepts the component that will grow into the bubble effect as one of its arguments. It’s generally\ndesigned for Dialog transitions although it could work for more creative use cases:\n__ The code below manipulates styles and look. This is done to make the code more \u0026ldquo;self contained\u0026rdquo;. Real world code should probably use the theme Form hi = new Form(\u0026quot;Bubble\u0026quot;); Button showBubble = new Button(\u0026quot;+\u0026quot;); showBubble.setName(\u0026quot;BubbleButton\u0026quot;); Style buttonStyle = showBubble.getAllStyles(); buttonStyle.setBorder(Border.createEmpty()); buttonStyle.setFgColor(0xffffff); buttonStyle.setBgPainter((g, rect) -\u0026gt; { g.setColor(0xff); int actualWidth = rect.getWidth(); int actualHeight = rect.getHeight(); int xPos, yPos; int size; if(actualWidth \u0026gt; actualHeight) { yPos = rect.getY(); xPos = rect.getX() + (actualWidth - actualHeight) / 2; size = actualHeight; } else { yPos = rect.getY() + (actualHeight - actualWidth) / 2; xPos = rect.getX(); size = actualWidth; } g.setAntiAliased(true); g.fillArc(xPos, yPos, size, size, 0, 360); }); hi.add(showBubble); hi.setTintColor(0); showBubble.addActionListener((e) -\u0026gt; { Dialog dlg = new Dialog(\u0026quot;Bubbled\u0026quot;); dlg.setLayout(new BorderLayout()); SpanLabel sl = new SpanLabel(\u0026quot;This dialog should appear with a bubble transition from the button\u0026quot;, \u0026quot;DialogBody\u0026quot;); sl.getTextUnselectedStyle().setFgColor(0xffffff); dlg.add(BorderLayout.CENTER, sl); dlg.setTransitionInAnimator(new BubbleTransition(500, \u0026quot;BubbleButton\u0026quot;)); dlg.setTransitionOutAnimator(new BubbleTransition(500, \u0026quot;BubbleButton\u0026quot;)); dlg.setDisposeWhenPointerOutOfBounds(true); dlg.getTitleStyle().setFgColor(0xffffff); Style dlgStyle = dlg.getDialogStyle(); dlgStyle.setBorder(Border.createEmpty()); dlgStyle.setBgColor(0xff); dlgStyle.setBgTransparency(0xff); dlg.showPacked(BorderLayout.NORTH, true); }); hi.show(); Figure 1. Bubble transition converting a circular button to a Dialog Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\njava_dev — March 23, 2016 at 9:53 am (permalink) Is this feature released in eclipse plugin?\nShai Almog — March 24, 2016 at 3:29 am (permalink) Shai Almog says:\nThis is part of the library not the plugin core. Libraries get updated every Friday since last Friday.\nSo it’s already in although we made some improvements to the implementation which will go in this Friday. To get this just use \u0026ldquo;Update Client Libs\u0026rdquo; in the Codename One section in the preferences.\nJavier Anton — May 21, 2020 at 10:15 am (permalink) Javier Anton says:\nA brief flicker around the dialog’s content is shown when the dialog background is set to transparent.\nEdit: solved by extending BubbleTransition and setting the transparency within\nShai Almog — May 22, 2020 at 4:08 am (permalink) Shai Almog says:\nIf you can see a bug in the code feel free to submit a pull request.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/shape-clipping-bubble-transition/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/shape-clipping-bubble-transition/shaped-clipping.png\"\u003e\u003c/p\u003e\n\u003cp\u003eClipping is one of the core tenants of graphics programming, you define the boundaries for drawing and when\u003cbr\u003e\nyou exceed said boundaries things aren’t drawn. Shape clipping allows us to clip based on any arbitrary \u003ccode\u003eShape\u003c/code\u003e\u003cbr\u003e\nand not just a rectangle, this allows some unique effects generated in runtime.\u003c/p\u003e\n\u003cp\u003eE.g. this code allows us to draw the image on the top of this post:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eImage duke = null;\ntry {\n    // duke.png is just the default Codename One icon copied into place\n    duke = Image.createImage(\u0026quot;/duke.png\u0026quot;);\n} catch(IOException err) {\n    Log.e(err);\n}\nfinal Image finalDuke = duke;\n\nForm hi = new Form(\u0026quot;Shape Clip\u0026quot;);\n\n// We create a 50 x 100 shape, this is arbitrary since we can scale it easily\nGeneralPath path = new GeneralPath();\npath.moveTo(20,0);\npath.lineTo(30, 0);\npath.lineTo(30, 100);\npath.lineTo(20, 100);\npath.lineTo(20, 15);\npath.lineTo(5, 40);\npath.lineTo(5, 25);\npath.lineTo(20,0);\n\nStroke stroke = new Stroke(0.5f, Stroke.CAP_ROUND, Stroke.JOIN_ROUND, 4);\nhi.getContentPane().getUnselectedStyle().setBgPainter((Graphics g, Rectangle rect) -\u0026gt; {\n    g.setColor(0xff);\n    float widthRatio = ((float)rect.getWidth()) / 50f;\n    float heightRatio = ((float)rect.getHeight()) / 100f;\n    g.scale(widthRatio, heightRatio);\n    g.translate((int)(((float)rect.getX()) / widthRatio), (int)(((float)rect.getY()) / heightRatio));\n    g.setClip(path);\n    g.setAntiAliased(true);\n    g.drawImage(finalDuke, 0, 0, 50, 100);\n    g.setClip(path.getBounds());\n    g.drawShape(path, stroke);\n    g.translate(-(int)(((float)rect.getX()) / widthRatio), -(int)(((float)rect.getY()) / heightRatio));\n    g.resetAffine();\n});\n\nhi.show();\n\u003c/code\u003e\u003c/pre\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e__\u003c/th\u003e\n          \u003cth\u003eThe original publication of this code was missing the second translate call which might have some on-device issues\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e__ |  Notice that this functionality isn’t available on all platforms so you normally need to test if shaped clipping is\u003c/p\u003e","title":"Shape Clipping \u0026 Bubble Transition"},{"content":"\nWe just made our first weekly release today, in the coming weeks when you send a build or update the client\nlibraries you should get a new version every Friday. We hope this will help us provide better consistency between\nthe docs/device builds and the simulator.\nWe finally completed the overhaul of the developer guide which now clocks at 732 pages. This doesn’t mean the\nguide is perfect or covers everything there is but rather that we covered the bigger pieces and reviewed the whole\ndocument for accuracy and relevance. There are still big pieces we’d like to add e.g. a section about the common\ncn1libs is something that I would personally like to see.\n__ | If there is something you feel isn’t covered properly in the docs let us know in the comments below\nor just edit the wiki directly! Now that the guide is complete and the JavaDocs are far improved we are targeting better videos for the website and\nIntelliJ support. We are still overworked with the new Windows port so that is slowing our general progress on\neverything else.\nJavaScript Promotion Ended We ended the JavaScript build promotion\nwe started last month. If you were a pro user and remain a pro user\nyou should have that ability into 2017. Everyone else now needs an enterprise license to enjoy that feature.\nNotice that if you let your subscription lapse you might lose this ability since we won’t have a way to distinguish your builds\nfrom everyone else. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — March 18, 2016 at 7:15 am (permalink) Chidiebere Okwudire says:\nGood to hear there’s progress on the WP port. Is it already possible to predict when we can expect the first release? 🙂\nShai Almog — March 18, 2016 at 7:30 am (permalink) Shai Almog says:\nOne of the reasons we didn’t want to go into this whole mess is the level of complexity. We put in a tremendous amount of work and are still at a stage where we might need to throw everything away and start from scratch!\nWe are trying to take a shortcut that would save us the need to port ParparVM to Windows, if we need to go thru that route it could take quite a while.\nAdAlbert — April 3, 2016 at 7:29 am (permalink) AdAlbert says:\nI think you don’t need ParparVM for Windows port because gc is implemented internally in C# and this is main advantage od ParparVM for iOS.\nShai Almog — April 4, 2016 at 2:26 am (permalink) Shai Almog says:\nIf we would go with ParparVM (which we probably won’t as we made good progress with iKVM) we would use C and not C#. We had a horrible experience when translating Java bytecode to C#. They differ at just the right amount to make translation darn near impossible.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/weekly-release-developer-guide-javascript-promotion-end/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/weekly-release-developer-guide-javascript-promotion-end/documention.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe just made our first weekly release today, in the coming weeks when you send a build or update the client\u003cbr\u003e\nlibraries you should get a new version every Friday. We hope this will help us provide better consistency between\u003cbr\u003e\nthe docs/device builds and the simulator.\u003c/p\u003e\n\u003cp\u003eWe finally completed the overhaul of the developer guide which now clocks at 732 pages. This doesn’t mean the\u003cbr\u003e\nguide is perfect or covers everything there is but rather that we covered the bigger pieces and reviewed the whole\u003cbr\u003e\ndocument for accuracy and relevance. There are still big pieces we’d like to add e.g. a section about the common\u003cbr\u003e\ncn1libs is something that I would personally like to see.\u003c/p\u003e","title":"Weekly Release, Developer Guide \u0026 JavaScript Promotion End"},{"content":"\nOne of our most important posts from 2015 was\nSteves PSD to App: Converting a Beautiful Design into a Native Mobile App.\nThis post included a very thorough step by step video guide walking thru the creation of a non-trivial UI design\nand ended with the introduction of Steve’s CSS plugin for Codename One.\nAs we are close to wrapping up the developer guide update it occurred to us that this remarkably important tutorial\nisn’t within the developer guide!\nSo we re-did the tutorial as a document and while we were doing that we also updated the code a bit to use\nthe new native fonts (instead of the actual fonts from the PSD). We also updated it to use the new material design\nicons which are really appropriate for this design.\nThis guide is really useful for all developers who deal with UI’s and PSD’s regardless of whether you are a\nCodename One developer.\nYou can check out the full project we discuss below on github here\nConverting a PSD To A Theme Codename One provides extensive support for designing beautiful user interfaces, but it isn’t necessarily obvious to new developers how to achieve their desired results. A common workflow for app design includes a PSD file with mock-ups of the UI, created by a professional designer.\n__ PSD is the Adobe Photoshop file format, it’s the most common format for UI designs in the industry For this tutorial we adapt a very slick looking sign-up form found online and convert it to a Codename One component that can be used inside an application.\nThe process we followed was:\nFind the PSD design we want to use:\nthis PSD file created by Adrian Chiran (we mirrored it here in case it goes offline): Figure 1. Sign Up form Design\nRe-create the general structure and layout of the design in a Codename One Form using nested components and layout managers. Here is a break-down of how we structured the component hierarchy in the Form: Figure 2. Component hierarchy and layouts\nExtract the images we needed using Photoshop – this process is often referred to as \u0026ldquo;cutting\u0026rdquo;\nExtract the fonts, colors, and styles we needed to reproduce the design in Codename One\nImport images into the Codename one project, and define theme styles so that our components match the look of the original design\nHere is a screenshot of the resulting component running inside the Codename One simulator:\nFigure 3. Resulting app in the Codename One simulator\nBreaking Down the PSD Open the PSD you are interested in using Photoshop.\n__ You might be missing fonts in your system so you can either install them or ignore that. Keep in mind that some fonts might not be redistributable with your application In this PSD we want only one of the screen designs so initially we want to remove everything that isn’t related so we can get our bearings more effectively:\nSelect the drag tool (the top left tool)\nIn the toolbar for the tool (top bar area) check the Auto Select mode\nSelect the Layer Mode for auto selection (in some cases group would actually be better so feel free to experiment)\nClick on the portion in the PSD that you are interested in\nYou should end up with something like this where a layer is selected in the layers window:\nFigure 4. Selecting a layer from the region you are interested in\nScroll up the hierarchy a bit and uncheck/recheck the eye icon on the left until you locate the right element layer.\nFigure 5. Selecting a layer from the region you are interested in\nRight click the layer and select Convert To Smart Object.\n__ The right click menu will present different options when you click different areas of the layer, clicking on the left area of the layer works Figure 6. In the right click menu option select \u0026ldquo;Convert To Smart Object\u0026rdquo;\nOnce the layer hierarchy is a smart object you can just double click it which will open the sub hierarchy in a new tab and you now only have the pieces of the image you care about.\nFigure 7. Double clicking the smart object allows us to edit only the form we need\nRemoving the Noise The first thing we need to do is remove from the image all of the things that we don’t really need. The status bar area on the top is redundant as if is a part of the phones UI. We can select it using the select tool and click the eye icon next to the layer to hide it.\nNormally we’d want to have the back arrow but thanks to the material design icons that are a part of Codename One we don’t need that icon so we can hide that too.\nWe don’t need the \u0026ldquo;Sign Up\u0026rdquo; or \u0026ldquo;Done\u0026rdquo; strings in the title either but before removing them we’d like to know the font that is used.\nTo discover that I can click them to select the layer then switch to the text tool:\nFigure 8. The text tool allows us to inspect the font used\nThen I can double click the text area layer to find out the font in the top of the UI like this:\nFigure 9. The Done toolbar entry uses SourceSansPro Regular\n__ Notice that I don’t actually need to have the font installed in this case I don’t (hence the square brackets) Also notice that the color of the font is accessible in that toolbar, by clicking the color element we get this dialog which shows the color value to be f73267, this is something we will use later\nFigure 10. The color dialog lists the hex color at the bottom, we can paste that directly to the designer tool\nWe can now hide both text layers so they won’t pose a problem later.\nThe Camera Button The camera button includes an icon and the button background itself. You can just use that as a single image and be done with it, but for the purpose of this tutorial I will take the harder route of separating this into a button background and a foreground image.\nWhen you click on the camera icon you will notice that the camera icon is comprised of two separate layers: the camera and the \u0026ldquo;x\u0026rdquo; symbol above it. We can select both layers using ctrl-click (command click on the Mac) and convert both to a smart object together using the same method as before:\nFigure 11. The camera smart object\nSince the image is used as an icon we want it to be completely square which isn’t the situation here!\nThis is important as a non-square image can trigger misalignment when dealing with icons and the background. So we need to use the Image → Canvas Size menu and set the values to be the same (the higher value of the two).\nFigure 12. The canvas size dialog for the camera.png file\nWe can now use File → Save As and save the first image resource we will need into a temporary directory. Make sure to save a PNG file to preserve quality and transparency!\nFor convenience we’ll refer to the file as camera.png when we need it later.\nFigure 13. The camera icon image\nWe can follow the exact same procedure with the parent button layer (the white portion) which we can convert to a smart object and save as camera-button.png.\nFigure 14. The camera button image set to a gray background so it will be visible\nNow we can hide both of these elements and proceed to get the background image for the title.\nHere the \u0026ldquo;smart object trick\u0026rdquo; won’t work…​ There is an effects layer in place and the smart object will provide us with the real underlying image instead of the look we actually want. However, solving this is trivial now that we hid all of the elements on top of the image!\nWe need to switch to the rectangular select tool:\nFigure 15. The select tool and the clean image we want to select\nNow drag the select tool to select the image don’t cross into the white pixels below the image. You can use the zoom value and set it to a very high value to get the selection right.\nWhen the selection is right click Edit → Copy Merged. Normally Copy would only copy a specific layer but in this case we want to copy what we see on the screen!\nNow click File → New it should have the Presets set to Clipboard which means the newly created image is based on what we just copied (that is seriously great UX). Just accept that dialog and paste (Ctrl-V or Command-V).\nYou can now save the image, since it’s just a background using JPEG is totally acceptable in this case. We named it background.jpg.\nFigure 16. The background image\nThe last thing we need is the colors used in the UI. We can use the \u0026ldquo;eye drop\u0026rdquo; tool in a high zoom level to discover the colors of various elements e.g. the text color is 4d606f and the separator color is f5f5f5:\nFigure 17. The eye drop tool can be pointed at an area of the image to get the color in that region\nThe Code While that was verbose it was relatively simple. We’ll create a simple barebones manual application with the native theme.\n__ The reason for this is to avoid \u0026ldquo;noise\u0026rdquo;, if we use a more elaborate theme it would have some existing settings. This can make the tutorial harder to follow Figure 18. Simple bare bones app settings\nOnce the project is created double click the theme.res file and within the designer select Images → Quick Add Multi Images. Select the 3 images we created above: background.jpg, camera.png \u0026amp; camera-button.png. Leave the default setting on Very High and press OK.\nThen save the resource file so we can use these images from code.\nHere is the source code we used to work with the UI above there are comments within the code explaining some of the logic:\nprivate Label createSeparator() { Label sep = new Label(); sep.setUIID(\u0026quot;Separator\u0026quot;); // the separator line is implemented in the theme using padding and background color, by default labels // are hidden when they have no content, this method disables that behavior sep.setShowEvenIfBlank(true); return sep; } public void start() { if(current != null){ current.show(); return; } // The toolbar uses the layered mode so it resides on top of the background image, the theme makes // it transparent so we will see the image below it, we use border layout to place the background image on // top and the \u0026quot;Get started\u0026quot; button in the south Form psdTutorial = new Form(\u0026quot;Signup\u0026quot;, new BorderLayout()); Toolbar tb = new Toolbar(true); psdTutorial.setToolbar(tb); // we create 4mm material arrow images for the back button and the Get started button Style iconStyle = psdTutorial.getUIManager().getComponentStyle(\u0026quot;Title\u0026quot;); FontImage leftArrow = FontImage.createMaterial(FontImage.MATERIAL_ARROW_BACK, iconStyle, 4); FontImage rightArrow = FontImage.createMaterial(FontImage.MATERIAL_ARROW_FORWARD, iconStyle, 4); // we place the back and done commands in the toolbar, we need to change UIID of the \u0026quot;Done\u0026quot; command // so we can color it in Red tb.addCommandToLeftBar(\u0026quot;\u0026quot;, leftArrow, (e) -\u0026gt; Log.p(\u0026quot;Back pressed\u0026quot;)); Command doneCommand = tb.addCommandToRightBar(\u0026quot;Done\u0026quot;, null, (e) -\u0026gt; Log.p(\u0026quot;Done pressed\u0026quot;)); tb.findCommandComponent(doneCommand).setUIID(\u0026quot;RedCommand\u0026quot;); // The camera button is comprised of 3 pieces. A label containing the image and the transparent button // with the camera icon on top. This is all wrapped in the title container where the title background image // is placed using the theme. We chose to use a Label rather than a background using the cameraLayer so // the label will preserve the original size of the image without scaling it and take up the space it needs Button cameraButton = new Button(theme.getImage(\u0026quot;camera.png\u0026quot;)); Container cameraLayer = LayeredLayout.encloseIn( new Label(theme.getImage(\u0026quot;camera-button.png\u0026quot;)), cameraButton); cameraButton.setUIID(\u0026quot;CameraButton\u0026quot;); Container titleContainer = Container.encloseIn( new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER), cameraLayer, BorderLayout.CENTER); titleContainer.setUIID(\u0026quot;TitleContainer\u0026quot;); TextField firstName = new TextField(\u0026quot;\u0026quot;, \u0026quot;First Name\u0026quot;); TextField lastName = new TextField(\u0026quot;\u0026quot;, \u0026quot;Last Name\u0026quot;); TextField email = new TextField(\u0026quot;\u0026quot;, \u0026quot;Email Address\u0026quot;, 20, TextField.EMAILADDR); TextField password = new TextField(\u0026quot;\u0026quot;, \u0026quot;Choose a Password\u0026quot;, 20, TextField.PASSWORD); TextField phone = new TextField(\u0026quot;\u0026quot;, \u0026quot;Phone Number\u0026quot;, 20, TextField.PHONENUMBER); Label phonePrefix = new Label(\u0026quot;+1\u0026quot;); phonePrefix.setUIID(\u0026quot;TextField\u0026quot;); // The phone and full name have vertical separators, we use two table layouts to arrange them correctly // so the vertical separator will be in the right place TableLayout fullNameLayout = new TableLayout(1, 3); Container fullName = new Container(fullNameLayout); fullName.add(fullNameLayout.createConstraint().widthPercentage(49), firstName). add(fullNameLayout.createConstraint().widthPercentage(1), createSeparator()). add(fullNameLayout.createConstraint().widthPercentage(50), lastName); Container fullPhone = TableLayout.encloseIn(3, phonePrefix, createSeparator(), phone); // The button in the south portion needs the arrow icon to be on the right side so we place the text on the left Button southButton = new Button(\u0026quot;Get started\u0026quot;, rightArrow); southButton.setTextPosition(Component.LEFT); southButton.setUIID(\u0026quot;SouthButton\u0026quot;); // we add the components and the separators the center portion contains all of the elements in a box // Y container which we allow to scroll. BorderLayout Containers implicitly disable scrolling Container by = BoxLayout.encloseY( fullName, createSeparator(), email, createSeparator(), password, createSeparator(), fullPhone, createSeparator() ); by.setScrollableY(true); psdTutorial.add(BorderLayout.NORTH, titleContainer). add(BorderLayout.SOUTH, southButton). add(BorderLayout.CENTER, by); psdTutorial.show(); } Styling The UI So the code above is most of the work but we still need to put everything together using the theme. This is what we have so far:\nFigure 19. Before applying the changes to the theme this is what we have\nFigure 20. This is what we are aiming at with no additional code changes\nThis looks like a major set of changes but it requires exactly 10 UIID definitions to get to this look!\nOpen the designer and select the theme. Press the Add button and type in TitleContainer. Uncheck derive for the background and select IMAGE_SCALED_FILL for the Type and the background.jpg image.\nDefine the padding as:\nLeft – 3 millimeter\nRight – 3 millimeter\nTop – 8 millimeter\nBottom – 2 millimeter\nThis will allow enough space for the title. Define margin as 0 on all sides. Then press OK.\nAdd the \u0026ldquo;Title\u0026rdquo; UIID. In the Color tab define the foreground as ffffff define transparency as 0 (fully transparent so we will see the TitleContainer). Define padding as 1 millimeter on all sides and margin as 0 on all sides.\nIn the Border tab press the …​ button and select [Empty].\nIn the Font tab select the True Type as native:MainThin. Select the True Type Size as millimeters and set the value to 3.5.\nPress OK to save the changes.\nCopy the Title UIID and paste it, change the name to \u0026ldquo;TitleCommand\u0026rdquo; and press OK to save the changes.\nCopy the Title UIID again and paste it, change the name to \u0026ldquo;RedCommand\u0026rdquo;. In the Color tab set the foreground color to f73267. In the Font tab set the True Type to native:MainLight and set the size to 3. Press OK to save the changes.\nAdd the \u0026ldquo;TitleArea\u0026rdquo; UIID. In the Color tab define transparency as 0 (fully transparent so we will see the TitleContainer). Define padding and margin as 0 on all sides.\nIn the Border tab press the …​ button and select [Empty].\nPress OK to save the changes.\nAdd the \u0026ldquo;TextField\u0026rdquo; UIID. In the Color tab define transparency as 255 (fully opaque) and the background as ffffff (white). Define padding as 2 millimeter on all sides and margin as 0 on all sides.\nIn the Border tab press the …​ button and select [Empty].\nIn the Font tab set the True Type to native:MainLight and set the size to 2. Press OK to save the changes.\nCopy the TextField UIID again and paste it, change the name to \u0026ldquo;TextHint\u0026rdquo;. In the Color tab set the foreground color to 4d606f. Press OK to save the changes.\nAdd the \u0026ldquo;SouthButton\u0026rdquo; UIID. In the Color tab define transparency as 255 (fully opaque) and the background as f73267 (red) and the foreground as ffffff (white). Define Alignment as Center.\nDefine padding as:\nLeft – 1 millimeter\nright – 1 millimeter\ntop – 2 millimeters\nbottom – 2 millimeters\nDefine margin as 0 on all sides.\nIn the Font tab set the True Type to native:MainThin and set the size to 3. Press OK to save the changes.\nAdd the \u0026ldquo;CameraButton\u0026rdquo; UIID. In the Color tab define transparency as 0 (fully transparent). Define Alignment as Center.\nDefine padding as:\nLeft – 1 millimeter\nright – 1 millimeter\ntop – 3 millimeters\nbottom – 1 millimeter\n__ This helps spacing away from the title Define margin as 1 millimeter on all sides.\nPress OK to save the changes.\nYou can now save the theme and the app should look like the final result!\nNot Quite There Yet There is one last piece that you would notice if you actually try to run this code. When pressing the buttons/text fields you would see their look change completely due to the different styles for focus/press behavior.\nYou can derive the regular styles from the selected/pressed styles but one of the simplest ways is to just copy \u0026amp; paste the styles to the pressed/selected tabs. We can copy CameraButton, RedCommand, SouthButton \u0026amp; TextField to the selected state. Then copy CameraButton, RedCommand \u0026amp; SouthButton to the pressed state to get the complete app running! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nsalah Alhaddabi — November 14, 2016 at 8:12 pm (permalink) Dear Shai, Separator UIID is missing. Will you please provide it as I am having a gap between the text fields and the gray line is not appearing.\nShai Almog — November 15, 2016 at 5:26 am (permalink) Se is defined like this with 1 pixel padding on all sides and 0 margin\nhttps://uploads.disquscdn.c…\nsalah Alhaddabi — November 15, 2016 at 2:28 pm (permalink) Thank you soooo much dear really appreciate your help a lot!!!\nsalah Alhaddabi — November 19, 2016 at 2:14 pm (permalink) Dear Shai, I am so surprised to see that the toolbar on android has still white background while it works fine on ios. Also when I change the device on the simulator from ios 6 plus or android Samsung S7 to other samller devices the screens look ugly and the toolbar becomes white the the title area appears even though I have hidden it. Please help!!\nShai Almog — November 20, 2016 at 6:13 am (permalink) Override the border of title area UIID as empty.\nsalah Alhaddabi — November 20, 2016 at 4:37 pm (permalink) very nice very nice thanks a million!!\nzainab — March 22, 2017 at 10:02 pm (permalink) can any one give me the java code for the first basic form. the one without styling. please. thank you so much in advanced\nzainab — March 22, 2017 at 10:05 pm (permalink) I am having difficulties with netbeans running the simple signup form. can anyone help with the code and all plugins please.\nShai Almog — March 23, 2017 at 5:57 am (permalink) There is one plugin and that is the Codename One plugin which you can install via the download section of this website. It also includes the code for this demo if you go to File -\u0026gt; New Project -\u0026gt; Codename One -\u0026gt; Demos you would see the PSD demo code\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/psd-to-app-revisited/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/psd-to-app-revisited/psd_to_app_title_image.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of our most important posts from 2015 was\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/blog/psd-to-app-converting-a-beautiful-design-into-a-native-mobile-app.html#comment-2566720750\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eSteves PSD to App: Converting a Beautiful Design into a Native Mobile App\u003c/a\u003e.\u003cbr\u003e\nThis post included a very thorough step by step video guide walking thru the creation of a non-trivial UI design\u003cbr\u003e\nand ended with the introduction of Steve’s CSS plugin for Codename One.\u003c/p\u003e\n\u003cp\u003eAs we are close to wrapping up the developer guide update it occurred to us that this remarkably important tutorial\u003cbr\u003e\nisn’t within the developer guide!\u003c/p\u003e","title":"PSD to App Revisited"},{"content":"\nWe just updated the library with our last ad hoc release, starting next week we will release libraries every Friday\nand occasionally also a plugin update within that same proximity. We made some refinements to some\nAndroid theme elements and one of those refinements is a new TitleArea drop shadow.\nThis effectively creates a situation where we can’t reasonably detect an empty title and so if you want the title\nto truly disappear you can either:\nSet the TitleArea border attribute to empty\nDo something like form.getToolbar().setUIID(\u0026quot;Container\u0026quot;)\nWe released an update for the Eclipse plugin but are experiencing some issues with the NetBeans update\ncenter which we will hopefully resolve before the weekend.\nAs a side note we are working hard to re-imagining the IntelliJ/IDEA plugin, but our current approach will\nprobably still rely on Ant instead of a move to gradle or maven. Both of these seem like really good ideas\non paper but at the moment they might not be as convenient. I’ll try to write a bit on the process as we\nmove forward and have a clearer picture on this.\nNativeInterface Generics The NativeInterface API’s haven’t changed much since their inception but we just committed a small\nnice to have feature.\nUp until now if you wanted to get a reference to your native interface you would have to do this:\nMyNativeInterface m = (MyNativeInterface)NativeLookup.create(MyNativeInterface.class); With the new version you can now do this:\nMyNativeInterface m = NativeLookup.create(MyNativeInterface.class); That’s a nice trick generics can pull off by setting the method signature to:\npublic static \u0026lt;T extends NativeInterface\u0026gt; T create(Class\u0026lt;T\u0026gt; c); I wasn’t a big fan of generics when they came out and I still don’t like the declaration of the method but the end\nresult is really nice.\nDocumentation Update We are on the brink of 700 pages for the developer guide and I think we’ll finish just shy of 1000 for this iteration.\nThis work is taking some time but it’s totally worth the effort as the level of the documentation is at a league\nof its own. E.g. check out the IO section in the guide here.\nThe original was remarkably bare and didn’t cover so many basic things that should be covered e.g.\nthe webservice wizard, SliderBridge\netc…​ Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — March 10, 2016 at 8:27 am (permalink) Chidiebere Okwudire says:\nI’m really excited about the updates to the Android toolbar and will try it out as soon as the netbeans plugin is updated. Well done!\nznprojects — March 10, 2016 at 11:33 am (permalink) znprojects says:\nThe documentation looks fantastic. I remember this being one of the things that always made me hesitant to recommend CN1 to others in the past. Seeing what’s there now, that hesitation is gone.\nNigel Chomba — March 15, 2016 at 5:50 pm (permalink) Nigel Chomba says:\nNetbeans plug in is taking too long, cant the plugin be hosted on your site as well since you updated us netbeans has issues for now.\nShai Almog — March 16, 2016 at 4:07 am (permalink) Shai Almog says:\nWe are communicating with them: http://forums.netbeans.org/…\nWe used to have our own host but maintaining both was a pain and bred confusion for developers.\nThis isn’t a big deal since the libraries/simulator etc. are all updated instantly as we release them.\nNigel Chomba — March 16, 2016 at 12:05 pm (permalink) Nigel Chomba says:\nOkay thanks for the clarity.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/library-update-nativeinterface-generics/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/library-update-nativeinterface-generics/phone-gallery.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe just updated the library with our last ad hoc release, starting next week we will release libraries every Friday\u003cbr\u003e\nand occasionally also a plugin update within that same proximity. We made some refinements to some\u003cbr\u003e\nAndroid theme elements and one of those refinements is a new \u003ccode\u003eTitleArea\u003c/code\u003e drop shadow.\u003c/p\u003e\n\u003cp\u003eThis effectively creates a situation where we can’t reasonably detect an empty title and so if you want the title\u003cbr\u003e\nto truly disappear you can either:\u003c/p\u003e","title":"Library Update \u0026 NativeInterface Generics"},{"content":"\nStarting with the next update of Codename One (later this week) we will switch Toolbar on as the default for\nall newly created projects. This doesn’t mean much for most of us as existing projects won’t be affected, however\nif you are creating a new project this means you won’t need to create a Toolbar for every Form and that we\nwon’t have to deal with as many issues related to the native Android title.\nThis is clearly the way to go, as we look at modern mobile apps even from Google itself. They use the side menu\nfor almost all apps and eschew the overflow for most usages (e.g. gmail). By focusing on the Toolbar we\ncan further refine it and add better support for its appearance within the templates.\nAs part of that we already refined the overflow button a bit and the default padding for the TitleArea etc. We will\nprobably add additional refinements e.g. the drop shadow for the Android theme.\nMillimeter Sizes We added a new API to handle millimeters to pixel conversion: Display.convertToPixels(float). This API accepts\na floating point value which is more convenient than the existing integer based API. Ideally we’d want this to\npropagate as an option into the designer tool but that is not trivial as it requires a change in the resource file\nformat. It’s something we plan to do as we move forward though.\nWe also added the ability to create a material icon with an explicit millimeter size:\nFontImage.createMaterial(char icon, Style s, float size)\nThis is useful as the current approach of picking the size of the style font doesn’t always work as we’d want especially\nin cases where we want the icon to be larger than the text.\nDocs Update \u0026amp; Weekly Releases While we made a lot of progress with the docs I’ve slowed down the server updates for them. The main issue is that\nwe are moving too quickly with the docs and don’t have time to release minor changes that we make to the API’s.\nE.g. newer samples in the docs already use the API’s mentioned above as well as some other newer API’s. This\ncauses a situation where developers can’t compile our samples when working against the latest version. One\nsolution for this is to make a weekly release schedule instead of our current \u0026ldquo;ad hoc\u0026rdquo; updates which are problematic.\nThis way we can both update the docs and the binary in the same time and also have a clearer schedule of\nlibrary updates (notice that library updates don’t necessarily include a plugin update).\nSo right now the tentative plan is to have a weekly release every Friday to include all the stuff we worked on\nover the week. This week we’ll probably release a bit earlier due to the plugin update but this should start next\nweek. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nLukman Javalove Idealist Jaji — March 8, 2016 at 4:59 am (permalink) Lukman Javalove Idealist Jaji says:\nGreat…I’ve been trying to use StatusBar ToastMessages and the signature component but all to no avail….Even when I updated my plugin…This is a better approach…and also when you anounce feature and even show a demo of it, let the releae time of the feature into the core API not be too long from the time of incorporation into the API as with the StatusBar and others…\nbryan — March 9, 2016 at 7:26 am (permalink) bryan says:\nIs there any chance you can create a new demo app which shows most of these new features. All the existing demos are semi-obsolete, and whilst the docs provide example snippets, it’s not always obvious how to put everything together.\nShai Almog — March 10, 2016 at 3:48 am (permalink) Shai Almog says:\nThis was updated yesterday so all these API’s should be there now.\nI agree. We are trying to be more organized all across the board and having a proper release schedule is part of that organized mentality.\nShai Almog — March 10, 2016 at 3:51 am (permalink) Shai Almog says:\nRefreshing the demos is high on our priority and will probably happen in tandem with new video tutorials/courses.\nWe need to update all demos to Java 8 as most of them are currently out of date. Since the docs are now mostly targeted at Java 8 we need to do the same there.\nWe also need new demos that are more refined, the kitchen sink is REALLY old by now and we need a new version of that. We consider all of that work as \u0026ldquo;documentation\u0026rdquo; which is currently one of our top 4 priorities.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/toolbar-default-millimeter-sizes-weekly-releases/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/toolbar-default-millimeter-sizes-weekly-releases/generic-java-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eStarting with the next update of Codename One (later this week) we will switch \u003ccode\u003eToolbar\u003c/code\u003e on as the default for\u003cbr\u003e\nall newly created projects. This doesn’t mean much for most of us as existing projects won’t be affected, however\u003cbr\u003e\nif you are creating a new project this means you won’t need to create a \u003ccode\u003eToolbar\u003c/code\u003e for every \u003ccode\u003eForm\u003c/code\u003e and that we\u003cbr\u003e\nwon’t have to deal with as many issues related to the native Android title.\u003c/p\u003e","title":"Toolbar Default, Millimeter Sizes \u0026 Weekly Releases"},{"content":"\nI was working on documenting the SQLite support in Codename One, you can see some of that work both in the\ndb package and in the\ndeveloper guide. As a demo for\nSQL I decided to just create a tool that allows you to type arbitrary SQL to execute it on the device and see\nthe results in a Table…​\nBeside being a cool example this can be a hugely powerful debugging tool to one of the more painful API’s to\ndebug on the device. You can integrate this as a hidden feature into your application and use it to debug odd \u0026ldquo;on device\u0026rdquo;\nissues by querying the DB!\nToolbars All Around The Toolbar API is the way forward\nbut up until now we didn’t include the option to set the Toolbar globally so for every Form you had to do the:\nToolbar tb = new Toolbar(); form.setToolbar(tb); You can now set the Toolbar to be on by default on all forms so form.getToolbar() will return a valid Toolbar\nthat you can use right away. There are two ways to enable it, in code using:\nToolbar.setGlobalToolbar(true); Or using the theme constant:\nglobalToobarBool=true Debugging Location Calls Piotr contributed another pull request\nthat refines the behavior of the simulator when working with the location API. This highlights a relatively\naccessible path to code contribution thru the Java SE code which should be easier.\nCheck out my post on contributing code to the Codename One project\nhere\nDocumentation Progress Our manual is over 650 pages. We just finished a rewrite of the IO section which is HUGE!\nSimilarly to the galleries we made for components and layouts we created sections for the\ndatabase,\nXPath processing/parsing language \u0026amp;\ngeneral IO (storage, filesystem, parsing, networking etc.).\nCheck out these sections and let us know what you think. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDalvik — March 4, 2016 at 1:21 pm (permalink) Dalvik says:\nCan we maybe add more functionality to the DB explorer tool?\nThis opens some potential to \u0026ldquo;on device analysis\u0026rdquo; style API’s. Any plans on that?\nShai Almog — March 5, 2016 at 4:14 am (permalink) Shai Almog says:\nI’d love that but I’m not sure when we’ll get around to do something like this.\nMr Emma — April 14, 2016 at 3:25 pm (permalink) Mr Emma says:\nFor some reason your locationmanager never works for me even tho i follow all possible instructions, it works perfectly on the emulator but moving to a real android device it never works\nShai Almog — April 15, 2016 at 3:01 am (permalink) Shai Almog says:\nI suggest trying it as we explained it.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/sql-explorer-global-toolbar-location-docs/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/sql-explorer-global-toolbar-location-docs/documention.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI was working on documenting the SQLite support in Codename One, you can see some of that work both in the\u003cbr\u003e\n\u003ca href=\"/javadoc/com/codename1/db/package-summary/\"\u003edb package\u003c/a\u003e and in the\u003cbr\u003e\n\u003ca href=\"/manual/files-storage-networking/\"\u003edeveloper guide\u003c/a\u003e. As a demo for\u003cbr\u003e\nSQL I decided to just create a tool that allows you to type arbitrary SQL to execute it on the device and see\u003cbr\u003e\nthe results in a \u003ccode\u003eTable\u003c/code\u003e…​\u003c/p\u003e\n\u003cp\u003eBeside being a cool example this can be a hugely powerful debugging tool to one of the more painful API’s to\u003cbr\u003e\ndebug on the device. You can integrate this as a hidden feature into your application and use it to debug odd \u0026ldquo;on device\u0026rdquo;\u003cbr\u003e\nissues by querying the DB!\u003c/p\u003e","title":"SQL Explorer, Global Toolbar, Location \u0026 Docs"},{"content":"\nWe’ve had a busy week working with several customers on various tasks/issues as well as the documentation\nwhich is practically unrecognizable by now (more than 600 pages by now). As a result a lot of small fixes and\nenhancements were made to the code as well as one new niche component.\nConnectionRequest.downloadImageToStorage We have multiple ways to download an image and our general favorite is the URLImage.\nHowever, the URLImage assumes\nthat you know the size of the image in advance or that you are willing to resize it. In that regard it works great for\nsome use cases but not so much for others.\nIn those other cases we usually recommend one of the Util methods.\nHowever, that might not always be appropriate since some edge cases might require more complex\nmanipulation of requests e.g. making a POST request to get an image.\n__ | Adding global headers is another use case but you can use\naddDefaultHeader\nto add those. To make this process simpler we added a set of helper methods to\nConnectionRequest that downloads images directly.\nThese methods complement the Util methods but go a bit further and feature very terse syntax e.g. we can just\ndownload a ConnectionRequest to Storage using code like this:\nrequest.downloadImageToStorage(url, (img) -\u0026gt; theImageIsHereDoSomethingWithIt(img)); New Callback \u0026amp; Callback Dispatcher You will notice that the terse code above accepted an argument that isn’t an ActionListener or a Runnable\nsince it passes an Image object in the callback.\nHistorically we had a little known interface in Codename One that was inspired by GWT called\nCallback. This interface\nwas used mainly for webservice calls so it had onSuccess/onError methods and a generic based response.\nWith Java 8 lambdas it occurred to us that it makes more sense to split this interface into two interfaces so\nwe can write more terse code and so we now have:\nSuccessCallback \u0026amp;\nFailureCallback.\nThese are pretty convenient and I’m pretty sure we’ll use them elsewhere.\nSignature As part of his work for a customer Steve implemented the SignatureComponent.\nThis allows an app to show a surface where the user can scribble a signature to approve a contract or detail\nwithin the app.\nSimple usage of the SignatureComponent class looks like this:\nForm hi = new Form(\u0026quot;Signature Component\u0026quot;); hi.setLayout(new BoxLayout(BoxLayout.Y_AXIS)); hi.add(\u0026quot;Enter Your Name:\u0026quot;); hi.add(new TextField()); hi.add(\u0026quot;Signature:\u0026quot;); SignatureComponent sig = new SignatureComponent(); sig.addActionListener((evt)-\u0026gt; { System.out.println(\u0026quot;The signature was changed\u0026quot;); Image img = sig.getSignatureImage(); // Now we can do whatever we want with the image of this signature. }); hi.addComponent(sig); hi.show(); Small Changes Component.remove() We added the ability to do Component.remove().\nThis is really shorthand syntax for the somewhat contrived getParent() syntax but it’s also pretty helpful when\nwe aren’t sure if there is a parent.\nSo in effect it saves us the cost of an additional if statement.\nGeneric Action Listener \u0026amp; NetworkEvent Callbacks Up until now NetworkEvent\nwas pretty painful to use. E.g. if you wanted to monitor networking code via a listener you always had to\ndowncast to the NetworkEvent e.g.:\nNetworkManager.getInstance().addErrorListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { NetworkEvent e = (NetworkEvent)ev; // do something... } }); Or with Java 8 syntax:\nNetworkManager.getInstance().addErrorListener((ev) -\u0026gt; { NetworkEvent e = (NetworkEvent)ev; // do something... }); This sucks and made us constantly rethink our decision to use ActionListener everywhere…​\nUntil we suddenly realized we can generify ActionListener which is now ActionListener\u0026lt;T\u0026gt;. As a result\nwe made all the listener events in NetworkManager and ConnectionRequest use NetworkEvent\nas the generic and the result is that this works:\nNetworkManager.getInstance().addErrorListener((networkEventInstance) -\u0026gt; { // do something... }); Shorter Padding/Margin Syntax I’ve been writing a lot of demos and one of the things I try to do when writing demo code is to keep it as self\ncontained as possible so it will work on your machines.\nThis is sometimes challenging as providing things such as theme instructions to reproduce my results is probably\nnot intuitive. So to reproduce some behaviors I use Style manipulation code rather than themes which are superior\nbut harder to convey in a manual.\nAs part of that I was manipulating margin and wanted to make sure the margin is in DIPs (millimeters). The common\ncode for this is:\ncmp.getAllStyles().setMarginUnit(Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS); This applies to all 4 sides of the margin/padding but if this seems redundant to you then you are not the only one…​\nSo from now on if you have less than 4 elements only the first one will count so this statement will be equivalent:\ncmp.getAllStyles().setMarginUnit(Style.UNIT_TYPE_DIPS); This also applies to padding so you can use that syntax there. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nYaakov Gesher — March 1, 2016 at 10:15 am (permalink) Great stuff! It’s wonderful to see constant API improvements and new features every month!\nFlying Bytes Jansen — March 9, 2016 at 2:46 pm (permalink) Flying Bytes Jansen says:\nThe SignatureComponent is just what I need. When will it be available?\nShai Almog — March 10, 2016 at 3:44 am (permalink) Shai Almog says:\nIt was released yesterday. Just do an Update Client Libs to get the latest and it will \u0026ldquo;just work\u0026rdquo;.\nFlying Bytes Jansen — March 10, 2016 at 8:49 am (permalink) Flying Bytes Jansen says:\nGreat, thank you!\nMahmoud — July 30, 2018 at 9:56 am (permalink) Mahmoud says:\nDear Shai,\nThere is an issue in Signature Component (ios,android) i cant draw dot(point) by one click\nto draw it i need to press down and small move to any side\nyour help plz\nBR,\nShai Almog — July 31, 2018 at 5:20 am (permalink) Shai Almog says:\nHi,\nI’ve made a small change which should hopefully resolve this.\nMahmoud — July 31, 2018 at 5:38 am (permalink) Mahmoud says:\nyou mean new change in new bulid or new update lib?\nShai Almog — August 2, 2018 at 5:51 am (permalink) Shai Almog says:\nIn the library. We’ll have the fix after you update this Friday. If it happens after that let me know.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/downloads-callbacks-signature-more/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/downloads-callbacks-signature-more/signature.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve had a busy week working with several customers on various tasks/issues as well as the documentation\u003cbr\u003e\nwhich is practically unrecognizable by now (more than 600 pages by now). As a result a lot of small fixes and\u003cbr\u003e\nenhancements were made to the code as well as one new niche component.\u003c/p\u003e\n\u003ch3 id=\"connectionrequestdownloadimagetostorage\"\u003eConnectionRequest.downloadImageToStorage\u003c/h3\u003e\n\u003cp\u003eWe have multiple ways to download an image and our general favorite is the \u003ca href=\"/javadoc/com/codename1/ui/URLImage/\"\u003eURLImage\u003c/a\u003e.\u003cbr\u003e\nHowever, the \u003ca href=\"/javadoc/com/codename1/ui/URLImage/\"\u003eURLImage\u003c/a\u003e assumes\u003cbr\u003e\nthat you know the size of the image in advance or that you are willing to resize it. In that regard it works great for\u003cbr\u003e\nsome use cases but not so much for others.\u003c/p\u003e","title":"Downloads, Callbacks, Signature \u0026 More"},{"content":"\nA very common UI pattern is the 5 star ranking system. Up until recently we always had the same answer\nwhen developers asked us how to implement it: \u0026ldquo;Use toggle buttons\n(CheckBox)\u0026rdquo;.\nThis is still not a bad answer but we think there is a \u0026ldquo;better\u0026rdquo; simpler way to do this thru the\nSlider which was\neffectively designed with this usage in mind.\nThe best way to do that is to just create two images with all 5 stars full and with all 5 stars empty and assign\nthis to the Slider/SliderFull UIID’s. Keep in mind that you need to apply both to the selected and unselected\nstates of the UIID’s.\n__ | You can change the UIID of slider itself e.g. to something like \u0026ldquo;Stars\u0026rdquo; at which point the UIID’s will be\nStars \u0026amp; StarsFull. This will allow your users to click/drag to select the number of stars. The code below uses the star material icon\nto generate something like this on the fly without any resources.\n__ | We enclose the slider in a FlowLayout to prevent it from growing. This is because I chose the stars to be tiled\ninstead of aligned (like we could if we used an image). So if the component will grow it won’t have the right feel.\nEnclosing the component in a FlowLayout is an old trick to prevent components from growing beyond their preferred\nsize. private void initStarRankStyle(Style s, Image star) { s.setBackgroundType(Style.BACKGROUND_IMAGE_TILE_BOTH); s.setBorder(Border.createEmpty()); s.setBgImage(star); s.setBgTransparency(0); } private Slider createStarRankSlider() { Slider starRank = new Slider(); starRank.setEditable(true); starRank.setMinValue(0); starRank.setMaxValue(10); Font fnt = Font.createTrueTypeFont(\u0026quot;native:MainLight\u0026quot;, \u0026quot;native:MainLight\u0026quot;). derive(Display.getInstance().convertToPixels(5, true), Font.STYLE_PLAIN); Style s = new Style(0xffff33, 0, fnt, (byte)0); Image fullStar = FontImage.createMaterial(FontImage.MATERIAL_STAR, s).toImage(); s.setOpacity(100); s.setFgColor(0); Image emptyStar = FontImage.createMaterial(FontImage.MATERIAL_STAR, s).toImage(); initStarRankStyle(starRank.getSliderEmptySelectedStyle(), emptyStar); initStarRankStyle(starRank.getSliderEmptyUnselectedStyle(), emptyStar); initStarRankStyle(starRank.getSliderFullSelectedStyle(), fullStar); initStarRankStyle(starRank.getSliderFullUnselectedStyle(), fullStar); starRank.setPreferredSize(new Dimension(fullStar.getWidth() * 5, fullStar.getHeight())); return starRank; } private void showStarPickingForm() { Form hi = new Form(\u0026quot;Star Slider\u0026quot;, new BoxLayout(BoxLayout.Y_AXIS)); hi.add(FlowLayout.encloseCenter(createStarRankSlider())); hi.show(); } In this code you will notice we allow selecting a value between 0 \u0026amp; 10 where 10 is really 5 stars. This allows us\nto pick values like 4.5 stars and just divide the actual value. However, most ranking systems don’t allow a value\nbelow 1 star. To solve this you can just use a Label to represent the first star and use a the Slider for the remaining\n4 stars. In which case the values would be between 0 – 8.\nTerse commands I love lambdas. I wasn’t a fan before they were introduced but they grew on me and made me a convert.\nOne of the annoyances I had with Codename One was with using Command syntax which forced me to fallback\nto pre-lambda code for practically everything as Command is a class and not a single method interface. This\nbothered me enough to do something about it so now we have ActionListener versions of many Command API’s.\nThese all redirect to the\nCommand.create(String,Image,ActionListener)\nmethod which effectively creates a Command with the given details for the given action listener. So instead\nof writing code like this:\nform.getToolbar().addToSideMenu(new Command(\u0026quot;My Command\u0026quot;) { public void actionPerformed(ActionEvent ev) { myCodeHere(); } }); I can write this:\nform.getToolbar().addToSideMenu(Command.create(\u0026quot;My Command\u0026quot;, null, (ev) -\u0026gt; { myCodeHere(); })); And to make things even simpler I created helper methods that do that implicitly in Toolbar and Form:\nform.getToolbar().addToSideMenu(\u0026quot;My Command\u0026quot;, null, (ev) -\u0026gt; { myCodeHere(); }); Notice that the version of this method that accepts a the action listener also returns the created Command instance\nwhich might be useful if you want to do something with the command later on (e.g. remove it). So this should work:\nCommand cmd = form.getToolbar().addToSideMenu(\u0026quot;My Command\u0026quot;, null, (ev) -\u0026gt; { myCodeHere(); }); Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDiamond — February 24, 2016 at 2:49 pm (permalink) Diamond says:\nHi Shai,\nPlease check this page, it’s not aligned.\nShai Almog — February 24, 2016 at 2:52 pm (permalink) Shai Almog says:\nHi Diamond,\nI just played a bit with the UI for asciidoc conversion of blog posts. What browser/OS combination are you using? Can you provide a screenshot so I can see if we are seeing the same thing?\nDiamond — February 24, 2016 at 5:50 pm (permalink) Diamond says:\nChrome on Windows 10 machine.\nHere is the screenshot.\nShai Almog — February 24, 2016 at 6:39 pm (permalink) Shai Almog says:\nGotcha, that’s a really wide screen. Looking into it.\nShai Almog — February 25, 2016 at 7:25 pm (permalink) Shai Almog says:\nJust did an update, is it better?\nDiamond — February 25, 2016 at 7:26 pm (permalink) Diamond says:\nYes, it’s fixed now.\nShai Almog — December 20, 2016 at 4:43 am (permalink) Shai Almog says:\nThanks!\nJust use getProgress() on the Slider component: http://codenameone.com/java…\nNot the most intuitive method name for this case but we initially designed it as a progress indicator…\nsafa — April 29, 2017 at 10:53 pm (permalink) safa says:\nhello , how can i get and set the values of rating stars?\nShai Almog — April 30, 2017 at 4:14 am (permalink) Shai Almog says:\nThe guy who asked this 4 months ago deleted his question but my answer is the same:\nJust use getProgress() on the Slider component: http://codenameone.com/java…\nNot the most intuitive method name for this case but we initially designed it as a progress indicator…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/its-full-of-stars-terse-commands/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/its-full-of-stars-terse-commands/components-slider.png\"\u003e\u003c/p\u003e\n\u003cp\u003eA very common UI pattern is the 5 star ranking system. Up until recently we always had the same answer\u003cbr\u003e\nwhen developers asked us how to implement it: \u0026ldquo;Use toggle buttons\u003cbr\u003e\n(\u003ca href=\"/javadoc/com/codename1/ui/CheckBox/#createToggle-com.codename1.ui.Image-\"\u003eCheckBox\u003c/a\u003e)\u0026rdquo;.\u003c/p\u003e\n\u003cp\u003eThis is still not a bad answer but we think there is a \u0026ldquo;better\u0026rdquo; simpler way to do this thru the\u003cbr\u003e\n\u003ca href=\"/javadoc/com/codename1/ui/Slider/\"\u003eSlider\u003c/a\u003e which was\u003cbr\u003e\neffectively designed with this usage in mind.\u003c/p\u003e\n\u003cp\u003eThe best way to do that is to just create two images with all 5 stars full and with all 5 stars empty and assign\u003cbr\u003e\nthis to the \u003ccode\u003eSlider\u003c/code\u003e/\u003ccode\u003eSliderFull\u003c/code\u003e UIID’s. Keep in mind that you need to apply both to the selected and unselected\u003cbr\u003e\nstates of the UIID’s.\u003c/p\u003e","title":"It's Full Of Stars \u0026 Terse Commands"},{"content":"\nJust last week I wrote that we are making an effort not to add new features and we got foiled by a couple of new features.\nThe main reason for this is paying customers who need to\nhave a feature now. This makes it hard for us to focus completely, but it does keep the lights on\nhere so we can’t really complain.+\nTo be fair, during this time we were able to almost double the page count of the developer guide from the\n3.2 era to 584 pages at this moment and we still have a lot of work ahead of us in that department.\nToastBar Steve was working with a customer who needed a none obtrusive notification system at the bottom similar\nto the newer versions of Android’s toast UI. Fabricio already built a\nnative cn1lib for toast messages but because the library is native it\nisn’t as flexible as we needed.\nThe new ToastBar API\nstarted off as a StatusBar API but we changed that to avoid confusion with the iOS StatusBar. Here\nis a quick video Steve made showing off the ToastBar.\nGaussian Blur \u0026amp; Dialog Blur Some effects are very easy to accomplish in Codename One while others not so much. Gaussian blur is\none of those none trivial effects that become even harder to achieve when performance is of the essence.\nIts a really powerful effect that makes the UI standout over the background and should be built in now that\nits a builtin part of iOS 8+.\nWe now have two new API’s in Display:\ngaussianBlurImage \u0026amp;\nisGaussianBlurSupported.\nThese API’s let us apply the blur to an arbitrary image which is useful for many things.\nOne of the chief uses for this is blurring a Dialog. We can apply Gaussian blur to the background of a dialog\nto highlight the foreground further and produce a very attractive effect. We can use the\nsetDefaultBlurBackgroundRadius to apply this globally, we can use the theme constant dialogBlurRadiusInt\nto do the same or we can do this on a per Dialog basis using setBlurBackgroundRadius.\nForm hi = new Form(\u0026quot;Blur Dialog\u0026quot;, new BoxLayout(BoxLayout.Y_AXIS)); Dialog.setDefaultBlurBackgroundRadius(8); Button showDialog = new Button(\u0026quot;Blur\u0026quot;); showDialog.addActionListener((e) -\u0026gt; Dialog.show(\u0026quot;Blur\u0026quot;, \u0026quot;Is On....\u0026quot;, \u0026quot;OK\u0026quot;, null)); hi.add(showDialog); hi.show(); Figure 1. Gaussian Blur behind the Dialog Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDiamond — February 22, 2016 at 7:07 pm (permalink) Hi Shai \u0026amp; Steve,\nCan the Toast bar be shifted to the top of the screen?\nIs it possible to change the level of image blur on container tensileDrag?\nshannah78 — February 22, 2016 at 8:05 pm (permalink) shannah78 says:\nI have just added a ToastBar.setPosition() method that will allow you to move the toastbar to the top of the the form. I’ll leave to Chen to answer the tensileDrag question.\nChidiebere Okwudire — February 22, 2016 at 8:47 pm (permalink) Chidiebere Okwudire says:\nHi Steve, nice job with the ToastBar. Just on time as I was considering implementing something like that. I have two questions about the ToastBar:\n1. Can ToastBars be cascaded? Use case: For example when network is down, I want to show a permanent ‘offline mode’ message. However, in the mean time, there might be ‘real toasts’ in which case I’d like to show second toast temporarily above the permanent ‘offiline mode’ notice. Is that possible?\n2. Can we add a button the toast bar? This is common e.g. in the gmail app where a right-aligned ‘UNDO’ button is added to the toast. Here’s an example: i.stack.imgur.com/LWClq.jpg\nshannah78 — February 22, 2016 at 10:08 pm (permalink) shannah78 says:\n\u0026ldquo;Can ToastBars be cascaded?\u0026rdquo;\nYou can add multiple statuses. When a status is cleared or expires, it will show the next status in line. If you want to \u0026ldquo;bring a status to the front\u0026rdquo;, you can just call \u0026ldquo;show()\u0026rdquo; on that status again and it will be brought to the front.\n\u0026ldquo;Can we add a button the toast bar?\u0026rdquo;\nNot right now. If this is something that is useful, it wouldn’t be hard to add though.\nShai Almog — February 23, 2016 at 3:32 am (permalink) Shai Almog says:\nDo you mean something like the iOS swipe to search effect?\nI think it’s more of a swipe than a tensile drag.\nDiamond — February 23, 2016 at 4:01 am (permalink) Diamond says:\nThis effect occurs on some apps, when you pull down the profile container, the blurred profile image at the top begins to get clearer.\nShai Almog — February 23, 2016 at 4:05 am (permalink) Shai Almog says:\nWe don’t have an event for tensile drag but you might be able to use this with the title animation. However, I’d use the Gaussian blur method once rather than as needed during drag as it can be a pretty expensive method.\nDiamond — February 23, 2016 at 4:10 am (permalink) Diamond says:\nI found another way that could be achieved, apply it to a placeholder image which is overlayed on the profile image and decrease the alpha (opacity) as the container is scrolled or pull down.\nChidiebere Okwudire — February 23, 2016 at 8:29 am (permalink) Chidiebere Okwudire says:\n1. Great! It would be nice to add this to the examples\n2. I think it’s useful and quite common in apps these days\nJérémy MARQUER — February 23, 2016 at 8:33 am (permalink) Jérémy MARQUER says:\nReally nice features 🙂\nKyri Ioulianou — June 22, 2016 at 6:24 pm (permalink) Kyri Ioulianou says:\nHi Shai. The dialog blur seems to be removing all text in the background. Is there any way to prevent this?\nShai Almog — June 23, 2016 at 3:12 am (permalink) Shai Almog says:\nThe screenshot above blurrly shows the text so I don’t know what you are talking about?\nKyri Ioulianou — June 24, 2016 at 9:09 am (permalink) Kyri Ioulianou says:\nBefore and after a gausian blur. See how the text dissappears?\nShai Almog — June 24, 2016 at 9:22 am (permalink) Shai Almog says:\nIf it’s only on the simulator it could be related to this fixed bug\nElijah Mulili Mulwa — October 1, 2019 at 6:25 am (permalink) Elijah Mulili Mulwa says:\nI am displaying images on my codename projects and some of them appear blurred, what could be the reason?\nShai Almog — October 2, 2019 at 7:37 pm (permalink) Shai Almog says:\nHow do you display the images and where do you get them from?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/toastbar-gaussian-blur/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/toastbar-gaussian-blur/toastbar.png\"\u003e\u003c/p\u003e\n\u003cp\u003eJust last week I wrote that we are making an effort not to add new features and we got foiled by a couple of new features.\u003cbr\u003e\nThe main reason for this is paying customers who need to\u003cbr\u003e\nhave a feature \u003cstrong\u003enow\u003c/strong\u003e. This makes it hard for us to focus completely, but it does keep the lights on\u003cbr\u003e\nhere so we can’t really complain.+\u003cbr\u003e\nTo be fair, during this time we were able to almost double the page count of the developer guide from the\u003cbr\u003e\n3.2 era to 584 pages at this moment and we still have a lot of work ahead of us in that department.\u003c/p\u003e","title":"ToastBar \u0026 Gaussian Blur"},{"content":"\nWe are trying to improve the visibility of Codename One within search engines and as part of that\nwe think we can also help you guys improve your visibility. When you submit your apps to the app gallery we\nprovide dofollow links to your website/app store listings. We’d appreciate if you place dofollow links back to\nhttps://www.codenameone.com/ which you can place in a very hidden/unobtrusive way. This helps us increase\nour page rank and as a result will improve your page rank as we link back to you.\nTo add your app to the app gallery just comment on the post below with full details/link to your app. Make sure\nto include the package name, we need to verify that the app was built with Codename One and we don’t accept\nany other apps so please don’t post such entries as they would be deleted and comment links are \u0026ldquo;nofollow\u0026rdquo;\nanyway.\nFYI the moderation system might block posts with links and put them in the moderation queue, we get a notification\non that and approve the comments if they are indeed valid.\nPerformance Optimizations For ParparVM Sanny Sanoff submitted a major\npull request that’s already on the build servers.\nIt’s a very ambitious change and based on our internal benchmarks it does improve quite a few things in terms of\non-device performance.\nIt’s hard to tell how much of a difference will be felt in real world applications with changes like this as VM’s\nare pretty different from one another. We find that the biggest performance differences we see is when we\nimprove the implementation of core API logic e.g. string handling primitives etc.\nJavaScript Builds \u0026amp; Static Initializers With the recent news that JavaScript builds are now available to a wider audience we also ran into some issues.\nWe are working on releasing an updated version of the VM based on the latest code from TeaVM\nwhich will hopefully solve some of these problems. Since this is a big change it is taking a while but we hope to finish\nit this week…​\nOne point that didn’t get enough attention when we released the original JavaScript port was an issue it has with\nstatic initializers. TeaVM does some pretty insane things to make threading \u0026ldquo;feel\u0026rdquo; real despite\nthe fact that the browser is single threaded. Essentially every call to wait/notify etc. triggers a split in the generated\ncode that allows the VM to switch co-operatively to other code. For 98% of the code this is totally seamless as\nproper code would eventually block somewhere.\nHowever, static initializers are a bit of a special case here. It seems that its impossible to split them in a way\nthat allows this functionality. So you can still use static initializers but you can’t call wait/notify etc. within them.\nNormally that’s not a big deal, however it becomes a big deal when you realize that this also applies to code you\ninvoke indirectly e.g. image loading IO would trigger wait for the IO operation to complete internally. The workaround\nis to do image loading lazily and not in the static initializer, ideally we’d like a more robust workaround but since\nthis is a rather elaborate issue I’m not really sure how practical that would be.\nRetry on the Google Play Services Patch We had some issues with gradle Android builds last week and we eventually changed the default build back to\nant just so we could get thru the week. We restored gradle builds today and hopefully fixed the issues with the\nbuild process, if you notice anything this might be due to that…​\nPlease let us know at once if there are any recent regressions related to the Android build here. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChibuike Mba — February 19, 2016 at 2:56 pm (permalink) Chibuike Mba says:\nHi Shai, we have CodenameOne logo and link on our app website: http://ozioma.net\nOur app \u0026ldquo;Ozioma\u0026rdquo; is already on the CodenameOne app gallery here: https://www.codenameone.com… but I want to change the screenshots of the app to the newer version screenshot, how can I do that?\nApp package id: net.chibex.ozioma\nThanks.\nFabrizio Grassi — February 20, 2016 at 12:16 am (permalink) Fabrizio Grassi says:\nHi Shai, I just added your logo to my app site: http://apps-rbryx.rhcloud.com\nright now iJobClock is my only app.\npackage id: org.rbryx.iJobClock\nMany thanks\nShai Almog — February 20, 2016 at 4:07 am (permalink) Shai Almog says:\nGreat. Can I just grab the screenshots from your home page and update the app?\nShai Almog — February 20, 2016 at 4:07 am (permalink) Shai Almog says:\nThanks, adding it soon!\nChibuike Mba — February 20, 2016 at 8:28 am (permalink) Chibuike Mba says:\nYes, some of them not all. 5 screenshots are ok.\nThanks.\nShai Almog — February 21, 2016 at 4:01 am (permalink) Shai Almog says:\nThanks. Its updated now. Might take a moment for images to refresh in the CDN.\nApp looks REALLY great!\nWhen is the iOS version coming?\nChibuike Mba — February 21, 2016 at 11:40 am (permalink) Chibuike Mba says:\nOK Shai, Thanks.\niOS version will be coming in the next version of the app before the end of April this year.\nThanks once again, I appreciate.\nYaakov Gesher — March 1, 2016 at 10:07 am (permalink) Yaakov Gesher says:\nI just uploaded my app to Google Play: https://play.google.com/sto…. iOS version coming soon!\nsao — March 1, 2016 at 11:12 am (permalink) sao says:\nHi Shai, this is the google play id/link of the SNOS app:\nhttps://play.google.com/sto…\npackage id: com.teledom.snosapp\nNB: The app is yet to be marketed and taken to markets for clients to start using, thus the download rate from Google Play is still very low at the moment.\nThank you!\nAfam\nShai Almog — March 2, 2016 at 4:17 am (permalink) Shai Almog says:\nAdded. Thanks.\nShai Almog — March 2, 2016 at 4:17 am (permalink) Shai Almog says:\nAdded. Thanks!\nJames van Kessel — March 9, 2017 at 8:54 pm (permalink) James van Kessel says:\nHello Shai, Here’s the Google Play version of my new app (My First real app published to the app store!): https://play.google.com/sto…\npackage id: ca.zettabot.trainingtool\nApple version is pending on the wise meditations of the Apple Gurus in the sky…\nShai Almog — March 10, 2017 at 8:41 am (permalink) Shai Almog says:\nHi,\nthat’s great to hear. We’ll add this soon. Keep us posted when the app makes it to itunes.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/seo-gallery-performance-javascript-gradle/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/seo-gallery-performance-javascript-gradle/parparvm-blog.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are trying to improve the visibility of Codename One within search engines and as part of that\u003cbr\u003e\nwe think we can also help you guys improve your visibility. When you submit your apps to the app gallery we\u003cbr\u003e\nprovide dofollow links to your website/app store listings. We’d appreciate if you place dofollow links back to\u003cbr\u003e\n\u003ca href=\"https://www.codenameone.com/\"\u003ehttps://www.codenameone.com/\u003c/a\u003e which you can place in a very hidden/unobtrusive way. This helps us increase\u003cbr\u003e\nour page rank and as a result will improve your page rank as we link back to you.\u003c/p\u003e","title":"SEO, Gallery, Performance, JavaScript \u0026 Gradle"},{"content":"\nAs you know we’ve been working a lot on the docs both the developer guide and the JavaDoc’s, we nearly doubled\nthe amount pages in the developer guide and we did it without \u0026ldquo;cheating\u0026rdquo; (e.g. cramming more stuff, increasing font size).\nYou can see all that work in the developer guide section but what I want\nto discuss today is the new Component Gallery\n\u0026amp; Layout Gallery.\nBoth of these are a result of the developer guide work; as we did that we mapped a lot of the work back into\nthe JavaDocs and eventually edited the package.html files to produce that level of detail. We’re particularly proud\nof the fact that if you click almost any component or layout within those galleries you will see sample usage code\nthat should help you get started with anything you need.\nWhen writing this sample code we tried to reflect back on a lot of the requests that you guys made from us, so things\nsuch as dynamically downloading images to lists, ImageViewer etc. are all covered. Carousel UI with the Tabs\ncomponent and even trivial things such as making a Button look like a link.\nThis take a lot of effort to do so please provide us as much feedback as you can on the process, e.g. on my last\npost a developer asked a question related to Table. The answer to that question is now (thanks to him) in the docs. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nSadart — February 17, 2016 at 12:35 pm (permalink) Sadart says:\nGood job done. Docs are now extremely good for getting sample codes. Time saver! I had to redo the downloaded images on a form to use imageviewer and I have been ignoring it for ages. The initial codes in the old docs wasn’t clear enough for me. I can now implement it with ease. Thanks.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/component-gallery/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/component-gallery/component-gallery.png\"\u003e\u003c/p\u003e\n\u003cp\u003eAs you know we’ve been working a lot on the docs both the developer guide and the JavaDoc’s, we nearly doubled\u003cbr\u003e\nthe amount pages in the developer guide and we did it without \u0026ldquo;cheating\u0026rdquo; (e.g. cramming more stuff, increasing font size).\u003cbr\u003e\nYou can see all that work in the \u003ca href=\"https://www.codenameone.com/manual/\"\u003edeveloper guide\u003c/a\u003e section but what I want\u003cbr\u003e\nto discuss today is the new \u003ca href=\"/javadoc/com/codename1/ui/package-summary/\"\u003eComponent Gallery\u003c/a\u003e\u003cbr\u003e\n\u0026amp; \u003ca href=\"/javadoc/com/codename1/ui/layouts/package-summary/\"\u003eLayout Gallery\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eBoth of these are a result of the developer guide work; as we did that we mapped a lot of the work back into\u003cbr\u003e\nthe JavaDocs and eventually edited the \u003ccode\u003epackage.html\u003c/code\u003e files to produce that level of detail. We’re particularly proud\u003cbr\u003e\nof the fact that if you click almost any component or layout within those galleries you will see sample usage code\u003cbr\u003e\nthat should help you get started with anything you need.\u003c/p\u003e","title":"Component \u0026 Layout Galleries"},{"content":"\nTable is a composite component\n(but it isn’t a lead component),\nthis means it is a subclass of Container.\nIt’s effectively built from multiple components.\n__ | Table is heavily based on the\nTableLayout class. It’s important\nto be familiar with that layout manager when working with Table. Here is a trivial sample of using the standard table component:\nForm hi = new Form(\u0026quot;Table\u0026quot;, new BorderLayout()); TableModel model = new DefaultTableModel(new String[] {\u0026quot;Col 1\u0026quot;, \u0026quot;Col 2\u0026quot;, \u0026quot;Col 3\u0026quot;}, new Object[][] { {\u0026quot;Row 1\u0026quot;, \u0026quot;Row A\u0026quot;, \u0026quot;Row X\u0026quot;}, {\u0026quot;Row 2\u0026quot;, \u0026quot;Row B\u0026quot;, \u0026quot;Row Y\u0026quot;}, {\u0026quot;Row 3\u0026quot;, \u0026quot;Row C\u0026quot;, \u0026quot;Row Z\u0026quot;}, {\u0026quot;Row 4\u0026quot;, \u0026quot;Row D\u0026quot;, \u0026quot;Row K\u0026quot;}, }) { public boolean isCellEditable(int row, int col) { return col != 0; } }; Table table = new Table(model); hi.add(BorderLayout.CENTER, table); hi.show(); Figure 1. Simple Table usage\n__ In the sample above the title area and first column aren’t editable. The other two columns are editable. The more \u0026ldquo;interesting\u0026rdquo; aspects of the Table class can be achieved via the TableLayout. You can use the layout constraints (also exposed in the table class) to create spanning and elaborate UI’s.\nE.g.:\nForm hi = new Form(\u0026quot;Table\u0026quot;, new BorderLayout()); TableModel model = new DefaultTableModel(new String[] {\u0026quot;Col 1\u0026quot;, \u0026quot;Col 2\u0026quot;, \u0026quot;Col 3\u0026quot;}, new Object[][] { {\u0026quot;Row 1\u0026quot;, \u0026quot;Row A\u0026quot;, \u0026quot;Row X\u0026quot;}, {\u0026quot;Row 2\u0026quot;, \u0026quot;Row B can now stretch\u0026quot;, null}, {\u0026quot;Row 3\u0026quot;, \u0026quot;Row C\u0026quot;, \u0026quot;Row Z\u0026quot;}, {\u0026quot;Row 4\u0026quot;, \u0026quot;Row D\u0026quot;, \u0026quot;Row K\u0026quot;}, }) { public boolean isCellEditable(int row, int col) { return col != 0; } }; Table table = new Table(model) { @Override protected TableLayout.Constraint createCellConstraint(Object value, int row, int column) { TableLayout.Constraint con = super.createCellConstraint(value, row, column); if(row == 1 \u0026amp;\u0026amp; column == 1) { con.setHorizontalSpan(2); } con.setWidthPercentage(33); return con; } }; hi.add(BorderLayout.CENTER, table); Figure 2. Table with spanning \u0026amp; fixed widths to 33%\nIn order to customize the table cell behavior you can derive the Table to create a \u0026ldquo;renderer like\u0026rdquo; widget, however unlike the list this component is \u0026ldquo;kept\u0026rdquo; and used as is. This means you can bind listeners to this component and work with it as you would with any other component in Codename One.\nSo lets fix the example above to include far more capabilities:\nTable table = new Table(model) { @Override protected Component createCell(Object value, int row, int column, boolean editable) { __**(1)** Component cell; if(row == 1 \u0026amp;\u0026amp; column == 1) { __**(2)** Picker p = new Picker(); p.setType(Display.PICKER_TYPE_STRINGS); p.setStrings(\u0026quot;Row B can now stretch\u0026quot;, \u0026quot;This is a good value\u0026quot;, \u0026quot;So Is This\u0026quot;, \u0026quot;Better than text field\u0026quot;); p.setSelectedString((String)value); __**(3)** p.setUIID(\u0026quot;TableCell\u0026quot;); p.addActionListener((e) -\u0026gt; getModel().setValueAt(row, column, p.getSelectedString())); __**(4)** cell = p; } else { cell = super.createCell(value, row, column, editable); } if(row \u0026gt; -1 \u0026amp;\u0026amp; row % 2 == 0) { __**(5)** // pinstripe effect cell.getAllStyles().setBgColor(0xeeeeee); cell.getAllStyles().setBgTransparency(255); } return cell; } @Override protected TableLayout.Constraint createCellConstraint(Object value, int row, int column) { TableLayout.Constraint con = super.createCellConstraint(value, row, column); if(row == 1 \u0026amp;\u0026amp; column == 1) { con.setHorizontalSpan(2); } con.setWidthPercentage(33); return con; } }; __1 The createCell method is invoked once per component but is similar conceptually to the List renderer. Notice that it doesn’t return a \u0026ldquo;rubber stamp\u0026rdquo; though, it returns a full component. __2 We only apply the picker to one cell for simplicities sake. __3 We need to set the value of the component manually, this is crucial since the Table doesn’t \u0026ldquo;see\u0026rdquo; this. __4 We need to track the event and update the model in this case as the Table isn’t aware of the data change. __5 We set the \u0026ldquo;pinstripe\u0026rdquo; effect by coloring even rows. Notice that unlike renderers we only need to apply the coloring once as the Components are stateful. Figure 3. Table with customize cells using the pinstripe effect\nFigure 4. Picker table cell during edit Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nTommy Mogaka — February 14, 2016 at 5:03 am (permalink) In the case that cell contents are too long, is it possible to stretch the cell vertically by wordwraping its contents so that they don’t truncate out or push the content of the cell next to it out of view?\nThanks for the update on tables…. this is the one UI item many are long awaiting!\nOn the work on the documentation, a thumbs up! It will go a long way to making CN1 easily adopted by more developers.\nShai Almog — February 15, 2016 at 3:24 am (permalink) Thanks, that’s a great headsup on something that we missed in the table docs!\nWe added that into the developer guide and you’ll see an additional section talking about line wrapping and its pitfalls in the coming update of the guide later today.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/understanding-the-table-component/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/understanding-the-table-component/table-post-title.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/javadoc/com/codename1/ui/table/Table/\"\u003eTable\u003c/a\u003e is a composite component\u003cbr\u003e\n(but it isn’t a \u003ca href=\"/manual/components/#lead-component-sidebar\"\u003elead component\u003c/a\u003e),\u003cbr\u003e\nthis means it is a subclass of \u003ca href=\"/javadoc/com/codename1/ui/Container/\"\u003eContainer\u003c/a\u003e.\u003cbr\u003e\nIt’s effectively built from multiple components.\u003c/p\u003e\n\u003cp\u003e__ |  \u003ccode\u003eTable\u003c/code\u003e is heavily based on the\u003cbr\u003e\n\u003ca href=\"/javadoc/com/codename1/ui/table/TableLayout/\"\u003eTableLayout\u003c/a\u003e class. It’s important\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eto be familiar with that layout manager when working with \u003ccode\u003eTable\u003c/code\u003e.\u003c/th\u003e\n          \u003cth\u003e\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eHere is a trivial sample of using the standard table component:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eForm hi = new Form(\u0026quot;Table\u0026quot;, new BorderLayout());\nTableModel model = new DefaultTableModel(new String[] {\u0026quot;Col 1\u0026quot;, \u0026quot;Col 2\u0026quot;, \u0026quot;Col 3\u0026quot;}, new Object[][] {\n    {\u0026quot;Row 1\u0026quot;, \u0026quot;Row A\u0026quot;, \u0026quot;Row X\u0026quot;},\n    {\u0026quot;Row 2\u0026quot;, \u0026quot;Row B\u0026quot;, \u0026quot;Row Y\u0026quot;},\n    {\u0026quot;Row 3\u0026quot;, \u0026quot;Row C\u0026quot;, \u0026quot;Row Z\u0026quot;},\n    {\u0026quot;Row 4\u0026quot;, \u0026quot;Row D\u0026quot;, \u0026quot;Row K\u0026quot;},\n    }) {\n        public boolean isCellEditable(int row, int col) {\n            return col != 0;\n        }\n    };\nTable table = new Table(model);\nhi.add(BorderLayout.CENTER, table);\nhi.show();\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003cimg alt=\"Simple Table usage\" loading=\"lazy\" src=\"/blog/understanding-the-table-component/components-table.png\"\u003e\u003c/p\u003e","title":"Understanding The Table Component"},{"content":"\nI’ve been remarkably busy working on issues and documentation so I neglected an important announcement I\nhad to make. Over the weekend we flipped the default build from gradle back to ant. So effectively if you don’t set\nany build hint the behavior will be android.gradle=false which should work fine for most of you. This is temporary but\nwe felt it was necessary as a stopgap measure.\nIn other news it seems that fixing the Codename One documentation is like diving into a bottomless pit.\nWhen we started this effort the developer guide was 300 pages it is now approaching 500 pages and we\naren’t close to half way thru…​\nThis doesn’t even cover all the work we did with refining the JavaDocs and there is a lot of work that needs doing\non that side of the fence.\nDuring this time I’ve made a conscious effort not to do anything significant that isn’t documentation writing but\nsome code had to go thru. Specifically things related to syntax that needed doing for the developer guide.\nCheckBox Toggle Syntax Up until now we had terse syntax for creating a toggle button for a RadioButton but we didn’t have anything\nlike that for the CheckBox. So we added a couple of methods:\ncreateToggle(Image icon)\ncreateToggle(String text)\ncreateToggle(String text, Image icon)\nButtonGroup Shortcut Up until now creating a RadioButton required adding it to a ButtonGroup which was tedious.\nTo solve this we added a varargs\naddAll(Component…​)\nmethod as well as a varargs constructor.\nComponentGroup enclose ComponentGroup didn’t have an enclose method which is one of those things that beg for a fix since its the\nContainer for that sort of API.\nSo we added two enclose methods:\nenclose(Component…​)\nencloseHorizontal(Component…​)\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/android-gradle-build-status-minor-changes/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/android-gradle-build-status-minor-changes/gradle.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been remarkably busy working on issues and documentation so I neglected an important announcement I\u003cbr\u003e\nhad to make. Over the weekend we flipped the default build from gradle back to ant. So effectively if you don’t set\u003cbr\u003e\nany build hint the behavior will be \u003ccode\u003eandroid.gradle=false\u003c/code\u003e which should work fine for most of you. This is temporary but\u003cbr\u003e\nwe felt it was necessary as a stopgap measure.\u003c/p\u003e\n\u003cp\u003eIn other news it seems that fixing the Codename One documentation is like diving into a bottomless pit.\u003cbr\u003e\nWhen we started this effort the developer guide was 300 pages it is now approaching 500 pages and we\u003cbr\u003e\naren’t close to half way thru…​\u003c/p\u003e","title":"Android Gradle Build Status \u0026 Minor Changes"},{"content":"\nWe’d like to thank all of you who signed up to the pro subscription, the release of 3.3 is the perfect time to\ndo that. So we are opening up the JavaScript build target for 1 year until March 1st 2017 to all current pro subscribers!\nIf you have a pro subscription you can start sending a JavaScript build right away and experiment with porting\nyour app to the web…\nIf you don’t have a pro license currently then you have until March 15th to upgrade and enjoy this offer. After\nMarch 15th the JavaScript port will return to enterprise only status for everyone who didn’t signup prior to that.\nIf you are not familiar with the JavaScript port check out Steve’s great writeup\non it, you can also try out some of our demos live right now here\n(using desktop or mobile browsers). Just click the JS Port link at the bottom right section of a demo e.g.\nrestaurant or property cross.\nFYI If you cancel the subscription during this time or let it lapse this capability will be lost so make sure to keep it in place.\nMemory Issue on Android Builds With the switch to gradle in Android builds we experienced memory issues for some cases when building huge\napps. For some cases ading android.gradle=false to the build hints was enough but for others\nnot so much.\nThe problem relates to the size of Google Play Services which are an essential part of Android applications but\nhave grown to a size that is pretty big. We need play services for better location tracking, in-app-purchase, push\nnotification, maps etc.\nIn the past we had the build hint android.includeGPlayServices which\ntried to be smart about play services but its a bit too coarse as it only accepts true/false.\nTo alleviate this issue we deprecated the android.includeGPlayServices and are introducing\nthe new build hints below that will allow you to selectively include a play service. This means that future builds\nto the Codename One build servers can have one of the following 5 states:\nandroid.includeGPlayServices=true \u0026amp; one or more of the android.playService\nentries defined – this is an illegal state and will cause the build to fail android.includeGPlayServices=true \u0026amp; no android.playService\nentries defined – this will fallback to compatibility mode android.includeGPlayServices=false \u0026amp; no android.playService\nentries defined – play services won’t be included android.includeGPlayServices undefined \u0026amp; no android.playService\nentries defined – some play services will be included by default specifically: plus, auth, base, analytics, gcm, location, maps,\nads. android.includeGPlayServices undefined \u0026amp; one or more android.playService\nentries defined – only the play services you explicitly select will be included. The last two are a bit confusing so just to clarify if you do this:\nandroid.playService.plus=true The only play service included will be plus. However, if you don’t define any build hints specifically the above list\nof play services will be included. This is a \u0026ldquo;sensible default mode\u0026rdquo; that we picked to make the transition easier.\nThe list of supported hints follows, they all accept true/false as arguments for inclusion/exclusion.\nandroid.playService.plus android.playService.auth android.playService.base android.playService.identity android.playService.indexing android.playService.appInvite android.playService.analytics android.playService.cast android.playService.gcm android.playService.drive android.playService.fitness android.playService.location android.playService.maps android.playService.ads android.playService.vision android.playService.nearby android.playService.panorama android.playService.games android.playService.safetynet android.playService.wallet android.playService.wearable Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/a-thank-you-an-important-update-on-android-builds/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/a-thank-you-an-important-update-on-android-builds/html5-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’d like to thank all of you who signed up to the pro subscription, the release of 3.3 is the perfect time to\u003cbr\u003e\ndo that. So we are opening up the JavaScript build target for 1 year until March 1st 2017 to all current pro subscribers!\u003cbr\u003e\nIf you have a pro subscription you can start sending a JavaScript build right away and experiment with porting\u003cbr\u003e\nyour app to the web…\u003cbr\u003e\nIf you don’t have a pro license currently then you have until March 15th to upgrade and enjoy this offer. After\u003cbr\u003e\nMarch 15th the JavaScript port will return to enterprise only status for everyone who didn’t signup prior to that.\u003c/p\u003e","title":"A Thank You \u0026 an Important Update On Android Builds"},{"content":"\nFacebook recently announced the closing of parse.com which is disappointing but not totally surprising. Everyone\nknows a project from a large tech company can just shutdown in a blink of an eye leaving millions of users/developers\nin limbo. In that sense one of the questions that gets under my skin is what happens if Codename One calls it\nquits…\nYou’d be better off than anyone who used parse and its far less likely to happen. Codename One is \u0026ldquo;what we do\u0026rdquo;\nand have been doing for the past 4 years. More importantly, unlike Parse you could just use the open source project\nand your users wouldn’t be the wiser. Since Parse is a service that needs to connect to a hosted server everyone\nwho used parse (myself included) need to develop a rather complex strategy of moving their hosted data (which is\nlive) while moving their users some of which might still have the old version that use parse on their devices…\nWhen you are looking at PaaS services you need to always evaluate the case of the PaaS closing down (this\nis true for IaaS as well but to a lesser degree), in that sense Parse is quite problematic since its effectively\nexposed to user installs. Codename One is far safer since the built app doesn’t really need Codename One anymore…\nAs I mentioned above before taking a long detour, I have a personal app that relies on Parse so I will need to port\nit to a different infrastructure. Most of the code there is already well abstracted but I will need to find a way\nto migrate the data and also pick a host for the data. I will try to publish the process in a way that helps other\nparse4cn1 users with the migration.\nSlowing Down New Feature Development We have set an ambitious goal of posting less news for the month of February and probably March too.\nAs developers we always want to build a shiny new thing and satisfying a feature request from a user is often\nrewarding and cool. However, this means we don’t spend the time writing documentation, generating tutorials\nor working on things such as performance, the new windows phone port, fixing bugs etc.\nNone of those things are really news worthy, so spending the time just writing a blog post about better\nJavaDocs/samples for a particular package is probably not very helpful. But this is crucial, we need stability\nand refined docs in order to communicate better even with our top developers. As we work on the docs we\nsee exactly what people have been complaining about. We have a lot of documentation but it is quite bare\nand isn’t at the level it should be.\nThis is a big task and you can already see a lot of the results in the first two chapters of the developer guide and\nwithin the javadocs.\nNew Features/Enhancements In direct contrast to the statement above, some features did get thru despite our best efforts…\nWe added getActualComponent()\nto ActionEvent,\nthis allows us to handle events better for lead components such\nas MultiButton.\nFinally we added terse\nencloseIn\nmethods to the\nTableLayout\nclass. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — February 2, 2016 at 8:13 am (permalink) Chidiebere Okwudire says:\nWith regard to alternatives to Parse, I just came across this github repo: https://github.com/relatedc…\nJérémy MARQUER — February 2, 2016 at 8:42 am (permalink) Jérémy MARQUER says:\nI’m pretty agree with the \u0026ldquo;Slowing Down New Feature Development\u0026rdquo; paragraph, but I find it unfortunate that you will post less news … It allows us (devs) to stay in touch with your development !\nShai Almog — February 3, 2016 at 3:29 am (permalink) Shai Almog says:\nThere is also this: http://www.slant.co/topics/…\nWhich is more concise and to the point. That list is a bit too much of everything and hard to read.\nBTW slant has a Codename One entry that could probably use some love.\nShai Almog — February 3, 2016 at 3:32 am (permalink) Shai Almog says:\nThanks. We’ll post news as it happens and we might even keep the bi-weekly posts.\nHowever, if you look at the past few months we introduced a few new features every week. This is probably not something that will recur. We do intend to keep you up to date about development but if there isn’t any development (just docs, debugging and maintenance) then we might skip a post or write an opinion piece instead.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/parse-docs-updates/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/parse-docs-updates/parse.com-post-header.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eFacebook recently announced the closing of parse.com which is disappointing but not totally surprising. Everyone\u003cbr\u003e\nknows a project from a large tech company can just shutdown in a blink of an eye leaving millions of users/developers\u003cbr\u003e\nin limbo. In that sense one of the questions that gets under my skin is what happens if Codename One calls it\u003cbr\u003e\nquits…\u003cbr\u003e\nYou’d be better off than anyone who used parse and its far less likely to happen. Codename One is \u0026ldquo;what we do\u0026rdquo;\u003cbr\u003e\nand have been doing for the past 4 years. More importantly, unlike Parse you could just use the open source project\u003cbr\u003e\nand your users wouldn’t be the wiser. Since Parse is a service that needs to connect to a hosted server everyone\u003cbr\u003e\nwho used parse (myself included) need to develop a rather complex strategy of moving their hosted data (which is\u003cbr\u003e\nlive) while moving their users some of which might still have the old version that use parse on their devices…\u003c/p\u003e","title":"Parse, Docs \u0026 Updates"},{"content":"Codename One 3.3 Release Notes Home 3.3 Release Notes Summary Version 3.3 starts a trend of refinement that we hope to stretch into version 3.4. We modernized a lot of details and continued trends from 3.2 such as performance, background process support, terse syntax etc.\nHighlights - Click For Details Faster rendering of backgrounds \u0026amp; Labels\nUp until now the logic for rendering the background of the component resided entirely within Component.java \u0026amp; DefaultLookAndFeel.java.\nThis allowed for a simple rendering logic that is implemented in a single place, however it didn\u0026rsquo;t allow us to deeply optimize some operations in a platform specific way. We moved the rendering into CodenameOneImplementation.java which allowed us to override the logic both on Android \u0026amp; iOS to deliver native grade performance on any device.\nOn iOS this has been a strait forward change where most of the low level logic is now written using very efficient C code. On Android the pipeline complexity is far greater, but thanks to this approach we were able to reuse many system resources and reduce JANK significantly in applications. This work is still ongoing but the bit effort has been implemented.\nThis is probably the biggest piece of multiple changes that went into this release including fast tiling support, better font/string texture caching, Container API optimizations etc.\nRead more about this work in this blog post.\nAnimation Manager, Title Animations \u0026amp; Style Animations\nWe rewrote the animation logic in Codename One for 3.3. This broke some backwards compatibility but this was for a good cause as we now have a central class that manages all animation events going forward. This means that you should no longer get odd exceptions when using many animations in sequence.\nAs part of this enhancement we also added new animation types such as title scroll animation and the ability to animate a style object UIID.\nRead more about this work in this blog post.\n\u0026ldquo;Remastered\u0026rdquo; Documentation (ongoing)\nWe are redoing a lot of the Codename One documentation from scratch with Codename One 3.3. This is ongoing and we barely just started but the new documentation is far more readable, detailed and clear. Moving forward we are confident that our developer guide, JavaDocs \u0026amp; videos will be in a league of their own!\nRead more about this work in this blog post.\nMaterial Design Icons\nFontImage has been around for a while but up until now we didn\u0026rsquo;t use it to its full extent. It required getting an icon font, configuring it and we just skipped it for some cases.\nWith 3.3 we integrated the material design icon font which makes adding flat icons to your application remarkably simple!\nRead more about this work in this blog post.\nMedia Playback \u0026amp; Geo Fencing in the Background\nWe continued the background process trend with 3.3 as we enabled both geofencing (to track device location in the background) and media playback in the background.\nRead more about this work in this blog post.\nPhoneGap/Cordova Compatibility\nCodename One always supported embedding HTML \u0026amp; JavaScript but it didn\u0026rsquo;t support embedding things such as the Cordova/PhoneGap API\u0026rsquo;s.\nWith the new open source project we announced we can now convert many Cordova/PhoneGap apps to Codename One apps and deliver quite a few compelling advantages.\nRead more about this work in this blog post.\nNew hello world project \u0026amp; icon\nA major focus of this release was making Codename One useful and attractive right out of the box. As part of that work we replaced the default icon, redid the hello world app to a more impressive (yet simple) demo and updated the default fonts.\nRead more about this work in this blog post.\nNew Simplified Native Fonts\nFonts were a difficult subject prior to 3.3. You could either use the portable but ugly system fonts, or go with the gorgeous but flaky TTF fonts. Both don\u0026rsquo;t make sense when Android ships with the great Roboto font and iOS ships with the gorgeous Helvetica Neue font.\nWe now have support for a new font notation with the native: prefix. This notation (supported by the Designer), allows us to leverage the existing native fonts of the device which look both native and gorgeous.\nRead more about this work in this blog post.\nTerse syntax enhancements\nIn 3.2 we started moving towards terse syntax for container hierarchy construction and with 3.3 we brought that to fruition. We added methods such as an add method that accepts an image. We added factory encloseIn methods to almost all of the layout managers, we added form constructors that accept layout managers and much more!\nRead more about this work in this blog post.\nParparVM Performance \u0026amp; Open Source\nOur iOS VM has been open source from the start but we didn\u0026rsquo;t encourage its usage outside of Codename One. This changed with 3.3 and we are actively promoting the ParparVM OpenSource project.\nUnrelated to that we made a lot of performance improvements to the core VM translation logic, it should be very competitive in terms of generated code to pretty much everything else on the market. Especially with API calls as our entire API is hand-coded and highly optimized.\nRead more about this work in this blog post.\nProperties file format support\nWe didn\u0026rsquo;t have support for Java venerable Properties file format before 3.3. Surprisingly developers didn\u0026rsquo;t really complain about that ommission as we support XML, CSV \u0026amp; JSON. Now we can add Properties to that list!\nRead more about this work in this blog post.\nEnding Support for the codescan API\n3.3 will be the last release that includes an implementation of the codescan API for QR code/barcode reading. We will remove this API completely and we ask users to migrate their code to use the new codescan cn1lib. When we initially introduced this API we didn\u0026rsquo;t have support for cn1libs and integrated this into the core directly.\nRead more about this work in this blog post.\nDetails Fixed bug in Javascript bridge that seemed to affect Android only. This bug would sometimes cause get() to return null for a Javascript expression that should be non-null.\nFix for #1645 when a style was changed on the EDT the currently queued async paint got changed as well\nUpdated the usage of the @inheritDoc javadoc tag which was misused thru the entire codebase\nFix for NPE when initializing the UI too soon Fix for NPE when initializing the UI too soon\nAdded JavaDocs and code samples to Dialog Added JavaDocs and code samples to Dialog\nMinimised the overhead of drawString in Android in a similar way to the iOS port by drawing on a bitmap within the EDT instead of on the Android thread.\nFixed infinite progress javadocs\nFixed bug with OnOff switch that printed the \u0026lsquo;on-off\u0026rsquo; state of the switch as text even if the flag was set to disable this.\nAdded ability to programmatically set the on, off, and mask images for the OnOff switch to allow for greater \u0026lsquo;per-instance\u0026rsquo; customization of an off switch.\nFixed transform issue on iOS mutable images reported at http://stackoverflow.com/q/34770700/2935174\nAdded easy ability to toggle on/off the new paint modes for Android\nInitial work on new graphics optimization that caches paint data\nMerge pull request #1643 from @McSym28 Socket.java. isSupported() should be static\nMerge pull request #1637 from @ddyer0 - remember the requested size for derived fonts\nFixed issue with text fields intermittently showing the text from the previous text field when clicking \u0026lsquo;Next\u0026rsquo; in async edit mode on iOS.\nMerge pull request #1636 from @ddyer0 - Fix an additional error loop in the VM socket implementation\nMinor performance improvement for async paint\nWorkaround for usage of gradients in designer where developers set the same color on a linear gradient to get a solid color\nFix for URLImage to throw exceptions sooner: http://stackoverflow.com/questions/34713004/an-exception-occurred-during-transition-paint\nAdded support for Picker preferredPopupWidth and preferredPopupHeight that can be used on platforms like iPad to decide how big the picker popup should be. Currently only implemented for iPad, and not relevant to iPhone.\nMerge pull request #1633 from @ddyer0 - fix a fencepost error in flowlayout\nMerge pull request #1633 from @ddyer0 - when readFromStream or writeToStream throw an IOError, mark the stream as no longer connected.\nMerge pull request #1633 from @ddyer0 - Added event type information to ActionEvent\nRemoved vestigal keyboard support sections as they can\u0026rsquo;t effectively be used anyways. Keyboard changes ended up being too far reaching for this simple flag to be sufficient for reverting to old handling. The new handling appears to be working for all use-cases anyways.\nAdded 2D transform support for mutable images on iOS. This effectively fixes issues with being able to share charts that are generated as images #1629\nAdded new UITimer constructor for further simplicity\nReplaced array.length calls inside for loops with local \u0026rsquo;length\u0026rsquo; variables\nFixed issue with transforms on mutable images in JavaSE port that would cause Graphics.getTransform() to always return the identity transform\nAdded support for drawing shapes on mutable images in iOS #1629\nFixed async editing support on Android when TextureView is used.\nAdded addComponentToSideMenu() to Toolbar this will allow devs to customize the sidePanel even for permanent side menu\nAdded ability to center the title in the Toolbar Added ability to center the title in the Toolbar\nFixed cancelLocalNotification to only delete the notification whose deletion was requested\nFixed regression in left aligned labels http://stackoverflow.com/questions/34565387/button-settextpositionlabel-left-render-wrong/34581225\nFixed remove command from title\nAdded ScaleImageLabel to simplify the process of adding a label that will scale correctly\nAdded AssignableExpression to ParparVM implementation. This will allow the translator to work with instructions in a more generic way when determining if an instruction can be reduced to a single expression that can be assigned to a variable or passed as a parameter\nChanged ParparVM primitive local variables to use C locals instead of storing them in the stack. This should bring performance improvements on two fronts: 1. STORE operations now map to a single assignment instead of two, since we don\u0026rsquo;t have to assign the variable type. 2. LLVM should be able to perform better optimization surrounding C locals.\nFix for launching the android sms activity\nPull request from @ddyer0 Fix for two problems with Sockets; data corruption and infinite error loop when input socket is closed.\nFix for #1623 tickering should cycle\nRefactored ParparVM\u0026rsquo;s custom Invoke and Jump optimizations into separate Instruction classes so that there is no confusion on how the Jump and Invoke instructions interact with the stack.\nAdded getStackOutputTypes() and getStackInputTypes() methods to Instruction in ParparVM so that optimizers can inspect instructions to see how they affect the stack. This will eventually allow for better reduction of instructions during the optimization phases.\nImproved CustomInvoke optimizations in ParparVM to cover many more cases that were missed before. This should further reduce redundant stack operations surrounding qualifying method invocations.\nAdded small optimization for binary integer arithmetic ops in ParparVM to directly assign result to local variable instead of first pushing it to the stack, then popping it to a local\nImproved the performance monitor to show UIID\u0026rsquo;s\nFix for some edge cases of component animation: https://groups.google.com/d/msgid/codenameone-discussions/fdd7ce70-d8ac-418b-96e0-0cd9ca529cb1%40googlegroups.com\nFixed issue with android async keyboard still showing on form change\nAdded the missing overflow icon\nFixed the decay motion to stop if last 4 returned animation values are the same\nFixed potential exception in animation layout transition that might collide with a remove operation\nDeprecated the com.codename1.codescan package. Going forward developers are encouraged to use the cn1-codescan cn1lib instead. https://github.com/codenameone/cn1-codescan/\nNew ability to force popup dialog in a specific direction\nFlipped the default for \u0026ldquo;ends with 3 points\u0026rdquo; to be false as this slows down performance slightly\nFixed special case that caused scroll to 0,0 when first field of form requests focus whether or not it is already visible. This improves usability of the MaterialLogin demo.\nFixed problem with rendering FontImage, IndexedImage \u0026amp; RGBImage\nCaching derived font instances which can significantly boost performance by allowing the native side of the fence to cache additional data on the font object\nFixed issue with async editing changes causing text field to close and reopen sometimes when switching to a different field\nFixed masked icons to render correctly in the new pipeline\nFixed the android get contacts to ignore case upon returning contacts\nAdded a picture to some of the Simulator contacts\nImplemented component drawing for labels and buttons in the native async layer\nNative implementation of label and background drawing to squeeze every ounce of performance\nMajor refactoring of the UI with the goal of improving on device performance for iOS/Android by moving frequently used code into the IMPL layer and allowing us to optimize it\nAdded support for Android async editing\nImproved efficiency of Container.contains() for containers with many children\nAdjusted the decay scroll parameters based on comparisons with native iOS app scrolling\nAdded additional checks for peer components before firing the onParentPositionChange event. This dramatically improves smoothness of drag scrolling\nPerformance optimization for scrolling a large set of elements when we have no peers\nChanged default scroll motion to use exponential decay instead of friction to simulate more closely native behavior. You can revert to the previous friction style of scrolling by setting the theme constant \u0026lsquo;ScrollMotion\u0026rsquo; to \u0026lsquo;FRICTION\u0026rsquo;. You can tune the decay parameter \u0026lsquo;DecayMotionScaleFactorInt\u0026rsquo; to adjust how sensitive the scrolling is.\nRemoved excessive pointer events from event dispatch to prevent slowness during dragging\nOptimization for stringWidth that should avoid calls to that relatively slow API by caching the value within labels\nAdded a binary search for the \u0026lsquo;viewable\u0026rsquo; children of a container that can be used to make it easier to only paint visible children for large containers\nRemoved redundant opengl calls to try to make painting more efficient\nFixed contact getDisplayName() to never return null\nRemoved a rectangle allocation that caused a GC in the EDT paint cycle. This fixes some jitter that occurs while scrolling\nFixed the animation manager scrolling behavior so it won\u0026rsquo;t misbehave when pulling from the top\nMade style animation work as expected for multiple elaborate cases\nImproved add/remove component to act as if the component was already added/removed and avoid some exceptions in cases that would be serialized\nAdded ability to detect an empty border\nFixed regression with ComponentGroup due to changing method signature\nBetter error handling in the JavaSEPort\nNew title animations and style animations API\u0026rsquo;s\nAdditional improvements for side menu bar preventing potential issue with animations\nFix for potential exception if an animation is running while changing the Toolbar\nFixed the animations and add/remove operations so they won\u0026rsquo;t collide. If an animation is in progress add/remove will get queued until after the animation is performed\nNew animation framework that accepts all animation requests globally and processes them\nNew methods for Integer \u0026amp; Character classes\nAdded getTitleComponent to the Toolbar\nFixed regression in ios keyboard that caused it to not respect the ios.keyboardOpen build hint. Now it gives multiple levels of control over whether a field uses async editing or legacy editing\nFixed getPrimaryPhoneNumber to return a number if a number exists\nFixed issue with background location monitoring on iOS 9\nFixed textarea resizing to work properly on iOS 7 and below\nFixed edge case of text area being edited in legacy mode when part of the text area is covered by the keyboard. Now the native editing component is sized to only occupy the space above the keyboard so that scrolling happens more smoothly as typing, and the textview will auto scroll as the cursor moves in and out of view\nFix so that legacy keyboard doesn\u0026rsquo;t push the selected text area up any higher than the top of the text area\nFixed issue with keyboard upside down multiplier on iOS 7\nChanges to keyboard on iOS to deal with quirks on iOS 5. Also modified some of the orientation detection handling that didn\u0026rsquo;t seem to be working correctly on iOS 5.x\nAdded ability to have more than one layered pane\nWorkaround for regression in checkbox/combobox that broke their theme styles on the unselected state due to loading of theme beforehand\nAdded support for tuning the speed of the infinite progress\nFixed ConnectionRequest issue with setReadResponseForErrors is true\nAdded a static factory method to UITimer\nMade building Codename One easier for 3rd parties with some build.xml teaks\nAdded ability to disable the automatic tab UIID switching\nFixed NPE in validator interaction dialog on scroll change\nFixed deadlock when toggling between fields in legacy mode on iOS. Behaviour was seen only on iOS 7\nFixed issue with iOS isTextEditing not correctly reporting because it deferred to the superclass isTextEditing methods. This resulted, occasionally, in text fields not being rendered properly when in async edit mode\nFixed issue with keyboard opening, then closing, then opening again the first time a field is edited with async editing\nFixed new fonts to respect italic/bold setting on Android\nFixed text field editing with form bottom padding fields\nAdded the onShowComplete callback when a show() is called on a Form which is the current Form\nFixes in ParparVM encoding for cases where UTF characters might reside on the edge between bytes Fix for encoding issues triggered by partial reading of the bytes\nReworked text input to reduce the cyclomatic complexity. Working well on iOS 9 with async, legacy, and form bottom padding test cases on iPhone 4S\nAdded return statement to prevent calling editString twice simultaneously\nAdded DeviceName property and added implementation to the stopTextEditing method\nAdded optimization to reduce ParparVM stack operations involved in invoking methods that take only constants and local variables as parameters\nAdded explicit hook in keyboardWillShow to hide the picker, if it is showing\nAdded textposition support to title command\nAdded ability to make rows in the MultiButton stick together\nOptimized stack operations in ParparVM surrounding binary integer operations\nAdded some optimizations to reduce stack operations surrounding some integer comparisons in ParparVM\nFixed issues with scrolling fields into view on iOS when using 3rd party keyboard\nFairly major changes to text editing on iOS to fix some bugs that appeared when using the SwiftKey keyboard Since swiftkey will call the keyboardShown event multiple times while it is showing, with different keyboard sizes reported, we needed to handle these events more incrementally\nFixed issue with not scrolling to focused text field on iOS when VKBAlwaysOpen is set to YES\nAdded support for opacity in resource files\nAdded support for opacity in FontImage\nAdded simpler methods to edit/stop editing and track editing state for a text component\nAdded a builtin ability to launch the text area editing when a form is shown which simplifies some common boilerplate code that is often implemented incorrectly\nAdded a builtin ability to launch the text area editing when a form is shown which simplifies some common boilerplate code that is often implemented incorrectly\nImplemented RFE #1510 \u0026ldquo;simplifying error message handling\u0026rdquo;\nAdded north, south, east and west methods to match the center method in the BorderLayout\nMade the parent scrollable public, this is important for some generic code that resides outside the package specifically the validation manager\nFloatingHint a new type of textfield/label wrapper that allows the hint to migrate to a label on top\nFixed multiple issues in the popup positioning and arrow functionality\nMinor configuration fine tuneing for the progress indicator\nFix for uncover transition\nMade iOS simulators use Helvetica Neue on Macs\nAdded constructSideNavigationComponent to Toolbar to allow overriding the panel\nFix for issue with native font loading using the new native: syntax\nAdded missing theme constants for checkboxes Added missing theme constants for checkboxes\nFix for RFE #1609 added support for the assert keyword\nUpdated the size of the InfiniteProgress and made it spin faster\nFixed pull to refresh to show the infinite progress\nFixed issue with local sending a local notification causing push to be registered\nMoved createBackgroundMedia to the CodenameOneImplementation\nRemoved some iOS 6 dependencies for compatibility with older versions\nNew support for material design icon fonts\nAdded background media playback to android and JavaSE port\nFixed issue with network thread getting deadlocked in some cases when a setDisposeOnCompletion is set\nFixed issue with infinite progress dialog not showing up if an existing progress dialog is opened\nFixed issue with multiple concurrent infinite progress dialogs interfering with each other\nFixed getAllContacts(\u0026hellip;) to return the contacts sorted by name\nSupport for the new hello world project look Support for the new hello world project look\nFixed the fonts in the top 2 themes\nFixed issue with iOS apps still being in \u0026lsquo;minimized\u0026rsquo; state during the start() method\nFixed issue with string picker showing up underneath keyboard on iOS. Now keyboard will auto fold when string picker is shown\nMerge pull request #1608 from @Pmovil Fixed multipart utf8 string (fails on android)\nAdded support for onCompletionCallback for video components in iOS. Related to #1595\nSome improvements to the default demo in the designer\nAdded isNativeFont supported and new flow layout terse factory methods\nAdded ability to detect running on simulator which is useful for crash reporting\nSimplified code that allows binding standard boilerplate crash reporting logic\nShorthand terse syntax for layered layout\nFixed regression with testflight builds\nAdded support for native OS fonts that are builtin to iOS/Android with multiple weights. This is mapped to the simulator on Windows/Linux as Roboto due to copyright issues with Helvetica.\nFixed for exception in table layout\nFixed issue that caused a revalidate to occur off the EDT in iOS when the keyboard is about to be shown. This may fix numerous issues. But, at least seems to fix an NPE from #1601\nFixed issue where the first contact is always blank on iOS. Changed contacts to come out sorted by default #1598\nChanged Contact.getDisplayName() to return an alternate value like the phone, email, name if the contact has no display name #1598\nFixed iOS port not respecting setChunkedStreamingMode. iOS8 had been using chunked streaming by default for multipart requests. Now it will only use chunked streaming when setChunkedStreamingMode() is called with a non-negative integer argument\nFixed regression in Javascript bridge that broke execution on Android\nFix for #1602 - Menu missing with Android 6 Marshmallow\nAdded ability to hide/show components without removing them (setHidden)\nFixed data dir location to .cn1 inside the project directory. This directory is used by the simulator for localStorage\nAdded async methods to JavascriptContext for better performance when synchronous calls are not needed. Also fixed Javascript bridge callbacks in simulator\nAdded improved debugging in the Simulator\u0026rsquo;s BrowserComponent\nFixed iOS local notifications. Turned out they had been commented out by a merge right after they were implemented\nAdded some error logging when mkdir() fails\nFixed simulator BrowserComponent support for localStorage\nFixed bug in extracting html hierarchies\nFixed issue with some fonts being cut off at the bottom in iOS\nFixed stream closed error in video component on iOS #1595\nRemoved unnecessary retain in creating video component that could cause memory leak\nAdded terse API to download/parse JSON synchronously useful for webservices\nAdded tearse add() methods to container that accept images to make the process of adding even simpler\nCreated shorter default creation method to URLImage\nAdded factory methods based on encloseWith to BorderLayout and BoxLayout to simplify/shorten the resulting code\nAdded ability to construct a form with a layout manager\nSlider is now recognized by the generic list cell renderer and can be used in a renderer component\nWorkaround for EDT performance issues while dragging\nAdded the ability to extend the Toolbar and modify the side panel\nAdded support for background location services and geo fencing on iOS\nAdded support for Properties file format\nExposed a public constructor for Label which accepts the text and a UIID, this makes terse code simpler\nMade table layout constraint construction more terse for easier layout of tables\nAdded geofence and background location tracking\n","permalink":"https://www.codenameone.com/codename-one-3-3-release-notes/","summary":"\u003ch1 id=\"codename-one-33-release-notes\"\u003eCodename One 3.3 Release Notes\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e3.3 Release Notes\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"summary\"\u003eSummary\u003c/h3\u003e\n\u003cp\u003eVersion 3.3 starts a trend of refinement that we hope to stretch into version 3.4. We modernized a lot of details and continued trends from 3.2 such as performance, background process support, terse syntax etc.\u003c/p\u003e\n\u003ch3 id=\"highlights---click-for-details\"\u003eHighlights - Click For Details\u003c/h3\u003e\n\u003cp\u003eFaster rendering of backgrounds \u0026amp; Labels\u003c/p\u003e\n\u003cp\u003eUp until now the logic for rendering the background of the component resided entirely within Component.java \u0026amp; DefaultLookAndFeel.java.\u003cbr\u003e\nThis allowed for a simple rendering logic that is implemented in a single place, however it didn\u0026rsquo;t allow us to deeply optimize some operations in a platform specific way. We moved the rendering into CodenameOneImplementation.java which allowed us to override the logic both on Android \u0026amp; iOS to deliver native grade performance on any device.\u003cbr\u003e\nOn iOS this has been a strait forward change where most of the low level logic is now written using very efficient C code. On Android the pipeline complexity is far greater, but thanks to this approach we were able to reuse many system resources and reduce JANK significantly in applications. This work is still ongoing but the bit effort has been implemented.\u003cbr\u003e\nThis is probably the biggest piece of multiple changes that went into this release including fast tiling support, better font/string texture caching, Container API optimizations etc.\u003cbr\u003e\nRead more about this work in \u003ca href=\"/blog/code-freeze-for-3.3-performance.html\"\u003ethis blog post\u003c/a\u003e.\u003c/p\u003e","title":"Codename One 3.3 Release Notes"},{"content":"\nWe are thrilled to announce the immediate availability of Codename One 3.3!\nVersion 3.3 was tumultuous, we made a lot of earth shattering changes to performance, animations, fonts\nand many other things. As a result we have a ground-breaking release that requires\na step back.\nWith 3.4 we want to tone down on the \u0026ldquo;big ticket changes\u0026rdquo; and work heavily on product refinement. We are already\nhard at work updating our docs and refining our general process..\nIn 3.3 we focused a lot on the open source aspect of Codename One which is something we neglected\nto some extent in the past. We intend to keep pushing towards more transparency and community involvement\nas the project grows.\nCodename One 3.4 is currently scheduled for May 3rd 2016. Its chief goals are: Performance, Platform fidelity,\nDocumentation \u0026amp; ease of use.\nHighlights Of The Release – Click For Details ____Faster rendering of backgrounds \u0026amp; Labels\nUp until now the logic for rendering the background of the component\nresided entirely within Component.java \u0026amp; DefaultLookAndFeel.java.\nThis allowed for a simple rendering logic that is implemented in a single place, however it didn’t allow us\nto deeply optimize some operations in a platform specific way. We moved the rendering into\nCodenameOneImplementation.java which allowed us to override the logic both on Android \u0026amp; iOS\nto deliver native grade performance on any device.\nOn iOS this has been a strait forward change where most of the low level logic is now written using\nvery efficient C code. On Android the pipeline complexity is far greater, but thanks to this approach\nwe were able to reuse many system resources and reduce JANK significantly in applications. This\nwork is still ongoing but the bit effort has been implemented.\nThis is probably the biggest piece of multiple changes that went into this release including fast tiling\nsupport, better font/string texture caching, Container API optimizations etc.\nRead more about this work in this blog post.\n____Animation Manager, Title Animations \u0026amp; Style Animations\nWe rewrote the animation logic in Codename One for 3.3.\nThis broke some backwards compatibility but this was for a good cause as we now have a central class\nthat manages all animation events going forward. This means that you should no longer get odd\nexceptions when using many animations in sequence.\nAs part of this enhancement we also added new animation types such as title scroll animation and the\nability to animate a style object UIID.\nRead more about this work in this blog post.\n____\u0026ldquo;Remastered\u0026rdquo; Documentation (ongoing)\nWe are redoing a lot of the Codename One documentation from scratch with\nCodename One 3.3. This is ongoing and we barely just started but the new documentation is far more readable,\ndetailed and clear. Moving forward we are confident that our developer guide, JavaDocs \u0026amp; videos will be in a\nleague of their own!\nRead more about this work in this blog post.\n____Material Design Icons\nFontImage has been around for a while but up until now\nwe didn’t use it to its full extent. It required getting an icon font, configuring it and we just skipped it\nfor some cases.\nWith 3.3 we integrated the material design icon font which makes adding flat icons to your application\nremarkably simple!\nRead more about this work in this blog post.\n____Media Playback \u0026amp; Geo Fencing in the Background\nWe continued the background process trend with\n3.3 as we enabled both geofencing (to track device location in the background) and media\nplayback in the background.\nRead more about this work in this blog post.\n____PhoneGap/Cordova Compatibility\nCodename One always supported embedding\nHTML \u0026amp; JavaScript but it didn’t support embedding things such as the Cordova/PhoneGap API’s.\nWith the new open source project we announced we can now convert many Cordova/PhoneGap apps to\nCodename One apps and deliver quite a few compelling advantages.\nRead more about this work in this blog post.\n____New hello world project \u0026amp; icon\nA major focus of this release was making Codename One useful and\nattractive right out of the box. As part of that work we replaced the default icon, redid the hello world app to a\nmore impressive (yet simple) demo and updated the default fonts.\nRead more about this work in this blog post.\n____New Simplified Native Fonts\nFonts were a difficult subject prior to 3.3. You could either use the\nportable but ugly system fonts, or go with the gorgeous but flaky TTF fonts. Both don’t make sense when Android\nships with the great Roboto font and iOS ships with the gorgeous Helvetica Neue font.\nWe now have support for a new font notation with the native: prefix. This notation (supported by the Designer),\nallows us to leverage the existing native fonts of the device which look both native and gorgeous.\nRead more about this work in this blog post.\n____Terse syntax enhancements\nIn 3.2 we started moving towards terse syntax for container hierarchy\nconstruction and with 3.3 we brought that to fruition. We added methods such as an add method that accepts an\nimage. We added factory encloseIn methods to almost all of the layout managers, we added form constructors\nthat accept layout managers and much more!\nRead more about this work in this blog post.\n____ParparVM Performance \u0026amp; Open Source\nOur iOS VM has been open source from the start but we didn’t encourage its\nusage outside of Codename One. This changed with 3.3 and we are actively promoting the ParparVM OpenSource\nproject.\nUnrelated to that we made a lot of performance improvements to the core VM translation logic, it should be very\ncompetitive in terms of generated code to pretty much everything else on the market. Especially with API calls as\nour entire API is hand-coded and highly optimized.\nRead more about this work in this blog post.\n____Properties file format support\nWe didn’t have support for Java venerable Properties file format before\n3.3. Surprisingly developers didn’t really complain about that ommission as we support XML, CSV \u0026amp; JSON.\nNow we can add Properties to that list!\nRead more about this work in this blog post.\n____Ending Support for the codescan API\n3.3 will be the last release that includes an implementation of the codescan\nAPI for QR code/barcode reading. We will remove this API completely and we ask users to migrate their code to\nuse the new codescan cn1lib. When we initially\nintroduced this API we didn’t have support for cn1libs and integrated this into the core directly.\nRead more about this work in this blog post.\nYou can also read the far more detailed list of release notes here. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — January 27, 2016 at 11:50 am (permalink) Chidiebere Okwudire says:\nCheers guys! Well done!!\nSomething is obviously missing: An update on the new GUI builder which should have entered beta with release 3.3. What’s the status and why isn’t it mentioned in the feature list above?\nShai Almog — January 27, 2016 at 12:26 pm (permalink) Shai Almog says:\nThanks!\nWe thought about this quite a bit and chose not to emphasis that with this release even though we’ve done a lot of work on the GUI builder we still don’t feel its ready for beta. The UI/UX still isn’t perfect and the tutorials aren’t even remotely close to done.\nWe intended to do the finishing touches during the late part of 3.3’s release cycle but then we got delayed with regressions/fixes and are now delayed due to the documentation overhaul work. So we just didn’t get around to working on the GUI builder full time.\nI think that once we change the documentation/videos to use the new GUI builder people will start using it and will start filing issues. This will bring it to beta-status thru inertia during the 3.3 lifespan.\nChidiebere Okwudire — January 27, 2016 at 12:36 pm (permalink) Chidiebere Okwudire says:\nClear and probably a good choice.\nI tried creating a new project with the new GUI builder last week and after a few crashes and unclarity of how to do simple things that I can easily do with the old builder (e.g. setting components to parts of a border layout), I quit and reverted back to the old GUI builder. I’ll stick with that till further notice. I also saw a button for converting an existing project to a new GUI builder project so I guess when it’s ready, I’ll be able to migrate away from the huge state machine class.\nShai Almog — January 27, 2016 at 12:48 pm (permalink) Shai Almog says:\nYes the migration wizard is already there.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-3-3-now-live/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-3-3-now-live/codenameone3.3-release.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are thrilled to announce the immediate availability of Codename One 3.3!\u003cbr\u003e\nVersion 3.3 was tumultuous, we made a lot of earth shattering changes to performance, animations, fonts\u003cbr\u003e\nand many other things. As a result we have a ground-breaking release that requires\u003cbr\u003e\na step back.\u003cbr\u003e\nWith 3.4 we want to tone down on the \u0026ldquo;big ticket changes\u0026rdquo; and work heavily on product refinement. We are already\u003cbr\u003e\nhard at work updating our docs and refining our general process..\u003cbr\u003e\nIn 3.3 we focused a lot on the open source aspect of Codename One which is something we neglected\u003cbr\u003e\nto some extent in the past. We intend to keep pushing towards more transparency and community involvement\u003cbr\u003e\nas the project grows.\u003cbr\u003e\nCodename One 3.4 is currently scheduled for May 3rd 2016. Its chief goals are: Performance, Platform fidelity,\u003cbr\u003e\nDocumentation \u0026amp; ease of use.\u003c/p\u003e","title":"Codename One 3.3 Now Live"},{"content":"\nWe’ve been working feverishly to get Codename One 3.3 out of the door next week. Tomorrow morning we\nwill finally have the codefreeze branch for 3.3 and we’ll be able to focus on getting the docs/release in order.\nThe release should be on the 27th of the month and we should ideally get the plugins out of the door within the\nnext couple of days.\nPerformance Update We’ve worked a lot on getting Android to perform nicely in the newer phones. When we launched the Android\ngraphics architecture was quite different than it is today so we had to make quite a few changes over the years.\nUnfortunately, because of the ridiculously wide variety of devices something that performs well (or even functions)\nacross devices is just not technically feasible on Android.\nWe made a lot of improvements but they carry a heavy risk and we won’t turn them on by default on 3.3, we did\nhowever add an option to try them dynamically. You can just invoke the call:\nDisplay.getInstance().setProperty(\u0026quot;platformHint.legacyPaint\u0026quot;, \u0026quot;false\u0026quot;); This will toggle on the new Android optimizations (but have no effect elsewhere), you can flip the flag back and\nforth dynamically to see the difference. Although notice that you should probably recreate the form when doing this\nas some content might end up blank as a result.\nNotice that while this improves our Android performance significantly on newish devices (ironically we perform\nwell on older devices and very new devices), this isn’t the \u0026ldquo;end all\u0026rdquo; for performance tuning on Android. We\nare still working on improving performance further both on Android \u0026amp; iOS. This will also include revisited\ntools \u0026amp; guides for performance optimization/tuning of your apps.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/code-freeze-for-3-3-performance/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/code-freeze-for-3-3-performance/3.3-coming-soon.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve been working feverishly to get Codename One 3.3 out of the door next week. Tomorrow morning we\u003cbr\u003e\nwill finally have the codefreeze branch for 3.3 and we’ll be able to focus on getting the docs/release in order.\u003cbr\u003e\nThe release should be on the 27th of the month and we should ideally get the plugins out of the door within the\u003cbr\u003e\nnext couple of days.\u003c/p\u003e\n\u003ch4 id=\"performance-update\"\u003ePerformance Update\u003c/h4\u003e\n\u003cp\u003eWe’ve worked a lot on getting Android to perform nicely in the newer phones. When we launched the Android\u003cbr\u003e\ngraphics architecture was quite different than it is today so we had to make quite a few changes over the years.\u003cbr\u003e\nUnfortunately, because of the ridiculously wide variety of devices something that performs well (or even functions)\u003cbr\u003e\nacross devices is just not technically feasible on Android.\u003cbr\u003e\nWe made a lot of improvements but they carry a heavy risk and we won’t turn them on by default on 3.3, we did\u003cbr\u003e\nhowever add an option to try them dynamically. You can just invoke the call:\u003c/p\u003e","title":"Code Freeze for 3.3 \u0026 Performance"},{"content":"\nJavaDoc source code embeds suck!\nI love JavaDoc but it didn’t age well. When you work with other tools (e.g. in the Microsoft world) suddenly the\nembedded samples look amazing and \u0026ldquo;search\u0026rdquo; functionality is just built in!\nWhy can’t we have that?\nJDK 9 is introducing new support for search\nbut source embeds can be so much better and are a crucial learning tool…\nSince documentation and proper code samples are so crucial we decided to revisit our javadocs and start from\nthe ground up, to that point we created the new open source project:\nJavaDoc Source Embed.\nThe goal of this project is to allow using github \u0026ldquo;gist\u0026rdquo; in JavaDoc which allows you to create JavaDoc that looks\nlike this\ninstead of the normally anemic source embeds.\nIf you are unfamiliar with github gists its essentially\na code snippet hosting service that both formats the code nicely and allows you to easily maintain it thru\ngithub (fork, star, watch etc.).\nThe central hosting is the true \u0026ldquo;killer feature\u0026rdquo;, it allows you to embed the sample everywhere that’s applicable\ninstead of copying and pasting it. E.g. the LocationManager\nis a good place to hold the sample but so is the Geofence class.\nIn those cases we only had to copy this small snippet in the javadoc:\n\u0026lt;script src=\u0026quot;https://gist.github.com/codenameone/b0fa5280bde905a8f0cd.js\u0026quot;\u0026gt;\u0026lt;/script\u0026gt; The only two problems with gist are its lack of searchability and the fact that it won’t appear in IDE’s that don’t\nrender JavaScript. The JavaDoc Source Embed\nproject effectively solves that by automatically generating a \u0026ldquo;noscript\u0026rdquo; tag with the latest version of the gist\nso it appears properly everywhere it is referenced.\nWe’ll try to update our javadocs but would be happy for pull requests and issues pointing at missing samples\nand where they should be placed in the code.\nDeveloper Guide Wiki In other news we just finished the migration of the developer guide to the github wiki page and already it looks\nradically different. The approach of using githubs wiki pages has its drawbacks and asciidoc does have\nsome pain points but overall I think this is a good direction for an open project.\nIsmael Baum made a lot of wiki edits fixing many\ngrammatical and logical errors picking up so many mistakes in the process!\nBesides the many rewrites and fixes we made for the document we also authored a script that translates\nCodename One class names to links into the JavaDoc.\nSo now instead of just highlighting the mention of LocationManager you would see\nLocationManager\nwhich is far more useful. Notice that this shouldn’t affect things like code blocks only mentions of a\nspecific class. From this point on we’ll try to interconnect the documentation to produce a more coherent\nexperience with the docs.\nI’d open source the script we used for the links but its mostly a bunch of very specific sed\ncommands which probably won’t be useful for anyone. We won’t run it again since its a \u0026ldquo;one off\u0026rdquo; script,\nwe’ll just need to keep the linking going.\nFeedback Do you know of other tools we can use to improve the state of our documentation?\nWe are looking for several things that still seem to be hard with the current toolchain:\nBetter JavaDoc integrations – ability to embed it into the existing web design would be wonderful!\nCSS is a bit too limiting. Improving the look of the asciidoc PDF – Currently the PDF looks too academic in the opening page\nthere are some solutions for that but most seem hackish. Grammar \u0026amp; Style tools – There are some decent grammar checkers for word processors but\nwe couldn’t find anything that works with asciidoc. The same is missing for writing analysis tools that\ncan point out unclear writing. I saw that gitbooks has some interesting tools there but I’m unsure whether\nwe want to use it. Let us know if you are familiar with such tools or something else that we might not be aware of.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/javadoc-source-samples-that-dont-suck/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/javadoc-source-samples-that-dont-suck/with-javascipt-gist.png\"\u003e\u003c/p\u003e\n\u003cp\u003eJavaDoc source code embeds suck!\u003cbr\u003e\nI love JavaDoc but it didn’t age well. When you work with other tools (e.g. in the Microsoft world) suddenly the\u003cbr\u003e\nembedded samples look amazing and \u0026ldquo;search\u0026rdquo; functionality is just built in!\u003cbr\u003e\n\u003cstrong\u003eWhy can’t we have that?\u003c/strong\u003e\u003cbr\u003e\nJDK 9 is \u003ca href=\"http://mail.openjdk.java.net/pipermail/jdk9-dev/2016-January/003362.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eintroducing new support for search\u003c/a\u003e\u003cbr\u003e\nbut source embeds can be so much better and are a crucial learning tool…\u003c/p\u003e\n\u003cp\u003eSince documentation and proper code samples are so crucial we decided to revisit our javadocs and start from\u003cbr\u003e\nthe ground up, to that point we created the new open source project:\u003cbr\u003e\n\u003ca href=\"https://github.com/codenameone/JavaDocSourceEmbed\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eJavaDoc Source Embed\u003c/a\u003e.\u003c/p\u003e","title":"JavaDoc Source Samples That Don't Suck"},{"content":"\nFollowing with the feedback on the recent survey we spent a lot of time debating how we can improve the\ngeneral process of documentation and ideally have the community more involved. So one of the first things\nwe did is place our entire developer guide directly into the\nCodename One Wiki!\nThis allows any one of you without any special permissions (just a standard github account) to edit the wiki\ndirectly. No pull request or anything like that required. The syntax is based on asciidoc which is reasonably\nintuitive so if you see something wrong/missing etc. just edit it directly, we review all changes after the\nfact so if you get something wrong we will fix it!\nIf you want to monitor changes to the wiki and help us maintain it you can use the wiki RSS feed from github:\nhttps://github.com/codenameone/CodenameOne/wiki.atom. I also created an\nifttt recipe\nfor this but I’m not sure if it works well.\nWe’d also appreciate pull requests that improve our javadoc comments in the source so feel free to submit\nsuch changes as well if you see something that needs adding.\nParparVM Performance Another issue that was raised in the surveys was performance, this is an ongoing task and a lot of the regressions\nwe had in the past month are related to a heavy commitment we made to native grade performance. Steve\nrecently committed a lot of improvements to the architecture of ParparVM that should significantly boost\nthe performance of some simple calculations and arithmetics bringing them to the level of native C performance\nby eliminating stack operations and removing the locals overhead.\nActionEvent Type Information AWT/Swing created a lot of listener type interfaces and classes for practically every possible type of event in\nthe system. This made the code easy to understand but also made generic implementations harder and\nincreased the overall footprint of the JVM for things like AOT compilation.\nWith Codename One we went to the other extreme which is probably not ideal either (but somewhat hard\nto fix in retrospect) of using ActionListener/ActionEvent for everything.\nThis has advantages such as really simple and generic event binding, however it creats a situation where\nthe generic code to process an events can’t easily distinguish one type of event from another.\nDave Dyer contributed a\npull request\nthat added a new type attribute to action events together with a Type enum.\nYou can use this new capability with a line like this:\nActionEvent.Type t = ev.getEventType(); You can then use a switch case to handle various types of events or log them to the console for debugging.\nShape API’s And Transforms On Mutable Images Steve implemented the 2D shape API’s in Codename One quite a while back. One of the known problems was\nthe fact that some of these API’s weren’t implemented on mutable images in iOS.\nThe reasoning for that is that iOS has two very distinct and incompatible pipelines in Codename One. Rendering\nto the screen is done via OpenGL ES 2.0 and is very fast. Rendering to images is done via the iOS drawing API’s\nwhich are normally pretty slow but can be done on an offline surface.\nWith this you can now finally draw charts onto images, however some other effects such as perspective transform\nprobably won’t work on an image.\nSimpler Padding/Margin in Code Up until now if you wanted to change padding/margin you had to do something like this:\nstyle.setPadding(Component.TOP, padding); Getting the padding wasn’t much better:\nint paddingPixels = style.getPadding(Component.TOP); We now have two ways to do this that are simpler:\nstyle.setPaddingTop(padding); int paddingPixels = style.getPaddingTop(); This obviously applies to the sides/bottom as well.\nThe main motivation isn’t just the shorter amount of code and intuitive nature of the API. Its also slightly faster\nas some checks become unnecessary by the specific code.\nCentering the Toolbar We added to Toolbar the ability to center the title that was somewhat lost in the move between\nthe old title and the new Toolbar class. To the uninitiated it would seem that just styling the\n\u0026ldquo;Title\u0026rdquo; UIID to center should work. It seems to work on the surface but fails when we have uneven element widths\nto the right \u0026amp; left.\nE.g. a sidemenu icon on the left with nothing on the right.\nThis effectively allocates a space to the title that starts after the side menu and the centering operation is relative\nto that location not to absolute screen width. By doing it like this we layout everything to the center in the layout\nlevel which should produce the desired result. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — January 14, 2016 at 8:20 am (permalink) Chidiebere Okwudire says:\nHi,\nGood first step with the documentation in my opinion! I’m not sure though what will be more better – reviewing changes after the fact or managing changes via pull requests. Of course, that’s something that time will tell.\nOne thing that’s immediately obvious is the absence of navigation. Not such a big issue but can be better. You might also want to check out what the Parse guys do. Sometime last year, they also moved their docs to github [https://github.com/ParsePla…] but somehow, they are able to still render it with more appealing formatting on their website [https://parse.com/docs]. On the github README, they roughly explain how that is realize this using a backend parse app and a background job. This kind of solution (not necessarily using a Parse backend) could be cool for the CodenameOne docs as well.\nCheers\nShai Almog — January 14, 2016 at 8:35 am (permalink) Shai Almog says:\nWe already got a great set of edits there from https://github.com/Isborg who did an amazing job at fixing a lot of my mistakes! So I’m pretty happy.\nThis wasn’t clear in the article above but https://www.codenameone.com… and the generated PDF will still work exactly as before. The only difference is that we now generate them from the wiki sources. So the source in the wiki won’t necessarily be 100% correct since they didn’t go thru our validation but the manual should still work as expected. I explained our PDF generation workflow and placed the code back in the day within the jbake user group but it might warrant better docs especially with the work we’d like to do moving forward. I think we need to invest a lot in the look and feel of the developer guide/javadocs.\nI placed a right side navigation panel very similar to the existing manual which should be pretty intuitive too.\nChidiebere Okwudire — January 20, 2016 at 11:57 am (permalink) Chidiebere Okwudire says:\nThanks for the clarification. Cool that the pdf is generated from the wiki. By the way, the IFTTT recipe works 😉\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/wiki-parparvm-performance-actionevent-type/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/wiki-parparvm-performance-actionevent-type/parparvm-blog.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eFollowing with the feedback on the recent survey we spent a lot of time debating how we can improve the\u003cbr\u003e\ngeneral process of documentation and ideally have the community more involved. So one of the first things\u003cbr\u003e\nwe did is place our entire developer guide directly into the\u003cbr\u003e\n\u003ca href=\"https://github.com/codenameone/CodenameOne/wiki/Index\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCodename One Wiki\u003c/a\u003e!\u003cbr\u003e\nThis allows any one of you without any special permissions (just a standard github account) to edit the wiki\u003cbr\u003e\ndirectly. No pull request or anything like that required. The syntax is based on asciidoc which is reasonably\u003cbr\u003e\nintuitive so if you see something wrong/missing etc. just edit it directly, we review all changes after the\u003cbr\u003e\nfact so if you get something wrong we will fix it!\u003c/p\u003e","title":"Wiki, ParparVM Performance, ActionEvent Type \u0026 more"},{"content":"\nI deeply care about what we do at Codename One and writing a negative post even when the words aren’t mine\nis difficult. I think one of the most valuable thing about an open project is honesty and open communications even when\nthat’s unpleasant, without open criticism we can’t get better.\nChen recently sent out a request to fill out our survey via direct mail and responses came streaming in. Added\nto the guys who filled it out after our previous blog post we got a lot of additional valuable feedback.\nWe can’t satisfy everyone and we shouldn’t aim to, however developers who spent time answering our survey\nprobably like the basic concept of Codename One and should be happy. Most of them by a good margin (over 90%)\nare happy, but its only a good margin not a great margin and in this post I’d like to hash up the problems.\nMy goal here is to explain how we internalize your very valuable feedback and convert it into something we\ncan work with. I’d also like to explain why some things happen, e.g. what tradeoffs we took that lead us\nto this position. I’ll try to focus on proactive responses and reduce the \u0026ldquo;excuses\u0026rdquo; to a minimum but\nI do make some excuses for Codename One below since… well I’m biased.\nOne observation I had when reading the responses was that IntelliJ/IDEA developers were far more critical\nof Codename One than developers using other IDE’s. This makes a lot of sense as our current\nIntelliJ plugin isn’t as robust as the other plugins. This is something we really need to address moving forward.\nSurvey Question: What Do you like/dislike about Codename One? Stability and our fast update cycles are a problem as expressed in the comments below:\nI dislike the instability. It happened to me more than once that when I returned to my project after a pause of a\ncouple of months, my app -which previously worked fine- suddenly looks different and, worse, gives error\nmessages or even crashes. I get the impression that things are released too soon, before being properly\ntested…\nI like the simplicity and fast development cicle. I however stopped using it after my project simply stopped\nbuilding and gave no errors or any hint of what was wrong (I was experimenting with different technologies\nfor a project).\nGood online support; great performance on devices / I feel you go too fast sometimes, need to\nensure stability before releasing new version (regressions stop our development)\nWhen you release some changes and the plugin update it without ask to me. And suddenly my\napplication starts to present some bugs that didn’t exist before.\nWe just made 3 HUGE compatibility related changes\nwith our gradle migration, performance optimization \u0026amp; animation framework rewrite. This obviously impacted\nthe results but the feedback is indeed a valid one and this isn’t the first time this happens.\nWe have a standard reply for pro users: \u0026ldquo;use the versioned builds\u0026rdquo;. Unfortunately that reply\ndoesn’t work for basic/free users and even for pro users who might need the latest and greatest.\nAs a side note I’d like to mention that we see a very clear migration path of free/basic subscribers up to pro/enterprise\ntiers. So we care deeply about platform stability even for basic/free subscribers! You are (quite literally)\nthe Enterprise customers of tomorrow and we do care.\nAddressing stability is tough for a company of any size but its tougher for a small company like us especially\nwith the scale of the undertaking at hand. The mobile world is moving quickly and we need to move faster to\ncatch up, so how do we settle the conflict: move fast vs. break things?\nWe had heated debates about this internally several times including after reading these posts.\nI can’t say we have concensus, I can at least say we all agree that there is a problem that needs fixing.\nOne of the common suggestions we get when faced with this issue is that we need to provide an option to\nbuild against the last known stable version. Unfortunately, that won’t work because if we will offer such an option\nno one will use the latest and no one will report the issues as they happen. This will make bug fixing much harder\nas an issue will be reported after we already moved to a different task, so we will end up with a situation worse\nthan we have today as it would take us longer to fix issues.\nWe see the long term solution as a two pronged approach. We need better internal QA and a better process\nfor handling regressions. In retrospect we should have reverted some of the performance changes sooner\nas a temporary measure to get code working. We will try to be more vigilant with issues like this as we move\nforward. It was also a mistake to do this change during Christmas, we incorrectly assumed there would be\nless damage with people on vacation. The actual result was that the issue took longer to surface and when\nit did we were too deep in to revert properly.\nI’d like to further emphasize that we need your bug reports and communications in\nstackoverflow and the\nsupport forum as soon as you see a potential regression. If you see a\nsudden issue first check the\nblog, we try to communicate all major changes thru the blog. This can give you a\nsense of the areas we are working on\nand if one of those changes could have triggered a regression you are seeing.\nOut-dated tutorials or code examples.\nSome of the documentation is out of date, especially in regards to using it with Eclipse.\nIts painstaking going over everything. If you see something that’s out of date or plain wrong first\nwrite a comment there. Then file an issue in our github issue tracker so we can assign an action item to dealing\nwith that.\nDisliked lack of updated documentation/tutorials/support for CN1 workarounds for missing\nJava libraries\nLike: Java code / dislike: no medium and advanced tutorials/videos, layout not work on iphone.\nDocumentation should really be improved\nLag of clear examples on how to do things\nThe lack of information and tutorials\nwill be good to have an small code section to show the classes ussage.\nThe samples often do not use the \u0026ldquo;Visual\u0026rdquo; approach so a lot of time is spent translating the code.\nFor Example: The Validator-Component.\nDislike the learning curve.\nSome features are difficult to find documentation\nquality of documentation, details of docs\nWe had a sense that people weren’t using the developer guide as much as they are. With the results of this survey\nit dawned on us that this was a misconception. We need to work on the documentation\nmore thoroughly and keep changing it while working on Codename One itself rather than at the code freeze\nweek. However, the original chart we posted turned out to be based on a smaller sample than our final result,\nit seems the \u0026ldquo;How Do I\u0026rdquo; videos do occupy a large segment of the docs.\nKeeping the documentation in sync for something as big as Codename One is a big task and doing it in parallel to moving\neverything forward is even harder. However, building features without documenting them is probably useless as\nno one will use said features…\nSo we’ve decided to set documentation and reworking of the videos as one of our top short term priorities.\nWe need to re-think a lot of things in regards to documentation, e.g. should we move to a more open platform\nlike git with our docs?\nHow should samples integrate into the documentation?\nGenerally I think we need to improve the process to something that’s more open but still works into our\ngeneral workflow of building everything together. Ideally samples should integrate directly into git so you\nguys can contribute/use them right away.\nOne of our concerns here is tooling, right now we use asciidoc to generate the developer guide and this is\na bit problematic as we can’t seem to get the right look we had when we just used a word processor.\nIt also makes working with proofreaders much harder as they can’t read asciidoc and communicate with us\nvia the PDF file.\nIf you have experience with open source toolchains for documentation we’d appreciate some tips here…\nFor videos I don’t see a way of scaling this by much, I’ve improved my video generation process but its still\nfar behind the speed we would need to redo everything and update with new developments. Steve did some\ngreat videos but we have a lot of tasks and not enough time. The only solution here is for me to priorities videos\nover my other tasks which is something I will try to work on.\nDislike: performance on iOS and to some extent on WP\nDislike sluggish performance\nI think that if the apps have more performance it would be great!\nImprove performance in android.\nPerformance has shifted to our top priority just before the survey launched so this is quite important to us and\nI think that we were lax on performance for a bit too long.\nHaving said that, most of the performance problems we see every day have nothing to do with the performance\nimprovements we made and are a result of misuse of Codename One’s API’s and disregard of our guidelines\nwhich we documented poorly… (totally our fault).\nPart of the fix for performance should be improvement of tooling that would detect performance issues in the same\nway we detect EDT violations. We should also redo the documentation and videos on performance, this is obviously\nan important issue that needs attention probably more than any other issue.\nImprove performance and always introduce latest trending features in mobile development space (e.g. Google material design and 3D touch)\nWe have been slow with adopting some latest trends such as material design patterns and other capabilities.\nThese are things we are trying to do right now as we handle all of these other issues. Currently the material\ndesign level effects are on our top priority list.\n3d touch isn’t there yet, but we need to support that as well as pen input and various other capabilities. There\nare some complexities in doing that though, we’ll need to migrate to newer versions of xcode which might produce\nbuild regressions for some users and we are procrastinating on that. We will however, need to make\na big leap to xcode 7 sooner or later and that might cause some issues similar to the Android gradle\nmigration issues. However, because of the way Apple does things we won’t be able to provide you with\na fallback flag like we do in the Android build…\nWith the Android gradle migration we can easily fallback to using Ant if you explicitly ask to do so. Its our\ndecision and Ant still works just like it did before. However, Apple decided to limit newer versions of xcode\nto newer versions of Mac OS X. In itself this shouldn’t be a problem, but Apple also broke the older version of\nxcode when updating the OS…\nSo if we upgrade our servers to the latest OS X we won’t be able to run in compatibility mode for the older\nversions of xcode.\nLimited native features, when your client says hey you GOT to use this SDK, and cn1 doesnt have a lib, you feel\npretty backed into a corner because you then have to go write a native lib for 2 platforms.\nWhile the number of cn1libs is growing and we have the tutorial on wrapping a native SDK from Steve I do see\nthe point here. Unfortunately I’m unsure what we can do here.\nFor enterprise developers we sometimes help in wrapping cn1lib’s that they might require (we then place them in\na public repository as part of the cn1lib section). Accessing native API’s/libraries will probably always require some\nmanual work from the developer or from us. I’d love to have more automation on that but I doubt its technically\nfeasible.\nWhat worries the most my boss is the fact that we are \u0026ldquo;bound\u0026rdquo; to a build server to compile the apps.\nHe would prefer that we could be indipendent in that phase. On the other hand programming in java for all the\nplatforms and with the same set of APIs is wonderful!\nSince Codename One is open source the binding isn’t as bad as it could be. If worse comes to worse you\ncould always build from code. When picking any platform (native or otherwise) you end up depending\non the platform, e.g. Apple changed a lot of of things just these past 2 years (64bit, bitcode etc.) all of which\nwere huge disruptions for native developers but not as big for Codename One.\nTo difficult to use some components. For example table use sucks.\nWe’d like to hear about those things. Table has its issues and we could improve the API for various use cases so\njust open a discussion in the forum with some suggestions and you can also fork the code to contribute\nenhancements.\nPersonally, I never ran into a Table API I liked on any platform and ours isn’t much different.\nIs the Bluetooth API finally available?\nIts java based, easy to use, very good support and fast response time. Pore support for Windows\nphones, lack of standard functions like bluetooth and NFC\nBluetooth is something we got asked quite a few times for.\nThen when the time came to implement it we contacted several developers and asked for specific use cases\nfor bluetooth. E.g. which of the many bluetooth API’s do you actually need and for what purpose?\nIt turns out that 3 out of 3 developers didn’t really know what they wanted but had a requirement to \u0026ldquo;support bluetooth\u0026rdquo;\nwithout any actual information. Normally when we are faced with a situation like this we look at similar products\nand try to create a similar API to something like Cordova. However, we couldn’t find any WORA tool\nthat implemented bluetooth so we don’t have anything to go on.\nNotice that you can always use a cn1lib to build bluetooth support without our help.\nThe lesson here though is: you need to be clear about what you are asking for. Asking for bluetooth is like\nasking for \u0026ldquo;internet\u0026rdquo;. You need to ask more specific things e.g. bluetooth discovery and serial API’s. You\nneed to file an official request as a pro/enterprise developer and give proper details.\nOtherwise these things just get buried under the amount of work we have piled up.\nAbout Windows Phone support, this has entered as one of our highest priorities. I wrote a lot in the past about\nhow we got to the state we are in, I generally blame Microsoft and their volatile offhand approach to the platform\nbut we are also to blame here.\nSince this requires a ground up rewrite this might take some time as we are under staffed. The work Fabricio\ndid in open source can help us a lot but ultimately the big problems are in the VM and the servers hosting\nthe Windows builds. Both of these should be fixed.\nSurvey Question: How Can we Improve Codename One? More functionality, like cron, need better api to handle pdf files I am running issues opening pdf in\nthe App got very little help being a pro user.\nWe already have some basic cron like support see this.\nThe use case of viewing a PDF locally is something we need to improve, as a pro user you need to clarify\nthat an issue wasn’t resolved. You also should ask for a specific enhancement if you need it otherwise\nthis probably won’t make it into the queue of tasks.\nWe should work better on communicating this.\nYour very core and idea are cool. Your CN1 implementation has quality of \u0026ldquo;proof of concept\u0026rdquo;, i.e.\nalpha, i.e. minimalistic albeit working core. It’s ok for me, because I’m like you, but current spoilt generation of\nprogrammers needs more comfortable conditions, so they don’t shoot themselves into foot each time. Invest\nmore money, hire more developers (or, if you think you have enough, hire quality manager, he will return you to\nthe ground). Focusing on PR (recent months raised activity) alone is inadequate at current stage, it is not\nproportional to developer resources and development pace you have. You say IntelliJ idea plugin is not up to\ndate, your previous UI designer (did not see next one yet) looks like 2-nd year student’s project, your demos\n(where they have a text, e.g. propertycross) all use one unattractive bold font and they mostly lack design, they\nare uninspiring, you put caret in the middle of second letter of the hint (see screenshot of search screen in\npropertycross app – this all because of broken padding/marging based on 4 styles concept, i had the same in\nmy apps), you did not implement high-level ui concepts like those found in material design, and you don’t have\nStyledTextView control!! In other words, you didn’t advance much since J2ME means of expression, And at\nthe same time you advertise it all, just to get more people raising their eyebrows, and causing \u0026ldquo;shai, relogin\u0026rdquo;\nafter any positive words towards cn1 on forums.\nOur designer is based on an official product from Sun Microsystems and is actually far improved over that but\nI actually agree. It needs a rewrite and is undergoing one (albeit a slow one).\nWe are acting on a lot of the refinement issues mentioned quite a few of them are already in place in the\nNetBeans/Eclipse versions of the plugins. E.g. we rewrote the GUI builder and switched to new default\nthemes with better fonts. I do agree we should do a lot more there and the hint text is a good example…\nI don’t think you offered a solution to the 4 style approach in the comment, I don’t think there is a generic\nsolution to that. I do think we need to improve our demos and bring them to the refinement level we see\nin some of the finished apps from some developers.\nStyledTextView is one of the painful features of Swing so no we don’t have it although Steve created something\na while back based on an HTML editor component (notice that unlike Swing/FX we have a proper webkit browser).\nThis is actually something we looked into quite a lot and\nwould love to have but you would be shocked at the state of native support for styled input…\nThere is no unifying logic or even support for styled input in iOS/Android, its possible but remarkably hard on\nboth platforms and integrating the native input into our logic of this would be \u0026ldquo;difficult\u0026rdquo; to say the least.\nLets start by creating a really nice theme that looks and works great on all platforns.\nI agree, our themes need a lot of work.\nBetter support to 3rd party APIs, use Google’s GUI builder, offline local incremental building, no\nautomatic updating of versions – even for basic users – I like to control when things change\nGoogle’s GUI builder is for Android, our API is too radically different and this just won’t work. Its unrealistic to\ntry and adapt it. Might as well adapt Matisse which we did in the past until we hit a brick wall…\nYou don’t control when things change on mobile since Google/Apple deploy OS changes and restrictions meaning\nyour appstore submission will suddenly fail because Apple made a change in requirements.\nBuilding incrementally is a problem with build servers as it makes us into application hosts which is something\nwe don’t want to do. Building offline would be painful for everyone but most of all to the users. We can only\ntest on a very limited set of configurations and we finely tune our servers to match. Now multiply that number\nof configurations by 10,000 and you get the drift.\nIf you want to build offline and to a specific self controlled version you can use our source code, its there.\nTo me that’s an unattractive option since it makes everything much harder ultimately. Even if we try to officially\nsupport that we won’t be able to simplify it by much since we would still need to send you off to install this\nand that for every single platform…\nhost online webinar or Q\u0026amp;A sessions\nSteve did quite a few of these and we worked hard to promote them. The attendance wasn’t as high as we\nexpected so we decided his time could be better spent doing other things.\nI think that if Steve spends the time he did working on the webinar by just improving the docs \u0026amp; demos this\nwould probably be better. One of the problems with a webinar is its time sensitive nature, since our community\nis dispersed widely across the globe it makes the schedule unreasonable for half of the community regardless\nof the time slot chosen.\nMaking able to start the app using argumeents. Lets say… if you could fire a notification… an you\npress it…. then you could open an specific part of the app…. same way calling the codename one app from\nanother app using an specific intent. Also.. is important the support of services and bluetooth\nThat’s already supported, the docs are sometimes complex to comb thru so I suggest using stackoverflow if you are\nlooking for something specific. The app args option can be passed via URI to other apps on execution and a\npush notification can also include hidden payloads.\nImproving your support, improving the gui designer and providing more animations and responsive\ndesign elements in the designer. I’m a CN1 evangelist and the only weak point that my developer friends\nalways say about CN1 is the gui designer and that the generated UI isnt as nice and as easy to develop as\nanother tools\nBetter GUI editor, I really like the current one but it has some problems with reordering in the\nfiletree, and some confusing usability issues. 2) Ability to somehow send off a build and get a notification on\nthe device automatically that you tap to install, the email to yourself and click link approach slows down\nproductivity imho. 3) \u0026ldquo;native simulators\u0026rdquo; would be good, ie it can launch an (existing) real android emulator\nand a real iphone emulator [or EVEN a real device plugged into usb!] (this is a pipe dream on windows since\nno one can emulate iphone which sucks, been using macincloud recently, would probably gladly have that\nopen to see it launch in an iphone emulator rather than needing to send a build and install each time) – the\nmain reason I mention this is that you need to view it natively to see the real changes, some of the tiny\ntweaks i had to do for iOS to get the top status bar thing to look perfect took days due to the cloud building,\nif your simulator could somehow replicate the appearance perfectly it would be good, but Im assuming that\nis somewhat impossible. Did you try the new GUI builder?\nWe pretty much agree that this is a very important direction to go. We do need a lot more feedback on the new\nGUI builder though.\nThe second set of suggestions should be addressed by on-device-debugging which will use an on-device-agent\napproach for execution so it will be fast and instant. Notice iOS doesn’t have emulators only simulators so\nthis will not be applicable for those.\nI’m not sure I follow the problem with support, we already put pretty much all of our available time into support.\nHow did you try to get help from us and how did that not work out for you?\nBetter scrolling mechanism/algorithm/impl\nDid you try the latest on-device versions? We just replaced it not so long ago.\nI often find myself having a hard time finding the documentation I need. There is a lot out there,\nbut it is very fragmented, so requires a lot of search time. For example, I can go to the basic java doc to get\nthe full reference of all the components, but to get code examples I have to try to find a video of something\nclose enough being done, or maybe if I’m lucky a most basic usage might be available in the developer guide\nto help me. Less common use cases leave me to using guesswork and searching for others work. Would be\nnice if java doc had more detailed information or even small snippets for all methods.\nI very much agree with that feedback. Having a link to sample usage and more extensive docs seems like\na great direction. Also links to usage samples on github would probably go a long way in helping the docs.\nWrite more unit tests\nI tend to agree with that a lot but the problem isn’t \u0026ldquo;more\u0026rdquo;. The problem is \u0026ldquo;better\u0026rdquo;.\nThe big hard to detect in advance issues are usually device compatibility issues and those won’t\nbe detected by unit tests with our current feature set.\nWe would love to have feature such as automated on-device testing within device farms, once we have\nthat we can obviously use that internally for our own deployments. Currently this isn’t one of our top priorities\nsince its a pretty big feature that doesn’t \u0026ldquo;sell\u0026rdquo; so its very hard to justify that effort in the short term. However,\nwe would like to add that in the slightly longer term vision.\nSome emulation devices don’t work properly. For example, I have bug on HTC where the bottom\nof my panel gets chopped off, but it looks fine in the emulator.\nThis is indeed painful. We are looking at doing on-device-debugging and it seems that this actually carries more\ninterest than our initial survey revealed. We think that on-device-debugging will be a game changer for many\nCodename One developers.\nIn the interim did you contact us about such issues?\nDid you get help?\nWe invest a lot of time on support both to improve Codename One (based on your feedback) and to help you\nguys get around the rough spots.\nResolve the windows 8 versions and ability to directly build BB10 app instead of android apk version.\nOur decision to avoid BB 10 seems to have paid off as RIM themselves are discarding it in favor of Android.\nWe probably won’t invest further in Windows 8 support and focus our efforts on getting a proper universal\nWindows 10 app build that will work on desktops, tablets and phones. See some of my comments above.\nCreate another subscription level between the basic and the pro for developers that dont need so many builds or notifications every month\nWe got asked this a lot and its hard for us to tell whether this would really make sense financially\nand technically. There are standard industry measurements for pricing distribution that show whether\nyour pricing is sensible (ratio of users picking every tier).\nBased on those objective measures pro doesn’t seem to be too expensive although basic used to be too cheap.\nMake it mvc 🙂\nThe list, table \u0026amp; tree classes are MVC and those are the hardest classes to deal with in all of Codename One.\nSwing over did MVC by applying it to components that made no sense for that e.g. Buttons. Our goal was to create\nsomething that’s simpler in a \u0026ldquo;good way\u0026rdquo; and avoid over abstracting some notions.\nI would even go further by saying that we are removing some of the Swing like MVC usages that are over the top.\nE.g. copying Swing’s approach to building List was a mistake in retrospect and we are now focusing on a\nmore modern approach of infinite scroll.\nI’d love to see the CSS tool being integrated into CN1\nI’ve commented about this in the previous post about this survey and it seems there are several people who\nare interested in CSS… Make your voices heard!\nIf we don’t hear you and don’t see activity we won’t work on this!\nTry Steve’s plugin and start filing issues on that, once we start seeing people use it we will integrate it into the\nplatform but this has to be something we feel is stable and in demand.\nWhere Do We Go From Here? The feedback we got here is great! It matches a lot of our feelings yet contradicts other assumptions we held\nonto.\nI think this is a good time to show the final version\nof the answers to \u0026ldquo;Which of the following is the most important to you?\u0026rdquo; and \u0026ldquo;Which of the following is the second most important to you?\u0026rdquo;.\nBoth of these changed significantly:\nHistorically we stopped publishing our roadmap since in the past we got into trouble with\ndevelopers when we couldn’t keep up (because of other developers pressing on another deadline). But in light\nof this I think we need to break the rules a bit and publish a set of priorities for us as stewards of Codename One.\nThe order of these priorities is important:\nPerformance \u0026amp; Refinement – performance is a big ticket item but with recent changes I think we are 90%\nthere. A lot of the remaining work is in giving you the tools to track why a Codename One application is sluggish both\nin terms of documentation/tutorials and in physical tools (e.g. performance monitor).\nE.g. Chen was recently reviewing a performance issue that was triggered by making a single solid color UIID\nopaque instead of transparent. These things can sometimes be very hard to track even for us.\nThe refinement aspect is arguably more complex, themes that are more complete, material design capabilities\nand an easy/intuitive out of box feel. Windows Phone Port – while this didn’t get the top spot it is indeed painful to many developers. We are\ninvestigating a potential shortcut we can take that will hopefully save us the need of porting ParparVM\nto Windows. We would do the port anyway and probably base it on the excellent work from Fabricio. We see\nthis is the second most important thing we have to do but with the volatile nature of this task we can’t really\ncommit to a timeline. GUI Builder – we wrote a completely new GUI builder and we committed to having it at beta grade for 3.3.\nWe intend to keep with that plan and enhance it based on your requirements/feedback. Documentation – we need to review everything about our documentation and redo as much\nas we can. Ideally also go to older sources and reference the newly available data immediately. This is painstaking\nwork especially given the volume of documentation we have.\nIn the past our docs were open but they weren’t easily accessible. We’ll try improving this and refining the tools\nto work with the docs. This work might grind our progress to a standstill but I think its crucial that we do it now. IntelliJ/IDEA Update – we need to put out a fix for this. This might be in a form of moving to maven/gradle to\nsimplify the work that the plugin does today. On device debugging – we think we can leapfrog a lot of the solutions in the market with our approach to\non-device-debugging. This is something we wanted to do for quite a while and its hard to get to with our\ncurrent set of limited manpower. If we get thru the list above this is solid on my personal wish list… You will notice some important tasks that are missing from the \u0026ldquo;top priorities list\u0026rdquo;.\nE.g. a complete rewrite of the theme designer or a CSS alternative are missing. This has been a part of our TODO\nlist for quite a while but we left it out of the current priorities. We want to evaluate the reception of the new\nGUI builder as well as the reception to the CSS plugin from Steve before making any long term decisions here.\nAnother thing that’s important and missing is new Java language features. Even though 25 percent of you indicated\nthat they want this as their highest or second highest priority. The main problem here is in our phrasing of the\nquestion, Java language features mean very different things for different people and while we agree with the\nbasic premise of extending the functionality of the VM’s we have doubts about the scope. We might conduct\na separate survey dedicated for this exact purpose but right now we have enough on our plate.\nSummary I hope this gave you some answers about why things are in this particular way. I left out a lot of comments because\nof many reasons but I think I got most of them and didn’t pull punches. I hope this did give you a better sense\nof how we plan to fix these issues and maybe some ideas on how to help us with that process.\nFeel free to use the comments section to refine or better articulate some of the points made, or maybe\nanswer some of the questions I had about unclear comments above.\nI’d also like to thank all of you who answered the survey in great numbers, it has been very illuminating.\nWe really enjoyed the kind words in it as well, which made the other comments go down easier. We really\nappreciated the rougher comments as they do help us improve. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFabrício Cabeça — January 11, 2016 at 10:49 pm (permalink) Fabrício Cabeça says:\nThanks for mentioning my work with the Windows port, you can count on me in case you want to take this leap of faith. To me this is one of the biggest problems in cn1, the other one is the fast lifecycle that delivers great features but great headaches too. Versioned builds helps but even there I had issues before.\nCarlos — January 17, 2016 at 4:11 pm (permalink) Carlos says:\nI totally agree with the previous comment. Windows Phone support is important for me. On the other hand, regressions force us to write workarounds that can even be the cause of future problems when the issues are fixed.\nApart form that, I can’t emphathize enough how good CN1 has been for us, and how it has been a game changer for our business model. Thanks for that.\nOh, and please, whatever you do, don’t deprecate the list rendering approach. It may be a hassle to some developers, but I like the concept and actually make use of it on some projects.\nShai Almog — January 18, 2016 at 3:43 am (permalink) Shai Almog says:\nThanks!\nWe made a big mistake with the recent set of updates. We should have tiered them more slowly, added flags to disable them more easily and we shouldn’t have done them while everyone was on vacation (which seemed like a good idea when we started off).\nNo worries, we are probably stuck with renderers for good. The main change we’d do is in de-emphasizing it in our docs and trying to gently nudge people to use components/containers which are pretty performant.\njoaa — April 16, 2016 at 4:29 pm (permalink) joaa says:\nI love to be able to import my code from android studio and just continue working on it without the need to start from begining. Any comments?\nShai Almog — April 17, 2016 at 12:10 pm (permalink) Shai Almog says:\nThanks for the feedback. This is a point that came out a few times before so I posted a blog entry covering this here: https://www.codenameone.com…\nThe gist of it is \u0026ldquo;we’d like to do it but it’s damn hard so we might get to it one day…\u0026rdquo;.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/what-sucks-in-codename-one-how-can-we-fix-it/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/what-sucks-in-codename-one-how-can-we-fix-it/which-of-the-following-is-the-most-important-to-you-2.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI deeply care about what we do at Codename One and writing a negative post even when the words aren’t mine\u003cbr\u003e\nis difficult. I think one of the most valuable thing about an open project is honesty and open communications even when\u003cbr\u003e\nthat’s unpleasant, \u003cstrong\u003ewithout open criticism we can’t get better\u003c/strong\u003e.\u003cbr\u003e\nChen recently sent out a request to fill out our survey via direct mail and responses came streaming in. Added\u003cbr\u003e\nto the guys who filled it out after our previous blog post we got a lot of additional valuable feedback.\u003cbr\u003e\nWe can’t satisfy everyone and we shouldn’t aim to, however developers who spent time answering our survey\u003cbr\u003e\nprobably like the basic concept of Codename One and should be happy. Most of them by a good margin (over 90%)\u003cbr\u003e\nare happy, but its only a good margin not a great margin and in this post I’d like to hash up the problems.\u003c/p\u003e","title":"What Sucks in Codename One \u0026 How Can We Fix It?"},{"content":"\nI had a big post ready for today but after a long twitter debate with\n@BrendanEich I had to write a followup as\ntwitter is a poor medium for that level of debate.\nThis started with a blog post from Andreas Gal who effectively took the exact opposite stance to mine on\nGoogle’s move to OpenJDK.\nThen Mr. Eich picked it up:\n.@mosheeshel @enleeten @hhariri @Codename_One We don\u0026rsquo;t know enough yet, but I agree with @andreasgal that code changes show cost+risk go up.\n— BrendanEich (@BrendanEich) January 5, 2016\nTo be fair I’m biased. I work on a cross platform mobile toolchain and I’m an ex-Sun\nguy. But I think that the fact that the senior Java/Android community has embraced this change as a positive one\nsays a lot. Also Android compatibility is crucial in our line of business where we need code to work for all\nversions of Android without a problem…\nLets go over the claims made both on Twitter and in the article.\nOracle sinks its claws into Android Using a title like this is misleading, clickbait \u0026amp; antagonistic.\nI don’t think Oracle made any friends with the lawsuit, overall the vibe in the Java community is that\nthis was a mistake that didn’t help anyone. The thing is that OpenJDK is GPL and so Oracle doesn’t really\n\u0026ldquo;own\u0026rdquo; it and doesn’t really gain much except in maybe some \u0026ldquo;respect\u0026rdquo;.\nOpenJDK is GPL+CPE so Google can use it without paying Oracle a dime (just like Linux distros do). It also\nfeatures a patent grant which means that if Google passes the TCK’s (meaning they are Java compatible which\nis a good thing(tm)) they will receive a license for the patents and Oracle can’t legally sue\nthem over patents used in the VM!\nSo effectively the title is pretty wrong, Google gets newer up to date Java code for free and the Java OSS community\ncan focus on one code base (for security analysis, performance etc.) instead of two. Compatibility will rise\nalthough its already there or 99.99% there.\nThis Was Forced Thru Legal Process Totally true. That doesn’t make it bad for us although one could wish that peace was reached without the legal system.\nGoogle took a calculated risk when Android was young which made a lot of sense when Sun owned Java.\nThe reason for taking a specific action doesn’t mean its bad, I would wager that one of the reasons Google\navoided adopting OpenJDK in the past was legal as well.\nApache License vs. GPL License As I was writing this a great article was posted that pretty much answers this better than I could. I chose to leave my\nthoughts below since its simpler to read.\nIts harder to get people to adopt GPL, but they did it with Linux despite there being BSD licensed alternatives\nthat are pretty good. Google already used Linux as the core so already has some GPL code.\nThe original post already corrected the fact that OpenJDK didn’t exist when Android came out. But that wasn’t\nthe sticking point with Sun. Google wanted the Apache license and Sun was making a lot of money over mobile\nso this was a big problem/conflict.\nThe reason Google insisted on Apache was due to operators who were the gate keepers Google needed to get\npast to control mobile. Now that its already in and controls the market adding more GPL code is meaningless just\nas operators have gone down in their power since the days Android launched. Overall this changed nothing,\nin Android M you had X lines of GPL code from Linux and now you will have more lines of GPL+CPE code\nno real difference.\nAll this code and technology churn will have massive implications for Android @Codename_One @deanrl @enleeten @hhariri To recap, @andreasgal \u0026amp; I say MLOCs of forced change carry hi incompat risk, all agree that\u0026rsquo;d suck.\n— BrendanEich (@BrendanEich) January 6, 2016\nThis is far from accurate. To be fair, only Google engineers know the approximate extent of work and only\nafter the fact will we fully know the implications. However, I’ve ported JVM’s for years both at Sun\n\u0026amp; at Codename One. I’m very familiar with the issues of getting code to work on the desktop\nVM and the mobile VM and specifically with Android issues.\nFrom my experience Android VM compatibility issues are 80% vendor/operator issues (weird stuff with\ndevice specific behaviors) and 20% issues in the android.* packages. We ran into no\nissue whatsoever with the harmony code being different from Java 7 or 8 in terms of compatibility.\nIts possible that such edge cases exist but I doubt it would be a big deal and it would allow better\nserver/mobile shared code.\n@deanrl @Codename_One @mosheeshel @enleeten @hhariri @andreasgal Developer reward is later and second or third order. Risk+cost first order.\n— BrendanEich (@BrendanEich) January 5, 2016\nThe existing Harmony classes are old and stale, no one touched them in years so a big change of removing\nand replacing them with other classes will take some effort from Google’s developers. That’s a fact.\nIts years worth of changes that now Google needs to do in a single swoop but its something Google\nshould have done in the past to bring newer classes/features into place. The alternatives\nare doing nothing or doing this slowly at their own pace both of which would be bad.\nJava has amazing TCK’s that check compatibility, the likelyhood of something breaking is relatively low.\nWe have been porting Java code to Android for years with absolutely no issues related to these API’s so on\nthe surface this looks like something that would go unnoticed for most existing apps. If something will stop\nworking or behave radically different Google has the ability to work in compatibility mode for that specific\nAPI builtin to their manifest target SDK system.\nWhile this is big change in terms of lines of code most of those lines are already written and well tested so\nit looks like a big change but is much smaller in scope than the LOC would make it seem. Prior changes made\nby Google even for Marshmallow are huge earth shattering changes to the basic permissions system of Android\nthat has been in place since 1.x days. That is probably a far bigger problem for everyday Android developers\nthan this change.\nDevice compatibility with no-brand devices on the far east market and non-google devices are also far bigger problems\nfor an Android developer than this will ever be.\n@deanrl @Codename_One @mosheeshel @enleeten @hhariri @andreasgal 2/ Bill Joy of Sun persuaded us to kill Kipp\u0026rsquo;s VM as bug4bug is impossible.\n— BrendanEich (@BrendanEich) January 6, 2016\nI worked at Sun for years and never got facetime with Bill Joy… Ugh.\nWhat was true in 1995 is no longer true today, Java now has a robust TCK and language specification. It\nhas quite a few separate compliant VM’s and is pretty well understood. I think Google did an amazing\njob at compliance and its clear they followed the JVM specification well.\nThis Change Won’t Benefit Users @deanrl @Codename_One @mosheeshel @enleeten @hhariri @andreasgal Developer reward is later and second or third order. Risk+cost first order.\n— BrendanEich (@BrendanEich) January 5, 2016\nWhile there are some changes that benefit users directly, most software development changes don’t. Not\nall developers benefit from every language/API feature either.\nUsers will benefit from the fact that code bases are unified and security auditing will now focus on a more\nuniform code base. A lot of the standard Java tools might work better with Android as a result e.g. the current\nlevel of Android profiling support is HORRIBLE when compared to desktop Java or even iOS.\niOS has excellent profiling support thanks to d-trace (technology from Sun) so hopefully we’ll see an eventual\npeace process and more collaboration to benefit everyone.\nFinal Word @Codename_One @mosheeshel @enleeten @hhariri @andreasgal Any nontrivial work raises costs+risks. As technologist \u0026amp; founder I see it plainly.\n— BrendanEich (@BrendanEich) January 5, 2016\nI think this sums up a lot of the claims. Yes this will take Google some effort. Yes a few apps might be\naffected, I’d wager this would be far less than those affected by the Marshmallow changes and Google\nhas the tools to alleviate a lot of that problems (sdk version hints).\nWould Google have done it without the lawsuit?\nMaybe… If there was no lawsuit and Java 8 was out, maybe Google would have adopted OpenJDK or maybe\nthey would have dedicated the engineering effort to add this support into Android’s Harmony. Either way\na lot of engineering effort would have gone out whether the lawsuit was there or not.\nGoogle’s current version of Java is old and stale, replacing it is a good thing for everyone even though its\nnot free of any costs. But everything has a cost and this one is probably worth paying in the long run. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nBo83 — January 6, 2016 at 5:20 pm (permalink) Bo83 says:\ngreat article and I get the overall gist of what you are saying but I would need a dictionary of terms and a day to study it to really read this article and understand it intelligently and thoroughly. I just want to write code with the latest and greatest; can’t we all just get along 🙂\nShai Almog — January 6, 2016 at 5:28 pm (permalink) Shai Almog says:\nThanks.\nIt was actually fun debating him since he is a good debater (and REALLY smart). I just really can’t stand debating with \u0026ldquo;catch phrases\u0026rdquo;. Technical debates require proof and context which is problematic in twitter.\nChad — January 6, 2016 at 10:56 pm (permalink) Chad says:\nIMO phrases like \u0026ldquo;Java has amazing TCK’s that check compatibility\u0026rdquo; and \u0026ldquo;It has quite a few separate compliant VM’s\u0026rdquo; are disingenuous. This is what killed Harmony in the first place, they couldn’t get a TCK because Oracle didn’t like their license. I would love to make my own open source compatible JVM, but I will never see the TCK. I think it’s harmful to pretend it’s a \u0026ldquo;good thing(tm)\u0026rdquo; that implementations have to pass a hidden test suite whose keyholders may make demands of your software. Sure it means I can’t call my JVM \u0026ldquo;Java\u0026rdquo;, but that’s the problem here. There is only one open-source compliant JVM implementation base that I am aware of, and that is a bad thing.\nShai Almog — January 7, 2016 at 3:37 am (permalink) Shai Almog says:\nInteresting point, I skimmed over the angle of a VM implementer as its probably less interesting to most of the readership!\nFirst let me clarify that my bias is towards Google as I think they were in the right side technically as clean room implementations should be legal. We also use some code from Harmony in Codename One so I’m very much in favor of that.\nSun was the one that refused the TCK license to Harmony, its an important distinction with all the people pilling hate on Oracle I don’t think we need to add something else there 😉\n(Although to be fair Oracle didn’t fix anything in this regard)\nWe make our own VM too (ParparVM) so obviously to be compliant we also need to pass the TCK now (see my previous analysis on the subject) which might also be a problem. If you use OpenJDK and its license you can probably apply to access for that as I’m sure Google has. Since they are/were a Java licensee I think they might already have that access.\nFor a small VM (like us) this is more problematic so I totally agree that the opaqueness of the TCK process is a problem. FYI I did \u0026ldquo;see\u0026rdquo; and worked a lot with the TCK on older versions of Java to get our VM’s thru compliance. For Sun’s VM’s it was mostly trivial since the JIT/VM was reused but there are a lot of weird edge cases tested by the TCK.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/debating-brendan-eich-over-android-openjdk-move/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/debating-brendan-eich-over-android-openjdk-move/dukeandroid.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI had a big post ready for today but after a long twitter debate with\u003cbr\u003e\n\u003ca href=\"https://twitter.com/BrendanEich\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e@BrendanEich\u003c/a\u003e I had to write a followup as\u003cbr\u003e\ntwitter is a poor medium for that level of debate.\u003cbr\u003e\nThis started with a \u003ca href=\"http://andreasgal.com/2016/01/05/oracle-sinks-its-claws-into-android/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nblog post from Andreas Gal\u003c/a\u003e who effectively took the exact opposite stance to mine on\u003cbr\u003e\n\u003ca href=\"/blog/analysis-google-moving-to-openjdk-what-that-really-means.html\"\u003eGoogle’s move to OpenJDK\u003c/a\u003e.\u003cbr\u003e\nThen Mr. Eich picked it up:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e.\u003ca href=\"https://twitter.com/mosheeshel\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e@mosheeshel\u003c/a\u003e \u003ca href=\"https://twitter.com/enleeten\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e@enleeten\u003c/a\u003e \u003ca href=\"https://twitter.com/hhariri\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e@hhariri\u003c/a\u003e \u003ca href=\"https://twitter.com/Codename_One\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e@Codename_One\u003c/a\u003e We don\u0026rsquo;t know enough yet, but I agree with \u003ca href=\"https://twitter.com/andreasgal\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e@andreasgal\u003c/a\u003e that code changes show cost+risk go up.\u003c/p\u003e","title":"Debating Brendan Eich Over Android-OpenJDK Move"},{"content":"\nI think we’ll remember 2015 as the year we finally \u0026ldquo;hit our stride\u0026rdquo; and \u0026ldquo;got it\u0026rdquo;. Up until now we did a lot of\nthings correctly but were a bit disorganized both in the way we communicated Codename One and in the\nrefinement of the product itself.\nWe changed and refined almost every piece of Codename One in 2015 and the results were\ngreat. But we want to do better so here is my analysis of what we did wrong (both in 2015 and before) and\nwhat we did right. Followed by the initial survey results and feedback from we got from you guys and our\n2016 direction.\nWhat We Did Wrong I worked for a company that built flight simulators for EA in a previous lifetime. We had about 20 airforce pilots\non staff and they brought the wonderful culture of \u0026ldquo;debrief\u0026rdquo; to the development process. Every time we\ndid something we’d analyze what went bad and what went well so we can learn. I think focusing on the bad\nfirst really helps drive that point thru!\nWindows Phone Support –\nwe have huge problems here. Relying on Microsoft to add the Android support\nwas a mistake and we need to fix this as soon as we can. IntelliJ/IDEA Support – Our current support for IntelliJ/IDEA is by far the worst. Because the code for every\nIDE plugin is separate fixes/enhancements should be made 3 times and currently we only do them twice.\nThis is made worse by the fact that IntelliJ is used by an excellent demographic\nthat is getting a horrible first impression of Codename One!\nOne of the roads we are thinking about is moving away from Ant to support a more IDE neutral architecture.\nI don’t like Maven much and Gradle seems to also have its issues but if we can unify more IDE specific code\nthat could be a huge difference. Unclear messaging – our website and materials are still unclear and out of date. E.g. there is very little\nin the form of introduction to Codename One. A lot of the videos are stale by now and need newer versions. Build failures – builds still fail and produce unclear error messages. We need to improve that process\nso people don’t hit a wall. Easier migration – currently moving from Android/Swing still requires adapting a lot of API’s. While zero\nchanges is probably an unattainable goal we should still make that process less painful. Debugging – we still don’t have on-device debugging which is something we can and probably should offer. What We Did Wrong \u0026amp; Fixed In 2015 We made a lot of changes in 2015 that fixed long running problems:\nMoved to stack overflow\n– I had my reservations about this but its a HUGE improvement in every regard.\nIt also helped our SEO efforts and our general visibility. Bad design by default –\na default hello world application looked horrible in Codename One. The default\nfonts were also pretty horrible. Material design and other common paradigms are still not properly addressed\nout of the box in Codename One. We are working on filling the gap here and cosider these to be important priorities. Fast release cycle –\nwe procrastinated on releases prior to 2015. This made basic features like versioned\nbuild completely useless. Shortening the release cycles made them easier as each release became simpler. We failed to communicate that we are open source\n– a lot of people misunderstood Codename One’s source\ncode strategy and we only have ourselves to blame. We were pretty opaque about some of these things and\ndidn’t properly highlight our code on the site. Moving to github – we had a lot of reservations about this move. Ultimately we are thrilled with github\nand it really simplified a lot of things for us. Its a far better venue than Google code. Scroll performance – for quite a few years we got complaints about janky scrolling behavior in Codename One\nwhen compared to native iOS apps and recently also to Android apps. Since the complaints were vague\nwe just left them at that as they were pretty hard to investigate (too subjective). We recently made a big\npush here both on iOS \u0026amp; Android. The end result is much smoother and far more \u0026ldquo;native\u0026rdquo;. General performance – the initial release of ParparVM wasn’t as performant even when compared\nto XMLVM for some use cases. Thanks to many commits made by Steve and myself this has changed\ndrastically!\nParparVM will probably never beat the top of the line AOT VM’s in microbenchmarks since it isn’t designed to\ndo so, we pay a performance penalty to remove the GC overhead/stalls. But its now far more competitive\nfor many common use cases. Optimizing ParparVM is relatively easy because of its ridiculously simple\narchitecture that doesn’t require prior VM experience. Blogging – in 2015 I invested more time blogging and this resulted in an amazing traffic boost to the site\nand far more awareness of Codename One. In the past we used to get a lot of traffic from Slashdot/HN/reddit\nbut we stopped working at that circa 2013… This year I wrote the two most popular (ever) dzone mobile articles and\nthe second most popular Java dzone article. I got quoted in multiple outlets and this ultimately resulted in great\ntraffic for Codename One. Moved away from app engine – while the move isn’t complete we moved away the bulk of the functionality\nand a heavy weight was lifted from our wallet. What We Did Right We released a lot of new things this year that are brand new, here are some that we are most proud of.\nJava 8 support – we went into this not expecting much and it blew us away. This worked better than we expected. ParparVM – when we started writing our own VM we weren’t all in agreement that this was the right way to go.\nWhen we released it the bugs were significant and very hard to iron out. As we moved forward it matured\nto a product we are really proud of. Steve came up with the idea of rebranding the VM and Chen came up with\nthe name which ultimately was one of the best decisions we made this year. JavaScript Port – the JavaScript Port has proved to be a really useful tool for many different purposes. Our\nability to instantly demonstrate an app with no installation requirement is pretty darn amazing.. Certificate wizard – this was a \u0026ldquo;killer feature\u0026rdquo; the one big missing piece here is appstore Toolbar – when we launched Codename One the title area functionality looked totally different between\nthe mobile OS’s. In the interim this slowly converged to something far more similar. The Toolbar API closes\nthe gaps between the OS differences while bringing with it pretty advanced features… URLImage/FontImage – both of these really changed the way we write Codename One apps/demos.\nWe feel we need to redo all the demos based on font image. What You Guys Said We posted a link to our\nannual developer survey, if you haven’t filled it out yet then please do so right now. Its very unscientific\nbut it gives us a sense of how we are doing both in communicating what Codename One has and doesn’t have.\nThe two most important questions were first: \u0026ldquo;Which of the following is the most important to you?\u0026rdquo;\nTo which you answered:\nThe next question was: \u0026ldquo;Which of the following is the second most important to you?\u0026rdquo;\nTo which you answered:\nTo me these results are quite interesting as they show some interesting patterns e.g.:\nI would have expected on-device-debugging to be really important to some developers but its not\neven mentioned as the first order priority. Had I wrote the survey now I would have added \u0026ldquo;which Java language features are you missing\u0026rdquo;… I have\na strong sense that pretty much everyone who answered that wanted something different from the other guys\nwho picked that option. The new GUI builder is an important advancement and we need to finish it for 3.3. Better Windows Mobile support is probably almost as important as the new GUI builder Another interesting question was \u0026ldquo;What form of documentation/help do you value the most?\u0026rdquo;. The response\nfor this took us by a bit of a surprise:\nI would have expected the videos to be somewhat higher on the list, the \u0026ldquo;other\u0026rdquo; segment mostly refers to the forum\nbut that’s not quite documentation. Removing that it seems the clear majority shows a preference for written\ndocumentation over videos/courses…\nOur developer guide is probably the least refined part of our documentation as we were focusing more on\nvideo/blog entries. I prefer working with videos sometimes as they allow me to gauge viewer interest more\naccurately and are easier to promote, but it seems we need to put more effort into the developer guide.\nThe comments were probably some of the most interesting parts. I selected a few to both highlight and comment\non, if you have additional thoughts about this I’d love to hear them in the comments section to this post:\nSupport more languages (e.g. Kotlin), support Gradle, support Jar libraries on public repositories (e.g.\nMavencentral, JCenter, etc) perhaps with some checking to see whether it uses any unsupported api or stuff then\nproviding a way for the developers to add those missing bits.\nJVM languages are very interesting, Steve explored Mirah\nquite a while back and it is something we think could be interesting. Having said that I think keeping focus\nat this stage is crucial so this (at this time) isn’t a priority. However, if community members want to port\na language on top of Codename One or ParparVM we’d be happy to try and help in any way we can.\nI don’t like Maven and from dealing with Gradle recently it doesn’t seem to have fixed all the things broken\nin Maven. However, its more flexible and might be a good direction moving forward. The main motivation would\nbe in improving the intellij/IDEA integration and ideally having more common code between all IDE’s.\nCurrently Gradle isn’t as mature as Maven and Maven is a bit too rigid for what we are trying to do so we don’t\nhave any concrete plans here…\nGetting dependencies from Maven central might be a problem. Most standard libraries won’t work\nout of the box since most assume a lot of things about Java (e.g. filesystem/networking etc.) that we just don’t\nsupport. They also don’t support cn1lib’s which are pretty powerful.\nHaving said that, we would still like to add something like \u0026ldquo;maven central\u0026rdquo; to Codename One eventually, we’re\njust unsure whether maven central itself can actually be used for something like this.\nCodename One is getting better all the time anyway. I realise that reflection is challenging but RoboVM\nmanages it. It would make a big difference to simplifying some of the more complex data driven apps that I\nhave. Headless JUnit testing for apps, channels for push notifications. Google maps in the simulator.\nI agree that we need better headless testing but probably not JUnit. We need something to run on devices\nand ideally offer device farm support so you can instantly test your app (ideally with CI) on actual devices.\nThe reason we don’t support reflection isn’t technical. Its REALLY easy to add reflection. The\nreason is conceptual. We won’t be able to properly optimize/obfuscate the code, reflection is remarkably\nslow for AOT invocations and has no critical use case in mobile. Tools that add reflection also require that you\nimport everything into the final build resulting in 100mb+ build results. That isn’t a smart thing to do…\nWe could add something like reflection and just proclaim \u0026ldquo;if you use it then its your problem\u0026rdquo;, unfortunately once\nsomething like that exists people use it \u0026ldquo;unaware\u0026rdquo; because its a part of the API. Then we get the \u0026ldquo;blame\u0026rdquo; for\nthe resulting problems.\nHaving said that, I don’t want to rule anything out completely. We might add something that’s reflection \u0026ldquo;like\u0026rdquo;\nor even reflection itself to support various cases. The problem is avoiding the \u0026ldquo;link everything\u0026rdquo; end result that\ncomes with reflection.\nMove away from visual builder – it’s always more restricted than coding. Move towards more of a\nmarkup (XML, CSS) format.\nSteve introduced CSS support a while\nback and the new GUI builder really just uses XML. We didn’t see that much activity around the CSS support\nso its hard for us to gauge interest here but it seems low.\nThe plugin for CSS was meant to gauge community interest, if there is none then the effort of integrating CSS\ndirectly is probably not worth it. However, if this would pick up and gain traction we might make it an official\npart of the toolchain.\nFYI other comments (not mentioned here) asked for more GUI builder samples and other related features\n(GUI builder was the second highest RFE). So these sort of things are very subjective especially when covering\na varied community as we have in Codename One.\nCodename One has a lot of quirks, its taken a fair bit of time to learn and work around the niggly\nlittle differences between performance and rendering on different platforms. Things like screen flicking on\nAndroid with native components and SQLite issues on iOS. Apart from these issues its a great system for\ngetting cross platform apps together.\nI pretty much agree with everything you’ve said. We need a better story for database storage, peer components\nand on-device issues.\nLike: the GUI library, true WORA. Dislike: performance on iOS and to some extent on WP\nWe’ve done a lot of work on performance on iOS (see above) which should put both ParparVM and the Codename One\nport for iOS/Android at a whole different level in terms of performance.\nThe Windows Phone/Mobile port should be rewritten from the ground up, its an important task in our short term\ngoals.\nI feel you go too fast sometimes, need to ensure stability before releasing new version (regressions\nstop our development)\nAgreed. We need a better QA process.\nNotice that for pro accounts we have the stabler versioned build option.\nGetting started was a challenge.\nI’d love to hear more on that but this was the only part of the comment submitted. The initial onboarding is probably\nthe most crucial part in any tool.\nThe Plan For 2016 Based on the above and general feedback we get continously from developers we would like to focus on the following\nthru 2016. The highest priority bits would be:\nGUI builder – get it out the door and into the default projects. Hello world app should be a GUI builder app Windows Phone/Mobile – Leverage the excellent work done by Fabricio et. al to get Windows back into\na first class citizen platform. Performance/Native – improve and refine the performance of Codename One to make it indistinguishable from native.\nI’d also like to improve the way peer components act across platforms. Design – we need Codename One apps to be gorgeous out of the box. The first impression is crucial and\nwe currently botch it. Its much better than it was in 2014 but I think we can do a lot more! Documentation \u0026amp; Samples – that’s always crucial but I’d like to make these a top priority. There are a lot of other priorities I’d like to see going into Codename One. I’d like to see us leverage the JavaScript\nport more, I’d like us to offer a full ALM solution (automatic appstore upload as part of a CI process). I’d like\nto see on device debugging \u0026amp; better security options (encrypted filesystem/DB etc.).\nLet us know what you think both in the comments and thru the discussion-forum/support. Even if we say no initially\nwe often shift our opinions on things as we move forward and if we get enough feedback from the community. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDiamond — January 4, 2016 at 3:34 pm (permalink) Diamond says:\nThat’s a great success story for 2015.\nI would be commenting only on CSS support for codename one…\nI tried it out and realised that it generates additional 9-piece border images for my app, which increases the app size and in turn slows down the performance.\nIt would have been great if it could really create true styling like css does on webpages without generating images.\nThat’s why I stopped using it and I think that’s why other developers don’t really fancy it that much.\nOn a separate note, As codename one is open source, I think you should devise a way to attract more code contributions by all developers. As most of us create some cool features and unique codes but never contribute them back. Look for a way to promote the culture.\nShai Almog — January 4, 2016 at 6:27 pm (permalink) Shai Almog says:\nThanks, that’s great feedback. I doubt CSS will ever be like it is on a web page but we do need to improve some of the border API’s to be more performant and customizable.\nVery few open source projects get significant code contributions so we’re not counting on that as much as we hope for small bug fixes/pet-peeves from developers. E.g. this was a wonderful contribution: https://github.com/codename…\nJust a bunch of fixes for my horrible grammar/spelling.\nBut the main value of being open source is the community aspect, e.g. the work you are doing in stack overflow is tremendous!\nJerry — January 4, 2016 at 7:05 pm (permalink) Jerry says:\nThumbs up for the CN1 team. Good job guys.\nI would love to see you integrate the CSS plugin into CN1 after a little more housekeeping on the Plugin. This will make it easier to work with, especially for the new starters. I believe you will be overwhelmed by the result.\nShai Almog — January 5, 2016 at 3:39 am (permalink) Shai Almog says:\nThanks. I know Steve agrees and Chen to a lesser extent.\nPersonally, I’d like proof before committing resources to support this.\nDid you use the plugin?\nI think a lot of the people advocating CSS have a bit of a misconception of how it will \u0026ldquo;feel\u0026rdquo; within the Codename One developer workflow. I’d like to know if my concerns are founded or not before we take this big piece of code with all its baggage into Codename One.\ngardnr — August 1, 2016 at 9:58 pm (permalink) gardnr says:\nThe next sentences after \u0026ldquo;The reason is conceptual.\u0026rdquo; go on to discuss technical aspects of adding reflection.\nShai Almog — August 2, 2016 at 3:54 am (permalink) Shai Almog says:\nThey go hand in hand. The conceptual reason is that we want Codename One to be \u0026ldquo;seamless \u0026amp; efficient\u0026rdquo;. To do that we need to generate an app that is small like a native app, secure (as in obfuscated), fast etc.\nDue to the technical reasons above we can’t deliver the conceptual vision of Codename One \u0026amp; reflection.\nI think what I was getting at is that while this is solvable technically most people were oblivious to the problems this created as a result so this is more of \u0026ldquo;this is the wrong way of doing it that caused problems\u0026rdquo;.\nWe are thinking about offering a client side API that would solve the big reflection use cases (IoC, ORM, language support etc.) without the problems typically associated with reflection. This will require a different API and usage pattern but if this is interesting to you let us know.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/the-road-ahead-2015-in-review-survey-results/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/the-road-ahead-2015-in-review-survey-results/looking-forward.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI think we’ll remember 2015 as the year we finally \u0026ldquo;hit our stride\u0026rdquo; and \u0026ldquo;got it\u0026rdquo;. Up until now we did a lot of\u003cbr\u003e\nthings correctly but were a bit disorganized both in the way we communicated Codename One and in the\u003cbr\u003e\nrefinement of the product itself.\u003cbr\u003e\nWe changed and refined almost every piece of \u003ca href=\"/\"\u003eCodename One\u003c/a\u003e in 2015 and the results were\u003cbr\u003e\ngreat. But we want to do better so here is my analysis of what we did wrong (both in 2015 and before) and\u003cbr\u003e\nwhat we did right. Followed by the initial survey results and feedback from we got from you guys and our\u003cbr\u003e\n2016 direction.\u003c/p\u003e","title":"The Road Ahead: 2015 In Review \u0026 Survey Results"},{"content":"\nI’ve been following the news breaking since yesterday as\na hacker news post\nhighlighted that an Android commit included OpenJDK files. This is amazing news and a huge step forward\nfor Java, its still unclear if this is just another move or the inkling of a settlement between Google and\nOracle but I’m very hopeful that this is indeed a settlement. So far Google wouldn’t comment on the\ncourt case and whether it was settled since its still ongoing.\nDisclaimer: I worked at Sun/Oracle but had no internal knowledge of any of the things\ndiscussed here. The information here is collected from public sources, my understanding of the mentality of\nsaid companies \u0026amp; from our following the case at Codename One (we consulted IP lawyers quite a bit\nwhen we started and this case was always on our mind).\nI’ve read a lot of the comments in the reddit \u0026amp; hacker news threads and they seem to include a few upvotes\non comments that are just plainly wrong here is a brief FAQ/informational on these common misquotes.\nAndroid will move to Hotspot/JIT That’s unlikely. Java compatibility and compliance with OpenJDK doesn’t require that you use the JIT that ships\nwith it or any of its source code for that matter. Quite a few compliant implementations don’t.\nWhile Hotspot will probably beat ART for anything other than startup time performance on mobile is quite\ndifferent than desktop performance. Battery life is more crucial than speed and I doubt hotspot is\noptimized for that.\nSwing/AWT/FX Will Finally Be Supported On Android There is no indication of that and it seems very unlikely.\nGoogle can be Java compliant by supporting a subset of Java and this is even easier thank to the modularity\nchanges in Java 9. Swing/AWT/FX compliance complicate this whole process to a completely different level.\nGoogle Was At Fault There were several claims like this e.g. Google copied code etc.\nI don’t like the fact that Android isn’t Java compatible and forked, but I generally disagree with that statement.\nIt might have been wrong \u0026ldquo;morally\u0026rdquo; to fork Java, but I don’t think it was wrong legally.\nIn the discovery phase of the trial only one small method was shown to be a direct copy and the judge\ndismissed that as ridiculous.\nGoogle didn’t violate the trademarks of Java and the coffee cup which are an important tool to keep Java clean.\nE.g. they never claimed that Android runs Java, it runs Android/Dalvik and now ART. It compiles Java source code\nwhich is a big leap.\nThe claim is about copyrighting the API, that’s a problematic claim since Google did use a clean room implementation\nof the public API’s. The supreme court effectively said that clean room implementations of public API’s are\nillegal!\nThat’s a pretty bad thing since copyright is implicit. Its owned even if the person publishing the material doesn’t\nexplicitly write that little (c) you see next to various types of work. So if you ever implemented an API you are\nnow effectively using copyrighted code!\nMost programmers who understand this think that Google acted based on \u0026ldquo;fair use\u0026rdquo; which means they didn’t\nactually violate the rights of the copyright holder.\nOracle is a greedy litigious company Not really.\nOracle does sue companies but generally larger companies that can afford this, I’m unaware of them suing\na startup or other small companies (feel free to correct me if I’m wrong here). It is far more profit driven than\nSun was. I really loved Sun and loved working there, I can’t say the same about Oracle…\nBut to be totally fair, Sun no longer exists in part because it was mismanaged and maybe not \u0026ldquo;greedy\u0026rdquo; enough.\nHaving a strong \u0026ldquo;landlord\u0026rdquo; for Java might be disturbing in some regards but it has its advantages. I think\nanyone trying to show Oracle off as \u0026ldquo;evil\u0026rdquo; is plain wrong.\nThis is like the Microsoft Lawsuit No.\nMicrosoft was a Java licensee and took the code to create a non-compliant implementation. Google was\na licensee but the Android division was not. The fact that Google was a licensee for Java didn’t factor into\nthe trial to my non-lawyer knowledge.\nThis is about Java Compatibility While Java compatibility is important and Google did do some damage there (not as much as the lawsuit did but\nstill), this wasn’t the reason for the case.\nThe lawsuit originally mentioned a 6bn USD figure for compensation and Google was willing to pay 100M USD\nto settle… This was like most lawsuits are about money.\nIts not necessarily bad to sue about money but this clearly cost more than it should have for both sides as\nit hurt Java in the market and that hurt two of its biggest users (Oracle \u0026amp; Google). Sun used to make\na per device license fee for every J2ME phone sold, that was a huge bucket of money. I think Sun lost\nthat revenue stream because it just neglected to update J2ME for more than a decade and when it finally did it\nwas way too late.\nIs This Good For Java? Yes. Without a question!\nSome claim the lawsuit should have been decisively won by Google, I think that would have been great because\nas stated above I don’t think the copyright clause is good for the industry as a whole. But that ship has sailed\nand now the best thing for Java is ending the hostility and unifying behind one standard Java so its great.\nFurthermore, ending this hostility means Java proved its chops in court which is a huge milestone. Developers\noften have the justify-able backlash when the legal system is involved choosing to go with a technology that’s\nmore open (e.g. WebAssembly). Technologies like that might have hidden elements that can be\nsued over that we aren’t even aware of e.g. just using a GIF file was ground for legal action a few years ago…\nThis is problematic with more open standards as there isn’t a single \u0026ldquo;landlord\u0026rdquo; to carry the technology forward\nin such a court case.\nJava has seen quite a few days in court and one of the nice things about OpenJDK is that it includes a patent\nlicense provision. This is rare and really valuable, if Google and Oracle settle over OpenJDK it pretty much means\nwe can all align behind it peacefully and litigation would become far less likely.\nFurthermore, I think this would be great for Android as it will eventually move to a newer more modern version\nof Java and might enjoy better tooling as a result. It would also mean that some optimizations that might have\nbeen avoided by Android’s Runtime due to potential patent litigation might be applied to ART leading to\nadditional benefits.\nThe reduced stress among Google developers about IP cleanliness could also boost the productivity at Google\nand allow the Android developers to focus on building a better product.\nWhat About Older Versions of Android? For those we will be able to use something like retrolambda like we do in Codename One.\nHow Will This Affect Codename One? Right now we tried to avoid OpenJDK code as much as possible with the same basic thought pattern Google\ntook of using a clean room implementation to protect ourselves from future IP claims.\nWe are following this closely, if this happens we’ll align ourselves to be compliant with CLDC 8 which is\na valid Java 8 subset. This shouldn’t require much works as we are already 50% there and\nParparVM\netc. should be trivial to move to that level of compliance.\nThis would hopefully give us a path to move forward in a way that would keep everyone happy.\nSummary This is great news for all Java developers everywhere!\nWhether you work on Android, server, mobile or desktop!\nThis could be the start of the long anticipated \u0026ldquo;peace process\u0026rdquo; or at least a ceasefire between Google \u0026amp; Oracle.\nThis could allow us all to align behind one Java version eventually (taking into consideration the slow Android\nupdate process). It could help bring Java back into vogue with some developers who considered the closed\nnature of Java problematic. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nLuix — December 30, 2015 at 2:26 pm (permalink) Luix says:\nRe: \u0026ldquo;is it good for Java?\u0026rdquo; The main issue here is Java isn’t good enough for anyone. Most of the apps running in that resource hog are chucks of code blindly stolen from previous apps/programs. Most of the developers just steal the code and mend it to perform more or less decently, and when that’s not enough, they just simply demand more hardware.\nI don’t mean to start a flame war, but IMHO Google should ditch the Java approach all together and find a better replacement.\nShai Almog — December 30, 2015 at 2:31 pm (permalink) Shai Almog says:\nYou don’t mean to start a flame war but you post a \u0026ldquo;Java sux\u0026rdquo; comment in a Java blog. And with a Darth Vader avatar no less 😉\nCopy and paste == code reuse. Bad programmers exist everywhere. Java is actually pretty efficient (e.g. embedded etc.) and performant when compared to pretty much all alternatives.\nGoogle analyzed the options before picking Java, there are no realistic alternatives for Java and none are better performing.\nLuix — December 30, 2015 at 2:44 pm (permalink) Luix says:\nAn excellent answer. I apologize, English isn’t my main language. Java was the best alternative when Android started walking its first steps, but then again, a lot of water has gone below that bridge.\nAs a SysAdmin I deal with poorly written Java code all the time (i.e. the developers simply complain about their code running slow on expensive hardware because they don’t have enough resources). I’d like to see a path to better resource usage rather than expecting the system to grow in size. That’s just an unrealistic approach. I reckon it’s Google’s fault for not steering the development in that direction, but then again, Java might be the de facto standard, but it doesn’t mean it couldn’t be improved.\nShai Almog — December 30, 2015 at 2:53 pm (permalink) Shai Almog says:\nWe discussed this a bit in the hacker news thread. One of the problems with Java on the server/desktop is the lack of MVM (or isolates as they are called today) which allows multiple Java instances to share more state and thus take up less RAM/CPU. Back in the day this wasn’t a priority for Sun as it was selling big iron hardware and it would just mean \u0026ldquo;buy more hardware\u0026rdquo;.\nI totally see the issues you are running against, some Java apps are just ridiculous and its often hard for us to gauge what the hell is needed in terms of resources. One annoyance I had with servers was that the Xmx switch for the JVM to indicate the maximum memory has no value for the admin. It only allocates the memory visible to the Java application but not the memory I need to give to the server. So if I use -Xmx2gb the app might take up 2.5gb because of various VM overhead issues. This makes it pretty painful, but that’s an implementation problem more than an inherent issue in the Java language.\nLuix — December 30, 2015 at 3:01 pm (permalink) Luix says:\nAgain, I appreciate the time you took to make me a little less ignorant.\nLike you said, a language isn’t inherently bad or good, it’s the use we give to it what draws a positive/negative value.\nAnyway, I salute the step Google took to a open source implementation, and agree with you in your considerations about what that means in terms of growth for the community and the language itself. I just hope Google would tighten the development guidelines the way they did with the visual ones with Material Design.\nAll I have left are my best wishes for the upcoming new year.\nbryan — January 2, 2016 at 10:10 pm (permalink) bryan says:\nWhat you said makes no sense at all. Java the language is fine (unless your preference is functional languages), and the JVM (which as Shai has noted is NOT what Google use) works just fine also. Back in the day almost all feature phones had Java baked in, and given the hardware constraints, Java apps worked remarkably well (and worked even better with LWUIT – thanks Shai/Chen), so to say Java is intrinsically slow or a resource hog is nonsense.\nAdam — January 6, 2016 at 7:19 pm (permalink) Adam says:\n\u0026ldquo;While Hotspot will probably beat ART for anything other than startup time performance on mobile is quite different than desktop performance. Battery life is more crucial than speed and I doubt hotspot is optimized for that.\u0026rdquo;\nAre these really competing goals? Something that executes in fewer CPU cycles will result in longer battery life. AOT is always better than JIT for most things (unless they can only be known at runtime), but as far as a JIT engine goes, faster is better for everybody.\nShai Almog — January 6, 2016 at 7:30 pm (permalink) Shai Almog says:\nNot quite so simple… we have two cases:\na. Really complex calculations that take up 100% of the CPU. JIT has the advantage of determining all the branches that never change and optimizing them away. Inlining methods more aggressively etc.\nb. Most apps – cpu is needed for very short bursts and idle afterwards. JIT has plenty of CPU cycles left to optimize the short bursts to be much faster/smaller. On mobile devices this is good since it makes better use of CPU caches.\nAOT will always be slower than a good JIT since it has no way of optimizing away a branch statement that never changes. These are really expensive. Virtual method inlining (which leads to cross method optimizations) is also a HUGE benefit.\nReducing battery usage is a different deal though and memory constraints on the device are also different. A jit can over optimize and regress. It can choose to use IDLE CPU to do various tasks which when optimized for power consumption it won’t. At Sun we had several very different JIT implementations, the mobile JIT’s had a far simpler architecture than hotspot. You even see this in the two modes hotspot features (server \u0026amp; client).\nAnyway, I digress. Its a bit more complex than that.\nAdam — January 6, 2016 at 7:46 pm (permalink) Adam says:\nYes, a lot of that fits into my \u0026ldquo;unless they can only be known at runtime\u0026rdquo; parenthetical there, and I agree, there are limits to ahead of time compilation where a JIT can do much better.\nThat being said, what on earth would the JIT be doing that is consuming otherwise idle CPU cycles that aren’t otherwise necessary tasks? Overly aggressive garbage collection? Maybe I’m only looking at this from an application level lens when I should be viewing from a virtual machine lens.\nShai Almog — January 6, 2016 at 7:55 pm (permalink) Shai Almog says:\nThink of a JIT as a profiler that runs on your device in your users hands.\nThe profiler ran while the user used the application, since every user uses the app differently the JIT has an option to optimize based on how the user worked and idle is the perfect time to do it.\nHotspot will further optimize but needs to decide when to stop and also when to revert an optimization that didn’t generate the right results (optimizations aren’t always clean cut).\nMobile JIT’s aren’t as aggressive but they do something weird. They GC jitted code. E.g. if RAM is low or if a piece of code was used a few times and then no longer called then wasting RAM on compiled code is redundant.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/analysis-google-moving-to-openjdk-what-that-really-means/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/analysis-google-moving-to-openjdk-what-that-really-means/dukeandroid.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been following the news breaking since yesterday as\u003cbr\u003e\n\u003ca href=\"https://news.ycombinator.com/item?id=10803775\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ea hacker news post\u003c/a\u003e\u003cbr\u003e\nhighlighted that an Android commit included OpenJDK files. This is amazing news and a huge step forward\u003cbr\u003e\nfor Java, its still unclear if this is just another move or the inkling of a settlement between Google and\u003cbr\u003e\nOracle but I’m very hopeful that this is indeed a settlement. So far Google wouldn’t comment on the\u003cbr\u003e\ncourt case and \u003ca href=\"http://venturebeat.com/2015/12/29/google-confirms-next-android-version-wont-use-oracles-proprietary-java-apis/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nwhether it was settled since its still ongoing.\u003c/a\u003e\u003cbr\u003e\n\u003cstrong\u003eDisclaimer:\u003c/strong\u003e I worked at Sun/Oracle but had no internal knowledge of any of the things\u003cbr\u003e\ndiscussed here. The information here is collected from public sources, my understanding of the mentality of\u003cbr\u003e\nsaid companies \u0026amp; from our following the case at \u003ca href=\"/\"\u003eCodename One\u003c/a\u003e (we consulted IP lawyers quite a bit\u003cbr\u003e\nwhen we started and this case was always on our mind).\u003c/p\u003e","title":"Analysis: Google Moving to OpenJDK, What That Really Means"},{"content":"\nWe released a new version of the introducing Codename One video almost a month ago but we just neglected\nto highlight it in the blog. Our old videos are pretty dated by now and we use far better toolchains for video production\ntoday, so we are in the process of redoing all our old videos. This is a long and tedious process that we do\nwhile producing newer content, fixes and moving forward. So the timeline of such updates is quite volatile.\nCheck out the new video below.\nGradle \u0026amp; Keyboard Default Switch We just flipped the switch on two major changes in the Android build. All Android builds from now on will\ndefault to gradle instead of Ant. This is far superior to Ant builds as its the way forward for Google and it\nallows you to open the resulting project in Android studio.\nWe are flipping this switch to test this functionality before 3.3 rolls out. If this triggers issues for you please\nreport it at once, you can also disable it manually using the build hint android.gradle=false.\nThe new Android input mode is pretty different to the previous keyboard input mode, it should bring Android\nmore in line with the iOS port and modernize the UI quite a bit. This might introduce some incompatibilities\nor issues, be sure to report them!\nYou can manually disable this build hint using the android.keyboardOpen=false build hint.\nBarcode/QR Code Deprecation When we originally launched the barcode/qrcode API’s we didn’t yet have cn1libs so we just added this to the\nAPI core. Now that cn1libs have been around for ages and also used to implement\nanother barcode/QR code scanner API\nwe think its time to deprecate the API and move it into a separate cn1lib here:\nhttps://github.com/codenameone/cn1-codescan.\nAfter 3.3 we will remove this API for good from the core and you will need to migrate to the cn1lib (which should\nbe pretty trivial). The reasoning is actually rather simple besides slightly faster link times…\nThis API requires a binary native library that has been a thorn in our side every time Apple changed something\ne.g. bitcode support, x64 etc. Every such change would have been seamless and instant were it not for this\nlibrary. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\ndavidwaf — December 29, 2015 at 7:59 pm (permalink) davidwaf says:\nJust an observation: with the switch to gradle, i notice when using native android libraries, you now only accept bundling them as aar and no longer andlib, and merging of android manifests is switched on by default. Which is good. I ran into a small build error because my native lib had declared permisions:\nand merging fails. It fails on duplicate entries in resultant manifest file. It seems the CN1 build system also generates these permissions. Also i had to remove\nandroid_icon=\u0026quot;@drawable/ic_launcher\u0026quot;\nandroid_label=\u0026quot;@string/app_name\u0026quot;\nattributes from application tag from my native library manifest, since they conflicted during merge (I assume the CN1 build system generates these too, so the merge fails).\nAny way, these were small changes i had to make, after which my builds started working as usual again.\nShai Almog — December 30, 2015 at 3:48 am (permalink) Shai Almog says:\nThanks for the headsup! That’s exactly why we turned on the default now instead of waiting for 3.3.\nWe wanted to iron out the kinks.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/video-new-defaults-barcode-qrcode-changes/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/video-new-defaults-barcode-qrcode-changes/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe released a new version of the introducing Codename One video almost a month ago but we just neglected\u003cbr\u003e\nto highlight it in the blog. Our old videos are pretty dated by now and we use far better toolchains for video production\u003cbr\u003e\ntoday, so we are in the process of redoing all our old videos. This is a long and tedious process that we do\u003cbr\u003e\nwhile producing newer content, fixes and moving forward. So the timeline of such updates is quite volatile.\u003cbr\u003e\nCheck out the new video below.\u003c/p\u003e","title":"Video, New Defaults \u0026 BarCode/QRCode Changes"},{"content":"\nHistorically, we didn’t use Androids profiling tools often. They were pretty awful and the only tools that we really\nused extensively were the on-device GPU profiling tools which were reasonably good. In recent years Android’s\nnative story improved by leaps and bounds with the introduction of Android Studio and 3rd party tools developing\nnative Android apps has improved a lot. But the CPU profiling tools are still stuck in the stone age and this is\nin stark contrast to the iOS tooling.\n__\niOS Profiler Better looking and more functional\niOS Profiler Better looking and more functional\n__\nAndroid Profiler Both unattractive and disfunctional\nAndroid Profiler Both unattractive and disfunctional\n__\nNetBeans Profiler Java Profiles can be great e.g. NetBeans\nNetBeans Profiler Java Profiles can be great e.g. NetBeans\nThe really painful aspect here is that Java has amazing profilers, we use them for Codename One on the desktop\nand they deliver! E.g. check out the great NetBeans profiler pictured above.\nThe most depressing thing about this as an ex-Sun Java guy is that Apple implemented its amazing profiler using\nD-trace!\nFor the uninitiated D-trace is a technology developed by Sun for instrumenting OS processes without overhead.\nIt works amazingly well and has no noticeable performance penalty while providing amazing insight into running\nnative/Java applications. If only Google/Oracle could patch things up maybe Android would be able to use something\nlike that and some of the standard desktop profiling tools.\nOne of the things I learned over the years from profiling on all of these platforms is that performance is very\nportable. We use the NetBeans profiler 99% of the time and even when a problem isn’t felt on the desktop\nit can be seen in the profiler. There are special cases such as gradients being slower on Android than they\nare on the desktop, but overall performance is just 99% caching and eliminating calls. Just find the code that\nhappens a lot and make it happen less frequently.\nOn The Subject of Performance Christmas is the time for deploying risky changes?\nWell, that’s how we see it. Most of you guys will be on vacation and we’ll deploy some performance tuning\nupdates to squeeze additional smoothness out of Codename One. There were many things we discovered and\nimproved during our latest bout of profiling and I think we have the performance at a much nicer level than\nit was a couple of weeks ago.\nThere are many changes to the handling of images, labels, fonts and more but most of them should be\ncompletely seamless to all of you. Your app should just \u0026ldquo;feel smoother\u0026rdquo; with literally no code changes.\nHowever, there are some tips and behaviors that you guys need to be aware of…\nComponent Paint Override When overriding paint within Component we could sometimes rely on the color or other Graphics object\nsettings being consistent between device and simulator. The new Android pipeline shifts some logic into\nthe native rendering thread which means that code like this might behave oddly:\nLabel l = new Label(\u0026quot;Label\u0026quot;) { public void paint(Graphics g) { super.paint(g); g.drawLine(getX(), getY(), getX() + getWidth(), getY() + getHeight()); } }; Prior to this change \u0026ldquo;Label\u0026rdquo; and the line that would have been drawn on top of it would have been in the same\ncolor. With this change the paint code might occur on the Android native layer and so the color of the graphics\nmight not be set when we reach the drawLine method call. This is a bug in the code above that\nshould never assume the color of the graphics context in advance.\nEasier Optimizations We always said that you should use images wherever possible, they are very performant but I’d like to refine\nsome of those cases. A lot of our optimizations both on iOS and Android revolved around moving the Label\ndrawing into the native layer, so drawing a label should be really fast…\nBut there are some edge cases that we just can’t handle in the native layer, e.g. if the icon for the label isn’t\na native image then we need to fallback to the slightly slower rendering code. So if you used:\nTimeline (gif animation), FontImage, IndexedImage or\nRGBImage your performance won’t be as great.\nYou don’t need to discard code that uses any of those but if you want to create a list with thousands of components\nyou might want to avoid them within that list. The latter 3 also provide a way to convert them into a regular image,\nthis allows you to still use something useful like FontImage or RGBImage without\nthe performance penalty in a large list.\nIf you don’t need the \u0026ldquo;ends with 3 points\u0026rdquo; functionality I would highly recommend you disable it. In large lists\nit effectively initiates some string operations in some of the most performance crucial areas of the code.\nYou can disable this globally using the theme constant endsWith3PointsBool=false, as part of\nthis change we changed the default to false.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/the-sad-state-of-android-performance-tooling/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/the-sad-state-of-android-performance-tooling/profiling-in-android-ios.png\"\u003e\u003c/p\u003e\n\u003cp\u003eHistorically, we didn’t use Androids profiling tools often. They were pretty awful and the only tools that we really\u003cbr\u003e\nused extensively were the on-device GPU profiling tools which were reasonably good. In recent years Android’s\u003cbr\u003e\nnative story improved by leaps and bounds with the introduction of Android Studio and 3rd party tools developing\u003cbr\u003e\nnative Android apps has improved a lot. But the CPU profiling tools are still stuck in the stone age and this is\u003cbr\u003e\nin stark contrast to the iOS tooling.\u003c/p\u003e","title":"The Sad State of Android Performance Tooling"},{"content":"\nSteve has implemented one of our long time RFE’s: Async editing in Android. This effectively means that the\nAndroid keyboard will behave as it does in iOS and won’t fold/open as you move between text fields. It will\nalso remain open as you scroll the screen and won’t resize the UI as it opens!\nAs you can imagine this is a huge change so it is currently off by default but we will flip the change sometime\nnext week to be the default.\nTo toggle this option use the build hint android.keyboardOpen which can be true to enable this\nor false to disable this. This is a big change so keep your eyes open to regressions and\nreport them ASAP.\nPerformance Overhaul We used to always laugh at the Android team for whining over how difficult it is to optimize Android for devices with\n\u0026ldquo;only\u0026rdquo; 64mb of RAM. We can work on devices that have 2mb of RAM and leave room to spare!\nThe performance of Codename One has always been exceptional in this regard because we just didn’t have a choice\nwhen running on feature phones. This was pretty true for quite a while but with recent changes to the underlying\nimplementation of Android basic things that were quite performant became slow so we had to replace the pipeline.\nAndroid itself finally invested some effort in performance with their \u0026ldquo;project butter\u0026rdquo; and as a result the level of\nsmoothness on newer Android devices is spectacular. Unfortunately, we haven’t kept up with that. Worse our\nscrolling behavior was something we designed at Sun based on guesses of how the iPhone scrolling acts. These\nguesses weren’t as good as some of the newer attempts in this field.\nWe are attacking this in several ways. Steve wrote a completely new scrollng motion model that feels more native\nand is based on some studies of these algorithms done over the past 8 years. It feels much better than the previous\nfriction motion and is currently on by default for all new builds and the new version of the simulator. If you\nstill want the old version to work you can still access that using the theme constant ScrollMotion=Friction.\nWe also worked on the performance of Codename One itself, especially for very large data sets e.g. a\nscrollable Y Container with a BoxLayout.Y_AXIS that includes many containers\nwith labels/images (5,000 was the common test case). We shifted around many method calls and its now pretty\nsmooth to scroll such a UI on relatively old Android/iOS devices. But on the older devices its still not perfect so\nwe’d like to make this completely smooth even there!\nWe’re still working on a major refactoring here and two of the victims are DefaultLookAndFeel \u0026amp;amp LookAndFeel.\nBoth of these classes had larger roles to play in LWUIT but as we moved to Codename One and matured the\ntheme system they became mostly redundant. Unfortunately, they contain a lot of functionality some of which\nwe intend to keep.\nWe decided to to deprecate both of these classes to get started in this long term migration. However, some\ncomplex functionality such as deriving and overriding these classes will no longer work in upcoming builds!\nThe reason for this is simple, we are moving a lot of the paint work into the core OS porting layer which will allow us\nto optimize that functionality using native capabilities that aren’t available in the Codename One abstraction layer.\nE.g. at this time we are working on rewriting the label/button rendering code in C which should make it as performant\nas native OS code.\nVersion 3.3 We passed the middle of the road sign for 3.3 which should come out on January 27th. So far we are very pleased\nwith the rapid release roadmap and we think it really helped tightening the quality and reliability of Codename One.\nIt also made versioned builds into a far more viable feature than it was prior to 3.1!\nWith this in mind we’ll continue the 3 month release schedule, tentatively this is what we are thinking about for 2016\nreleases:\n3.3 – January 27th 3.4 – May 3rd 3.5 – August 2nd 3.6 – December 5th All of those are still subject to change both in dates and numbering scheme e.g. we might decide that version\n4 is warranted for a particularly exceptional release.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/smooth-scrolling-async-android-editing-3-3/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/smooth-scrolling-async-android-editing-3-3/3.3-coming-soon.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSteve has implemented one of our long time RFE’s: Async editing in Android. This effectively means that the\u003cbr\u003e\nAndroid keyboard will behave as it does in iOS and won’t fold/open as you move between text fields. It will\u003cbr\u003e\nalso remain open as you scroll the screen and won’t resize the UI as it opens!\u003cbr\u003e\nAs you can imagine this is a huge change so it is currently off by default but we will flip the change sometime\u003cbr\u003e\nnext week to be the default.\u003c/p\u003e","title":"Smooth Scrolling, Async Android Editing \u0026 3.3"},{"content":"\nWe committed a major somewhat revolutionary change to how layout animations and the basic component tree\nwork in Codename One. This is important to understand since it changes the very nature of how we expect\ncomponents to behave in Codename One. This also allows us to create some pretty spectacular effects\nsuch as the ones in the title above.\nThere are several types of animations in Codename One:\nForm/Dialog transitions Replace transitions Layout animations Low level animations Transitions and low level animations are both special cases that aren’t affected by this change. However, replace transitions\nand layout animations have been effectively rewritten to use the new AnimationManger class.\nThe AnimationManger class allows executing a component animation synchronously or\nasynchronously and starting with current builds all replace/layout animations (e.g. Container.replace,\nContainer.animateLayout etc.) delegate their work to this class.\nBroken Compatibility This is important since some compatibility is broken as a result of this change!\nOne of the core problems with the old animation framework was that you can’t have to animations going on\nat once e.g. if you did something like this:\nmyContainer.add(new Button(\u0026quot;Button\u0026quot;)).animateLayout(300); This code could fail if you invoke it twice concurrently since there would be two animations mutating the\ncontainer at the same time and they would not work in sequence!\nA lot of developers assumed incorrectly that this code would fix this problem:\nmyContainer.add(new Button(\u0026quot;Button\u0026quot;)).animateLayoutAndWait(300); Since the AndWait methods block the EDT they assume no other addition can happen during this time\nbut the AndWait method doesn’t block event dispatch so if a user triggers an event that triggers this code\nit could still fail. The workaround we often suggested was something like this:\nif(!locked) { locked = true; myContainer.add(new Button(\u0026quot;Button\u0026quot;)).animateLayoutAndWait(300); locked = false; } else { // postpone animation/addition } While this works it makes generic code difficult and has the side effect of only being aware of a specific change.\nSo as part of this change we changed the very way add/remove component work in Codename One!\nIf you add a component and there is no animation it will work like it always did. However, if you add a component and\nthere is an animation in progress the addition will be delayed to the end of the animation!\nThat might not produce the result you want but it will leave you with a valid UI and unlike some of the cases\nabove it is unlikely to crash your application, which is probably the most important thing.\nEnhancements We didn’t just do this to fix bugs though, we are looking at integrating some of the cool special effects you can\nsee here:\nThis animation is a combination of a new ability to step thru animation stages when scrolling with a new\n\u0026ldquo;style animation\u0026rdquo; that accepts a destination UIID for a Component and morphs from the source style to the\ndestination UIID. This specific demo includes this code:\nForm hi = new Form(\u0026quot;Shai's Social App\u0026quot;, new BoxLayout(BoxLayout.Y_AXIS)); for(int iter = 0 ; iter \u0026lt; 100 ; iter++) { hi.add(new Label(\u0026quot;Social Data Goes here...\u0026quot;)); } Toolbar tb = new Toolbar(); hi.setToolbar(tb); ComponentAnimation cna = tb.createStyleAnimation(\u0026quot;TitleAreaClean\u0026quot;, 200); ComponentAnimation title = tb.getTitleComponent().createStyleAnimation(\u0026quot;TitleClean\u0026quot;, 200); hi.getAnimationManager().onTitleScrollAnimation(cna, title); hi.show(); The styling for both the source title with my picture and the destination clean styles are defined in the theme but\nyou can also define the source style in code. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDiamond — February 19, 2016 at 9:12 am (permalink) Diamond says:\nHi Shai,\nWhere can I get the full source for this new animation manager demo please? Where is the image placed, at the contentPane or TitleArea using Toolbar?\nShai Almog — February 19, 2016 at 12:11 pm (permalink) Shai Almog says:\nHi Diamond,\nwe haven’t made it into a full fledged demo but I did add a shorter standalone section on this into the Toolbar javadocs and the developer guide: https://www.codenameone.com…\nMac Flanegan — March 2, 2017 at 4:53 pm (permalink) Mac Flanegan says:\nHi Shai,\nI am trying to implement this feature.\nBut the overflowbutton (Rigth command) and title are vertically centered.\nIs it possible to align the overflowbutton and title at the top?\nEdit: I tryed to use constant menuButtonTopBool but no success.\nMac Flanegan — March 2, 2017 at 5:12 pm (permalink) Mac Flanegan says:\nPlease, ignore…\nI have achieved the desired result using the ToolBar directly and not titleComponent …\nfrom\nStyle stitle = home.getToolbar().getTitleComponent().getUnselectedStyle();\nto\nStyle stitle = home.getToolbar().getUnselectedStyle();\nstitle.setPaddingBottom(20);\nShai Almog — March 3, 2017 at 8:03 am (permalink) Shai Almog says:\nOne of the approaches I took in one of my demos was to hide the side menu icon using the theme constant and then add a Command to the toolbar where I wanted it to be. The command just called the open side menu method of the toolbar.\nMac Flanegan — March 3, 2017 at 7:06 pm (permalink) Mac Flanegan says:\nHi Shai, thanks for reply.\nAny hints on how to gradually hide a component/container whith this method?\nI’m trying to create an interface similar to native android applications, like the YouTube App where the title is hidden with Scroll up.\nShai Almog — March 4, 2017 at 10:13 am (permalink) Shai Almog says:\nI think the flickr demo might have something like this that uses the hide toolbar feature\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-animation-manager/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-animation-manager/title-area-animation.gif\"\u003e\u003c/p\u003e\n\u003cp\u003eWe committed a major somewhat revolutionary change to how layout animations and the basic component tree\u003cbr\u003e\nwork in Codename One. This is important to understand since it changes the very nature of how we expect\u003cbr\u003e\ncomponents to behave in Codename One. This also allows us to create some pretty spectacular effects\u003cbr\u003e\nsuch as the ones in the title above.\u003c/p\u003e\n\u003cp\u003eThere are several types of animations in Codename One:\u003c/p\u003e","title":"New Animation Manager"},{"content":"\nWe wrote quite a bit about the architecture of the new VM we built for iOS and why we built it. Up until recently\nwe always viewed it as a Codename One specific tool. Something that would only be useful for us. We used open\nsource because \u0026ldquo;that is our way\u0026rdquo; and didn’t give it much thought after that.\nIt started to dawn on us recently that this tool could be useful for other developers that might take it in a different\ndirection from our original intention. We also came to the conclusion that this might not be a bad idea altogether.\nSo we are are effectively launching the Codename One VM as\nParparVM\nand it includes a lot of interesting benefits.\nTo avoid confusion and complex support overhead we always indicated that we don’t provide support for building\nCodename One natively. This made sense back in the\nday when our main support channels were email \u0026amp; the discussion forum. However, now that we are\nfocusing support around StackOverflow this shouldn’t be as much of a barrier since it won’t increase\nthe \u0026ldquo;noise\u0026rdquo;. We can’t guarantee an answer for every question as these things might step out of our\ncomfort zone, but we’ll try to do our best as usual. So feel free to ask questions about the VM and native\ncompilation on stackoverflow with the \u0026ldquo;codenameone\u0026rdquo; tag.\nGetting Started The source is available\nhere,\nThe ByteCodeTranslator and JavaAPI projects are designed as a NetBeans project although it should be\npossible to work with any Java IDE or ant directly. It requires asm 5.0.3 which you can find in the\ncn1-binaries project.\nYou can run the translation process using:\njava -jar ByteCodeTranslator.jar ios path_to_stub_class:path_to/vm/JavaAPI/build/classes;path_to_your_classes dest_build_dir MainClassName com.package.name \u0026quot;Title For Project\u0026quot; \u0026quot;1.0\u0026quot; ios none Once the translation process succeeds you should have a valid xcode project that you can run and use as\nusual. You will need a Mac for this to work.\nThe main class name is expected to have a public static void main(String[]) method and it is\nassumed to reside in the com.package.name directory (figuratively, you need to replace\ncom.package.name with your actual package passed to the translator).\nWhy Another VM for iOS? It seems like there are a lot of open source iOS Java VM’s in the field but the reality is that most of them are either\nproprietary or rely on a path that is very risky.\nBy translating bytecode to C source code ParparVM is effectively the only VM that we are aware of, that uses\na 100% supported by Apple approach for Java compatibility. The closest 2nd place would be J2ObjC from\nGoogle but it isn’t intended as a full VM and actually fills a very different roll from ParparVM.\nXMLVM’s C backend had a similar architecture but the project is no longer actively maintained.\nAll other Java VM’s for iOS that are actively maintained use approaches that Apple doesn’t officially support\nsuch as LLVM code or ARM code. This makes these solutions very fragile to changes made by Apple. E.g.\nthis quote:\nOur work to add full support for iOS 9 in time for its public release was one of the most daunting challenges we’ve faced in our existence\nHenric Müller\nBy contrast ParparVM required no code changes to support iOS 9, 64 bit, bitcode or other changes made by\nApple.\nThe core work for ParparVM took us about a month and the VM is trivial by comparison. Trivial in this sense\nis also good, as it means even novices can extend and enhance the VM further without serious compiler\nengineering background.\nTaking Action Check out the ParparVM\npage in the Codename One project, star/fork it and start playing around with it.\nLet us know what you think and how we can improve the VM’s reach/feature set in the comments below.\nWe think we can add a lot of features to the VM as conditional options and thus keep things that\nCodename One doesn’t need as a 3rd party extension that can be turned on at will.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/parparvm-spreads-its-wings/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/parparvm-spreads-its-wings/parparvm-blog.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe wrote quite a bit about the architecture of the new VM we built for iOS and why we built it. Up until recently\u003cbr\u003e\nwe always viewed it as a Codename One specific tool. Something that would only be useful for us. We used open\u003cbr\u003e\nsource because \u0026ldquo;that is our way\u0026rdquo; and didn’t give it much thought after that.\u003cbr\u003e\nIt started to dawn on us recently that this tool could be useful for other developers that might take it in a different\u003cbr\u003e\ndirection from our original intention. We also came to the conclusion that this might not be a bad idea altogether.\u003cbr\u003e\nSo we are are effectively launching the Codename One VM as\u003cbr\u003e\n\u003ca href=\"https://github.com/codenameone/CodenameOne/tree/master/vm\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eParparVM\u003c/a\u003e\u003cbr\u003e\nand it includes a lot of interesting benefits.\u003c/p\u003e","title":"ParparVM Spreads Its Wings"},{"content":"\nUPDATE August 10, 2018 – The steps described in this article are out of date. The Codename One project now includes an ANT script that will retrieve dependencies and build the project automatically. See the Quick Start section of the README for instructions.\nI’ve written open source software since the 90’s both for my own projects and for Sun Microsystems. When we\nfounded Codename One open source was the only option!\nWe didn’t choose open source with\nthe goal of receiving code contributions. Contributions are pretty rare even in highly visible projects. We saw\nthe true benefits of open source for a project like Codename One: trust.\nWhen you choose a platform for your code you need to trust that it will be there tomorrow \u0026amp; open source\nalleviates some of this risk. Open source keeps us honest about our cloud pricing.\nE.g. if we overcharge or provide shoddy service a fork might gain traction. This is a benefit to the consumer\nthat helps us in forming trust and gaining traction in the long run.\nI felt the need to write this opening paragraph due to a highly visible source code closing done by another\ncompany. We have no intentions, plans, thoughts or wavers in that direction. Furthermore, we consider\ncontributions to be the least important benefits of Open Source Software.\nCodename One is \u0026ldquo;more\u0026rdquo; open source than most projects, e.g. OpenJDK is OSS but its pretty hard to change\ncode within it. Its even hard to contribute these changes!\nYou can use/change most of our code using a trivial process. You don’t need a complex compiler toolchain\nfor changing or debugging Codename One. Most importantly: 99% of the code is in Java so you should feel\nright at home!\nUsing The Source We already have an old tutorial called \u0026ldquo;use the source\u0026rdquo;\nbut its pretty old by now. It still points at the old SVN and didn’t really go into details, so re-doing that and reminding\nyou that this can be done seems in order.\nWhen you debug your app with our source code you can place breakpoints deep within Codename One and\ngain unique insight. E.g. a Form flickers in your application just place a breakpoint in\nDisplay.setCurrent().\nWhen you run into a bug or a missing feature you can push that feature/fix back to us using a pull request.\nGithub makes that process trivial and in this new video and slides below we show you how.\nThe steps to use the code are:\nSignup for Github Fork\nhttp://github.com/codenameone/CodenameOne and\nhttp://github.com/codenameone/codenameone-skins\n(also star and watch the projects for good measure). Clone the git URL’s from the projects into the IDE using the Team-\u0026gt;Git-\u0026gt;Clone menu option. Notice\nthat you must deselect projects in the IDE for the menu to appear. Download the cn1-binaries project from github here. Unzip the cn1-binaries project and make sure the directory has the name cn1-binaries. Verify that\ncn1-binaries, CodenameOne and codenameone-skins are within the same parent directory. In your own project remove the jars both in the build \u0026amp; run libraries section. Replace the build libraries\nwith the CodenameOne/CodenameOne project. Replace the runtime libraries with the\nCodenameOne/Ports/JavaSEPort project. Update August 10, 2018 – You will need to build the codenameone-skins project using the build.xml file in its root directory in order to generate some skins that are required to build the JavaSE project.\nThis allows you to run the existing Codename One project with our source code and debug into Codename One.\nYou can now also commit, push and send a pull request with the changes.\nVideo – How To Use The Codename One Sources Slides **How To Use The Codename One Sources ** from Shai Almog Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nCh Hjelm — June 19, 2016 at 6:15 am (permalink) Ch Hjelm says:\nHi, this is a great approach and I’ve used debugging of CN1 sources for quite some time. However, the video does not mention if you can build for devices using your own copy of the CN1 sources – is that possible and how should it be done? Thanks\nShai Almog — June 20, 2016 at 4:10 am (permalink) Shai Almog says:\nBuilding for devices is a bit more complicated so we left that as an exercise for the developers…\nThis is actually a really difficult process to document e.g. in Android which is the simpler pipeline we run into issues all the time with Google changing things and having to run around after them. On iOS we gave the start of the process in the VM docs: https://github.com/codename… but it gets pretty hairy from there on.\nWe are looking at offering a better solution for offline building to the enterprise subscription in the near future.\nCh Hjelm — June 20, 2016 at 9:52 pm (permalink) Ch Hjelm says:\nThanks for the answer. I’m not an Enterprise user (and probably never will have the budget). If you can’t build with your modified CN1 sources for a device, then isn’t what you described above useless when developing an app for a device? Unless the changes get accepted back into the code base before having to run it on a device. And you also cannot ‘hack’ the CN1 sources when needed (e.g. I’ve had to make some changes to implement specific functionality which is not likely to be accepted into your code base), making it pretty pointless to spend time trying to work around such limitations. Sorry, if I’m missing something obvious, but I think you should mention these limitations in the material above – it’s pretty frustrating to find out after the fact.\nShai Almog — June 21, 2016 at 3:45 am (permalink) Shai Almog says:\nThe reason we make the enterprise requirement is because the support overhead is so great that it requires extra effort.\nThis is step 1 of building for devices. It’s not impossible and quite a few people did that but making it too simple will cause people to try and go thru this route and running against worse walls when doing that.\nI’d be interested to know what sort of changes can’t be done thru a cn1lib and must go into our core sources?\nAMDP AMDP — March 23, 2017 at 12:00 pm (permalink) AMDP AMDP says:\n\u0026ldquo;Most importantly: 99% of the code is in Java so you should feel right at home!\u0026rdquo;\nJust curious about the 1%. Can you describe what language and why?\nTroy.\nShai Almog — March 24, 2017 at 5:33 am (permalink) Shai Almog says:\nIt’s C, C#, Objective-C \u0026amp; JavaScript. Each port for each OS needs native code to implement the OS abstraction layer. 99% is actually a bit high I should have said 99% of the code that matters.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/how-to-use-the-codename-one-sources/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/how-to-use-the-codename-one-sources/how-to-use-the-codename-one-sources.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eUPDATE August 10, 2018\u003c/strong\u003e – The steps described in this article are out of date. The Codename One project now includes an ANT script that will retrieve dependencies and build the project automatically. \u003ca href=\"https://github.com/codenameone/CodenameOne/#quick-start-1\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eSee the Quick Start section of the README\u003c/a\u003e for instructions.\u003c/p\u003e\n\u003cp\u003eI’ve written open source software since the 90’s both for my own projects and for Sun Microsystems. When we\u003cbr\u003e\nfounded Codename One open source was the only option!\u003cbr\u003e\nWe didn’t choose open source with\u003cbr\u003e\nthe goal of receiving code contributions. Contributions are pretty rare even in highly visible projects. We saw\u003cbr\u003e\nthe true benefits of open source for a project like Codename One: \u003cstrong\u003etrust\u003c/strong\u003e.\u003c/p\u003e","title":"How To Use The Codename One Sources"},{"content":"\nOne of my favorite Pixar movies is Ratatouille, maybe because I’m such a glutton. So when I was thinking\nabout the next tutorial/demo and the idea of a restaurant app came up I knew it had to be based on Ratatouille.\nThis is a relatively simple demo that can literally fit in a single blog post all the way thru and the real cool\nthing about it is that you can try the JavaScript version right now from\nyour browser without compiling anything…\nThe demo shows off how attractive a really simple UI can be with the right font face and a few images/transparency\neffects. This is further emphasized via the nice expansion animation when clicking on an image. We also\ndemonstrate navigation, maps and integration with table ordering systems as part of the demo (haven’t\ntested the latter since its only supposed to work in the states). You can check out the\nfull source code of the\ndemo in github.\nThe Main Class The main class is pretty trivial with mostly boilerplate code:\npublic void start() { if(current != null){ current.show(); return; } new MainUI(theme).show(); } This effectively says that all the logic is in the MainUI class.\nThe Main UI Class This class is slightly larger so we’ll break it down to obvious pieces of code:\npublic MainUI(Resources theme) { super(RESTAURANT_NAME); this.theme = theme; Toolbar t = new Toolbar(); setToolBar(t); t.setScrollOffUponContentPane(true); Label rat = new Label(theme.getImage(\u0026quot;round_logo.png\u0026quot;)); rat.setTextPosition(Label.BOTTOM); rat.setText(RESTAURANT_NAME); rat.setUIID(\u0026quot;SideMenuLogo\u0026quot;); t.addComponentToSideMenu(rat); setLayout(new BorderLayout()); Container dishes = createDishesContainer(); addComponent(BorderLayout.CENTER, dishes); revalidate(); Style iconStyle = UIManager.getInstance().getComponentStyle(\u0026quot;SideCommandIcon\u0026quot;); t.addCommandToSideMenu(new Command(\u0026quot;Menu\u0026quot;, FontImage.create(\u0026quot; ue93f \u0026quot;, iconStyle)) { @Override public void actionPerformed(ActionEvent evt) { showDishesContainer(); } }); if(INCLUDE_RESERVATIONS) { t.addCommandToSideMenu(new Command(\u0026quot;Reservation\u0026quot;, FontImage.create(\u0026quot; ue838 \u0026quot;, iconStyle)) { @Override public void actionPerformed(ActionEvent evt) { Display.getInstance().execute(\u0026quot;reserve://opentable.com/\u0026quot; + OPEN_TABLE_RESERVATION_ID + \u0026quot;?partySize=2\u0026quot;); } }); } t.addCommandToSideMenu(new Command(\u0026quot;Find Us\u0026quot;, FontImage.create(\u0026quot; ue8d5 \u0026quot;, iconStyle)) { @Override public void actionPerformed(ActionEvent evt) { showMap(); } }); t.addCommandToSideMenu(new Command(\u0026quot;Contact Us\u0026quot;, FontImage.create(\u0026quot; ue86b \u0026quot;, iconStyle)) { @Override public void actionPerformed(ActionEvent evt) { showContactUs(); } }); t.addCommandToSideMenu(new Command(\u0026quot;Navigate\u0026quot;, FontImage.create(\u0026quot; ue85b \u0026quot;, iconStyle)) { @Override public void actionPerformed(ActionEvent evt) { Display.getInstance().openNativeNavigationApp(RESTAURANT_LATITUDE, RESTAURANT_LONGITUDE); } }); } That’s pretty much the whole application. You’ll notice that commands are added to the side menu with icon\nfonts, that demo predated our new Material design icons and new native fonts so it uses neither. Newer\ncode would be smaller and simpler.\nThe \u0026ldquo;rat\u0026rdquo; label above shows the rounded version of the logo on the side menu that slides out as such:\nThe main UI itself is implemented in the createDishesContainer call:\nprivate Container createDishesContainer() { Container cnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); cnt.setScrollableY(true); // allows elements to slide into view for(Dish d : DISHES) { Component dish = createDishComponent(d); cnt.addComponent(dish); } return cnt; } private Container createDishComponent(Dish d) { Image img = theme.getImage(d.getImageName()); Container mb = new Container(new BorderLayout()); mb.getUnselectedStyle().setBgImage(img); mb.getSelectedStyle().setBgImage(img); mb.getPressedStyle().setBgImage(img); mb.getUnselectedStyle().setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); mb.getSelectedStyle().setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); mb.getPressedStyle().setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); Container box = new Container(new BoxLayout(BoxLayout.Y_AXIS)); Button title = new Button(d.getDishName()); title.setUIID(\u0026quot;DishTitle\u0026quot;); Label highlights = new Label(d.getHighlights()); TextArea details = new TextArea(d.getFullDescription()); details.setUIID(\u0026quot;DishBody\u0026quot;); highlights.setUIID(\u0026quot;DishBody\u0026quot;); Label price = new Label(d.getPrice()); price.setUIID(\u0026quot;DishPrice\u0026quot;); box.addComponent(title); box.addComponent(highlights); Container boxAndPrice = new Container(new BorderLayout()); boxAndPrice.addComponent(BorderLayout.CENTER, box); boxAndPrice.addComponent(BorderLayout.EAST, price); mb.addComponent(BorderLayout.SOUTH, boxAndPrice); mb.setLeadComponent(title); title.addActionListener((e) -\u0026gt; { if(highlights.getParent() != null) { box.removeComponent(highlights); box.addComponent(details); } else { box.removeComponent(details); box.addComponent(highlights); } mb.getParent().animateLayout(300); }); return mb; } Here we just loop and create individual dish objects then create the expand/contract effect. This is done by\nadding/removing the details component and invoking the animateLayout method. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJaanus Hansen — December 2, 2015 at 8:50 pm (permalink) Jaanus Hansen says:\nWell, I suggest to remove the JavaScript demo. It is not performing well on my Android LG G2, I am afraid, that it makes a wrong impression, that CN1 is very slow and sometimes even buggy. I think, that you should use for demos Android and iOS apps, where CN1 works very well.\nbryan — December 2, 2015 at 10:36 pm (permalink) bryan says:\nJavascript demo doesn’t work on FF 42.0 (Linux 3.13.0-71-generic #114-Ubuntu SMP Tue Dec 1 02:34:22 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux). The rat icon displays then screen goes blank.\nShai Almog — December 3, 2015 at 3:31 am (permalink) Shai Almog says:\nI’m testing on firefox (prefer it over chrome). It works for me on a Mac. There is a blank screen between the rat image and the full initialization of the UI but it should be there only for a couple of seconds, can you try reloading?\nIs your connection very slow?\nThe app effectively runs locally so all data and resources are fetched before it runs.\nShai Almog — December 3, 2015 at 3:36 am (permalink) Shai Almog says:\nI think it shows the drawbacks of JavaScript which is part of the point.\nI wasn’t aiming for people to use it on the device but rather in the desktop to preview the UI.\nNotice we provide an Android APK as well in the demos section but you need external sources etc…\nI ran it on chrome on my oneplus one and it performed reasonably well. Not as fast as the native version but totally acceptable as a fallback option. Expansion is slightly slow the first time around as the images get lazily scaled but once that happens its smooth. The side menu is pretty slow on javascript though.\nbryan — December 3, 2015 at 4:28 am (permalink) bryan says:\nTried reloading – still doesn’t like me. Download speed is 7.26Mbps. Get these errors:\nunreachable code after return statement classes.js:7384:18\nInvalidStateError fontmetrics.js:501:0\n\u0026ldquo;Google Maps API warning: InvalidKey: https://developers.google.c…\u0026rdquo; util.js:30:57\nTypeError: $t is null classes.js:1940:16\nuncaught exception: [object DOMError]\n—————————–\nWorks OK in Chrome, except the location and ordering menu options cause the app to hang as with Android version:\n‘window.webkitStorageInfo’ is deprecated. Please use ‘navigator.webkitTemporaryStorage’ or ‘navigator.webkitPersistentStorage’ instead.\nhttps://www.codenameone.com… Failed to load resource: the server responded with a status of 404 (OK)\nwww.codenameone.com/:1 Failed to decode downloaded font: data:font/truetype;base64,PCFET0NUWVBFIGh0bWw+CjxodG1sIGRpcj0ibHRyIiBsYW5nP…5vdCBGb3VuZCcpOyAgCiAgICAgICAgPC9zY3JpcHQ+CiAgICA8L2JvZHk+CgoKPC9odG1sPg==\nwww.codenameone.com/:1 OTS parsing error: invalid version tag\nmaps.googleapis.com/maps-ap… Google Maps API warning: InvalidKey: https://developers.google.c…\nruntime.js:486 Uncaught TypeError: Cannot read property ‘maxZoom’ of null\nmaps.googleapis.com/maps-ap… Failed to decode downloaded font: data:font/truetype;base64,PCFET0NUWVBFIGh0bWw+CjxodG1sIGRpcj0ibHRyIiBsYW5nP…5vdCBGb3VuZCcpOyAgCiAgICAgICAgPC9zY3JpcHQ+CiAgICA8L2JvZHk+CgoKPC9odG1sPg==\nmaps.googleapis.com/maps-ap… OTS parsing error: invalid version tag\njs:68 Failed to decode downloaded font: data:font/truetype;base64,PCFET0NUWVBFIGh0bWw+CjxodG1sIGRpcj0ibHRyIiBsYW5nP…5vdCBGb3VuZCcpOyAgCiAgICAgICAgPC9zY3JpcHQ+CiAgICA8L2JvZHk+CgoKPC9odG1sPg==\njs:68 OTS parsing error: invalid version tag\nwww.codenameone.com/:1 Failed to decode downloaded font: data:font/truetype;base64,PCFET0NUWVBFIGh0bWw+CjxodG1sIGRpcj0ibHRyIiBsYW5nP…5vdCBGb3VuZCcpOyAgCiAgICAgICAgPC9zY3JpcHQ+CiAgICA8L2JvZHk+CgoKPC9odG1sPg==\nwww.codenameone.com/:1 OTS parsing error: invalid version tag\nwww.codenameone.com/:1 Failed to decode downloaded font: data:font/truetype;base64,PCFET0NUWVBFIGh0bWw+CjxodG1sIGRpcj0ibHRyIiBsYW5nP…5vdCBGb3VuZCcpOyAgCiAgICAgICAgPC9zY3JpcHQ+CiAgICA8L2JvZHk+CgoKPC9odG1sPg==\nwww.codenameone.com/:1 OTS parsing error: invalid version tag\n——————–\nI downloaded the source and created an Android app, and it works nicely. The location and ordering stuff stuff doesn’t work (I’m not in USA) – it makes the side menu go a bit weird when it hangs, so it might be worthwhile highlighting that this may not work less people think something has barfed.\nShai Almog — December 3, 2015 at 5:36 am (permalink) Shai Almog says:\nThanks we’re looking into it. Might be a Linux firefox issue (damn web technologies). We checked with two macs and this works there.\nShai Almog — December 4, 2015 at 8:39 am (permalink) Shai Almog says:\nSteve made some fixes here and we just deployed an update. It might take a couple of hours for cloud flair to flush the caches. Can you check this and see if it resolves the issues and if not can you verify that the error messages changed?\nbryan — December 6, 2015 at 4:04 am (permalink) bryan says:\nI think I’ve got some weirdness my end. On my development system, it still does not work, but on another system (same OS version, same FF version) it works. Ahh… just found the \u0026ldquo;problem\u0026rdquo;. On my devel system I always use \u0026ldquo;Private Browsing\u0026rdquo; with ‘Tracking Protection\u0026quot; turned on. With a regular browser window it works fine. Sorry for confusion.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/ratatouilles-restaurant-in-code/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/ratatouilles-restaurant-in-code/ratatouilles-restaurant-in-code.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of my favorite Pixar movies is Ratatouille, maybe because I’m such a glutton. So when I was thinking\u003cbr\u003e\nabout the next tutorial/demo and the idea of a restaurant app came up I knew it had to be based on Ratatouille.\u003cbr\u003e\nThis is a relatively simple demo that can literally fit in a single blog post all the way thru and the real cool\u003cbr\u003e\nthing about it is that you can try the \u003ca href=\"/demos/Restaurant/\"\u003eJavaScript version right now\u003c/a\u003e from\u003cbr\u003e\nyour browser without compiling anything…\u003c/p\u003e","title":"Ratatouille's Restaurant In Code"},{"content":"\nAfter a discussion with some members of the community we decided to shift the weight of our support efforts to\nStackOverflow from our existing\ngoogle group discussion forum. Notice that we will still answer questions\nin the discussion forum but we strongly prefer using StackOverflow (don’t forget to use the codenameone tag).\nThere are issues with StackOverflow which is why we are keeping the existing group and will still answer\nquestions/issues there but the benefits far outweigh the issues:\nCleaner – stack overflow is far better structured than the discussion forum. This translates to better\nsearch functionality that can make finding answers much easier Google spring cleaning – Many Google projects moved their support to StackOverflow and with Googles\nhistory of killing projects in use we have some concerns Community Collaboration – one of the big issues with the existing discussion forum is that the community\nfinds it harder to collaborate and incentives for community support aren’t clear. As part of this work we also try to answer questions thru StackOverflow even when we get them in other\nchannels (e.g. email support). This can be helpful as a future reference to users who are looking at the given\nissue encountered by a pro user.\nCordova Support Improvements A lot has changed in the Cordova support since we\noriginally announced it, Steve\nhas been hard at work on the following changes:\nPlugins are now automatically imported when projects are created. Improved documentation, especially for plugin development Plugin development should now just involve implementation of the native portions in Java. The rest is automated. All of the details are listed in the main port\nsite.\nDocumentation specific to plugin development can be found\nhere.\nThis effectively means it should be MUCH easier to port plugins to Cordova with these changes.\nEasier Text Component Editing We’ve simplified text editing features in two significant ways, first we just added a set of methods to TextArea\ninstead of the venerable yet unintuitive methods of Display.\nWe now have startEditing, startEditingAsync, isEditing \u0026amp;\nstopEditing in TextArea. Most of these are pretty trivial with the exception\nof startEditingAsync which wraps the call to startEditing in a callSerially.\nThat’s generally a good practice if you can follow that.\nWe also added to Form the methods setEditOnShow/getEditOnShow\nwhich allow you to determine a TextArea that will enter editing mode immediately when the form\nis shown. This is a common and somewhat error prone use case since its pretty tricky to know when a form\nwas actually shown (post transition).\nFloating Hint Hints in text fields are really useful to convey information, however they can become really bothersome when\nworking with details that aren’t yours. E.g. around here Shai and Almog can be both surnames and given names\nso a form showing a text field with Shai and Almog might not convey the right information to the user.\nSo why have a hint at all if we should always use labels as is the case above?\nHints are really convenient since they show a user exactly where to type and are a great convention for a blank\nfield… FloatingHint offers the best of both worlds. When there is no input or focus in the field\nthe floating hint appears like a regular text field hint with some extra space above. When there is input or a user\nenters the field the hint animates into a small label on top as such:\nYou need to style FloatingHint in the designer to provide the style for the label on top (the hint\nuses the same TextHint). Other than that the code is trivial just wrap any text area/field with a\nnew FloatingHint(myTextField).\nValidation Error Messages Up until now we provided great validation hints and constraints but didn’t provide any way to show the error\nmessages related to validation…\nWe just committed a fix for that where errors will appear as InteractionDialog with the popup\npointing either at the error emblem or at the component. You can enable/disable this functionality on the validator\nby using: val.setShowErrorMessageForFocusedComponent(true);\nNew Default Icon Up until recently we used our logo as the default icon for Codename One applications, in the next plugin update\nwe’ll replace it with this image. Obviously you would need to replace it as you would for every shipping application\nbut as a person whose phone is filled to the brim with Codename One logo icons for all the testcases I need to\nrun I think this is a huge improvement. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDiamond — December 9, 2015 at 10:46 am (permalink) Diamond says:\nHi Shai,\nI was trying out the FloatingHint and discover few bugs that occurs on Sim, Android and iOS.\nWhen you initiate scrolling with your finger placed on the textfield, it receives focus and trigger editing.\nIf a textfield contains text and you trigger scrolling from that textfield, the text is hanging on the screen while the textfield itself and the rest of the form scrolls.\nCan FloatingHint be modified to allow the empty space that holds the Label to be hidden when nothing is there and grow during the animation process? Right now the space between fields is too large due to that and doesn’t make forms look good.\nShai Almog — December 9, 2015 at 11:58 am (permalink) Shai Almog says:\nHi Diamond,\nyes we know of these issues. Steve just committed improvements for this on iOS and is switching to Android for further improvements.\nThe issues on Android are more severe since the text input there is a bit antiquated and needs a serious overhaul.\nFeel free to file issues on these bugs for tracking them.\nI’d like to provide that option in floating hint but its non-trivial in the current animation architecture since it would require growing in two containers which means using animateHierarchy and that API is a bit flaky. I’m looking at rewriting our animation logic to address some core issues in Codename One and allow some seriously cool effects including this sort of effect.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/stackoverflow-cordova-update-validation-text-input-hints-icon/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/stackoverflow-cordova-update-validation-text-input-hints-icon/floatinghint.gif\"\u003e\u003c/p\u003e\n\u003cp\u003eAfter a discussion with some members of the community we decided to shift the weight of our support efforts to\u003cbr\u003e\n\u003ca href=\"http://stackoverflow.com/tags/codenameone\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eStackOverflow\u003c/a\u003e from our existing\u003cbr\u003e\ngoogle group \u003ca href=\"/discussion-forum.html\"\u003ediscussion forum\u003c/a\u003e. Notice that we will still answer questions\u003cbr\u003e\nin the discussion forum but we strongly prefer using StackOverflow (don’t forget to use the codenameone tag).\u003cbr\u003e\nThere are issues with StackOverflow which is why we are keeping the existing group and will still answer\u003cbr\u003e\nquestions/issues there but the benefits far outweigh the issues:\u003c/p\u003e","title":"StackOverflow, Cordova update, Validation, Text Input, Hints \u0026 Icon"},{"content":"\nAs I discussed in a previous article, creating a beautiful user interface that behaves appropriately across multiple devices can be a challenge, what with the vast array of screen sizes that your app may be deployed to. Codename One provides you with some power tools on this front. E.g.:\nMulti-images\nPixel to Millimetre unit conversion (approximate)\nOn-device image scaling\nIn this article, I would like to share with you another powerful tool to add to your kit, the Cloudinary library.\nThe Motivation Let’s take a look at a screen mock-up from a a nice UI kit that I’ve been working with lately:\nReplicating this UI in Codename One is pretty straight forward:\nUse the ToolBar for the top bar, and a BoxLayout Y_AXIS for the contents.\nUse multi-images for the icons so that they come out to the correct \u0026ldquo;real\u0026rdquo; size on every device.\nThe main photo is a bit more challenging though. The design calls for us to span the entire width of the device. If we just use a multi-image we can get it to size approximately to this space. But not exactly. We could set a multi-image as a background image for a container, and specify that it \u0026ldquo;scale to fill\u0026rdquo; the space. In fact this solution will work perfectly, if we are able to store the image in our resource file.\nUnfortunately, it looks like this app is some sort of news app, where articles are loaded from a server, and each article comes with its own photo. Hence, there could be thousands or millions of photos that need to be sized this way in this app. Using the \u0026ldquo;multi-image\u0026rdquo; solution won’t scale well, since multi-images need to be stored inside the resource file, and you can’t realistically store thousands or millions of images in the resource file.\nLoading images over the network isn’t a problem. You can just use the URLImage class with a \u0026ldquo;scale to fill\u0026rdquo; filter. The PropertyCross demo actually uses a hybrid solution with URLImage to load images of housing properties, multi-images serving as the placeholder image so that the image will scale to the right size. This approach, while workable still has fairly major problem:\nHow do we resize the image to be the correct size on all devices, and maintain quality. E.g. On the iPhone 3G, we need an image to be 320 px wide to span the width of the screen, whereas on the iPhone 6+, the image needs to be 1080 px. If we download a 320px image from the network, and resize it on device, it will look great on the 3G but horrible on the 6+. If we instead download a 1080px image, it will look great on the 6+ but quite poor on the 3G. In addition, this will waste a lot of unnecessary bandwidth for 3G users, downloading hi-res images that they don’t need.\nWe could try to split the difference by downloading say 720px image, but this just leads to sub-par results on both devices. The ideal solution would be to download a 320px image on the 3G and a 1080px image on the 6+. That way, quality is optimal on both devices, and we don’t waste any bandwidth.\nOne possible solution is to produce multiple versions of the image on your server, and have the device automatically select the correct one. This wouldn’t be too difficult to do, but before you go off and create a server-side script for resizing your images, I recommend you check out Cloudinary. Because they already do this. And they do it very well.\nThe Solution Before you begin, you’ll need to sign up for a free cloudinary account. The free account gives you up to 75,000 image transformations per month, and up to 5 gigs of bandwidth.\nThen, you’ll need to add the cloudinary cn1lib to your project.\nWhen you sign up for cloudinary, you’ll receive an API key, and associated credentials for accessing their API. You just need to initialize the API in your app’s init() method, as follows:\nimport com.cloudinary.Cloudinary; ... Cloudinary cloudinary; ... public void init() { ... Cloudinary cloudinary = new Cloudinary(ObjectUtils.asMap( \u0026quot;cloud_name\u0026quot;, \u0026quot;my_cloud_name\u0026quot;, \u0026quot;api_key\u0026quot;, \u0026quot;my_api_key\u0026quot;, \u0026quot;api_secret\u0026quot;, \u0026quot;my_api_secret\u0026quot;)); // Disable private CDN URLs as this doesn't seem to work with free accounts cloudinary.config.privateCdn = false; ... } Loading and Displaying an Image Once Cloudinary is initialized you can use the API to fetch images, upload images, and much more. The following example loads an image from the internet, and resizes it to a square image that spans the width of the device screen:\nForm f = new Form(\u0026quot;Test\u0026quot;); f.getAllStyles().setPadding(0,0,0,0); f.setLayout(new BoxLayout(BoxLayout.Y_AXIS)); int deviceWidth = Display.getInstance().getDisplayWidth(); // We create a placeholder image to set the size for the image to fit // to. Image placeholder = Image.createImage(deviceWidth, deviceWidth); EncodedImage encImage = EncodedImage.createFromImage(placeholder, false); // Load an image from cloudinary Image img2 = cloudinary.url() .type(\u0026quot;fetch\u0026quot;) // Says we are fetching an image .format(\u0026quot;jpg\u0026quot;) // We want it to be a jpg .transformation( new Transformation().crop(\u0026quot;fill\u0026quot;) // We crop the image to fill the given width/height .width(deviceWidth) .height(deviceWidth) ) .image(encImage, \u0026quot;http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg\u0026quot;); // Add the image to a label and place it on the form. Label l = new Label(img2); // Get rid of margin and padding so that the image spans the full width of the device. l.getAllStyles().setMargin(0, 0, 0, 0); l.getAllStyles().setPadding(0, 0, 0, 0); f.addComponent(l); f.show(); The result is:\nYou’ll notice that if you try to load that image directly from the URL, it is massive! The Cloudinary service automatically resizes the image before sending it to the device in the requested size. Performing the resize on the server produces stellar results. Much better than you could achieve with on-device resizing. In addition, you save a lots of bandwidth for your users, which also improves app performance. It’s a win-win all ’round.\nBut That’s Not All This is the most basic example, I could come up with, but Cloudinary can do much more. See their features page for a full list of capabilities. Here is a few nice features that caught my eye:\nResizing \u0026amp; Cropping\nFace detection, and appropriate cropping\nWatermark overlays\nCircular thumbnails, rounded corners\nText overlays, shadows, and borders\nPhoto effects, like Sepia, Blur, Black \u0026amp; White, etc..\nPDF and Office document processing. E.g. you can extract pages from PDFs or Word documents as images.\nConvert image format / modify quality.\nLearn More The cn1lib is a fairly straight port of Cloudinary’s official Java API, and should support most of its features (including uploading). Check out the README for more information. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDiamond — November 25, 2015 at 5:40 pm (permalink) Hi Steve,\nI tried out Cloudinary and it works really great.\nThere is challenge though, if my MultiButtons or List reference the same image, cloudinary sent multiple requests until 1 is cached. And according to this article http://support.cloudinary.c…, it in turns increment the Transformation Quota.\nIs there a way to detect if an image URL is already in queue and instead of sending another request, it waits for that to finish and use it?\nAs a note to anyone using this library: Cloudinary changes spaces in filenames to underscores automatically.\nTo avoid 404 error, Do \u0026ldquo;.image(encImage, StringUtil.replaceAll(yourImageName, \u0026quot; \u0026ldquo;, \u0026ldquo;_\u0026rdquo;));\u0026rdquo;.\nshannah78 — November 26, 2015 at 12:06 am (permalink) Thanks for the tip on image names and underscores.\nThe issue with loading the same URL might be something we want to do at a lower level — like NetworkRequest. I ran into this same issue when doing the Flickr concentration demo for a webinar a couple months ago. I worked around it by keeping a map of the URLs that I loaded, and if a URL request was pending, it just returned the URLImage for the previous image. Here is the code I used:\nhttps://github.com/shannah/…\nbryan — November 26, 2015 at 6:03 am (permalink) bryan says:\nSlightly off topic, but I looked at the link to the UI toolkit you mentioned, and I’m wondering what does it do for me as a CN1 developer ?\nBTW – like your posts, very helpful and informative.\nshannah78 — November 26, 2015 at 4:45 pm (permalink) shannah78 says:\nUI toolkits like that are very helpful for making nice UIs in Codename One. I’m currently working on porting that particular one to a theme and UI library for codename one. The process I use is described here: http://www.codenameone.com/…\nCarl-Erik Kopseng — August 30, 2016 at 8:10 am (permalink) Carl-Erik Kopseng says:\nAny tips on generating image sitemaps for cloudinary? Since there could be any number of versions of the same image, I was wondering if we should list them all or just one canonical representation.\nShai Almog — August 31, 2016 at 4:31 am (permalink) Shai Almog says:\nIs this related to Codename One?\nI don’t think this is the best venue for cloudinary tips.\nGert — March 24, 2017 at 3:12 pm (permalink) Gert says:\nI’ve never seen such a wonder example..\nHowever, you’d like to change\nCloudinary cloudinary = new Cloudinary(ObjectUtils.asMap(…\nto\ncloudinary = new Cloudinary(ObjectUtils.asMap(…\nWell..a question. Can’t I use local image to transform?\nThanks.\nShai Almog — March 25, 2017 at 5:48 am (permalink) Shai Almog says:\nYou can transform local images with many of the API’s we have such as masking etc. for that you don’t need cloudinary though.\nGert — March 25, 2017 at 5:59 am (permalink) Gert says:\nThanks, Shai.\nI found the Image.fill(width, height) method at last. It is very useful one.\nAnother question,\nFirst, is there any possibility to drive iOS and Android fingerprint authentication?\nSecond, I would like to make the Windows and Mac forms to be \u0026ldquo;alwaysOnTop\u0026rdquo; and \u0026ldquo;Non-focusable\u0026rdquo; ? It is possible in Java swing, but I couldn’t find the way in this codename1. if no way, any other way to use native libraries?\nBest regards.\nShai Almog — March 26, 2017 at 5:08 am (permalink) Shai Almog says:\nYou will need native interfaces for that, I don’t think it will be hard but haven’t tried it myself.\nWhen you generate native interfaces it also generates one for Java SE which will execute in the desktop port and the simulator. You can implement \u0026ldquo;always on top\u0026rdquo; there. I would check the isDesktop method from Desktop to prevent that code from executing in the simulator.\nGert — March 28, 2017 at 12:26 pm (permalink) Gert says:\nHi, Shai, I was very impressed to your rapid reply.\nJust hope your business grow the best.\nStill I have question. I studied native interface, but I couldn’t find the way to make the Desktop form to \u0026ldquo;AlwaysOnTop\u0026rdquo;.\nFirst of all, I couldn’t pass the Form value as parameter for native methods, even I don;t know this way is right for always on top.\nPlease guide me how to implement alwaysontop feature using native interface.\nAll the best.\nshannah78 — March 28, 2017 at 4:39 pm (permalink) shannah78 says:\nYou don’t need to pass the Form to the native interface. You can get the JFrame in native (swing) code using Frame.getFrames() or Window.getWindows. http://stackoverflow.com/a/…\nGert — March 30, 2017 at 2:27 am (permalink) Gert says:\nThanks so much, it works very well.\nJust a question also.\nI use cd1’s Button or JButton.\nHowever I couldn’t get it in Native Interfaces, like Frame.getFrames()..\nEven it seems it will manage only swing components, not cd1 component in JavaSE Native methods.\nHow can I manage it?\nI prefer I will be able to get cd1 components in JavaSE native interface’s methods.\nSince we know we can’t pass button components as argument to native methods, i can’t know how to get it in native methods.\nThanks. shannah78, and shai again.\nGert — March 30, 2017 at 10:15 am (permalink) Gert says:\nHi, Shai, First of all, thanks to everything of codename one.\nWell, I would like to customize camera view, simply overlay PNG image in the full camera view screen.\nAny way how to do it?\nBest regards.\nshannah78 — March 30, 2017 at 6:06 pm (permalink) shannah78 says:\nI don’t know what you’re trying to do. You can still interact with CN1 from the native side. Just make sure that you only interact with Swing on Swing’s EDT, and only interact with CN1’s UI on the CN1 EDT.\nGert — April 1, 2017 at 2:24 pm (permalink) Gert says:\nYes, you are right. I was thinking wrongly. There was never needed to get any Buttons in native methods.\nThanks for your everything.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/sizing-images-just-right-with-cloudinary/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/sizing-images-just-right-with-cloudinary/cloud-based-image-management.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAs I discussed in a \u003ca href=\"/blog/i-am-your-density/\"\u003eprevious article\u003c/a\u003e, creating a beautiful user interface that behaves appropriately across multiple devices can be a challenge, what with the vast array of screen sizes that your app may be deployed to. Codename One provides you with some power tools on this front. E.g.:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003eMulti-images\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ePixel to Millimetre unit conversion (approximate)\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eOn-device image scaling\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eIn this article, I would like to share with you another powerful tool to add to your kit, the \u003ca href=\"https://github.com/shannah/cloudinary-codenameone\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCloudinary library\u003c/a\u003e.\u003c/p\u003e","title":"Sizing Images Just Right with Cloudinary"},{"content":"\nWe became infatuated with icon fonts\na while back and used them quite a bit, recently we added the\nFontImage class that made\nthem really easy to use.\nHowever, up until now you had to download a font. Look up the value and enter it in. This was OK but not\nideal in terms of syntax/availability especially for simpler apps.\nGoogle’s material design includes a really cool mobile friendly icon font and using that for all our builtin features\nseems like a no-brainer. This reduces the total download size while making the fidelity of the UI much higher.\nAs a result of this features like pull-to-refresh, infinite progress, share button etc. will implicitly look different and use\nthe icon font.\nYou can also use one of the huge list of Google’s material design fonts with just one line of code!\nTo do that just go to the Material Design Icon Catalog\nand type the icon name in the search field (or just scroll thru the images). E.g. say I want a thumb up button\nI can just apply it to a button like this:\nFontImage.setMaterialIcon(getStarted, FontImage.MATERIAL_THUMB_UP); The cool part about that code is that you don’t have to define a special font, color or anything!\nThe API will implicitly extract the button styles and use that to set the right icon into place.\nIf you just want the image to use in any way you see fit you can just use:\nFontImage img = FontImage.createMaterial(FontImage.MATERIAL_THUMB_UP, style); Where the style object indicates the size and color of the image. Notice you can also use getMaterialDesignFont\nto get the actual font object.\nBackground Music As part of our continuing effort to improve the portability of background processes within Codename One we\nrecently added support for background music playback. This support isn’t totally portable since the Android\nand iOS approaches for background music playback differ a great deal.\nTo get this to work on Android we added the new API: MediaManager.createBackgroundMedia.\nYou should use that API when you want to create a media stream that will work even when your\napp is minimized and this should work for Android.\nFor iOS you will also need to add a special build hint: ios.background_modes=music. Which\nshould allow background playback of music.\nBackground Location Updates – Geofencing This was actually committed last month but documenting this has been a bit more challenging so it got pushed\nback a bit. Background location is even more complex than background media, polling location is generally\nexpensive and requires a special permission on iOS. Its also implemented rather differently both in iOS\nand Android.\nBecause of the nature of background location the API is non-trivial. It starts with the venerable LocationManager\nbut instead of using the standard API you need to use setBackgroundLocationListener, but\nthis is where it flips. Instead of passing a location listener instance you need to pass a Class\nobject instance. This is important because background location might be invoked when the app isn’t\nrunning and an object would need to be allocated.\nNotice that you should NOT perform long operations in the background listener callback. IOS wake-up time is\nlimited to approximately 10 seconds and the app could get killed if it exceeds that time slice.\nNotice that the listener can sends events also when the app is in the foreground, therefore it is recommended\nto check the app state before deciding how to process this event. You can use Display.isMinimized()\nto determine if the app is currently running or in the background.\nWhen implementing this make sure that the class passed is a public class in the global scope (not inner class\nor anything like that). Make sure that the class has a public no-argument constructor and make sure you\npass it as a class literal e.g. MyClassName.class. Don’t use\nClass.forName(\u0026quot;my.package.MyClassName\u0026quot;)!\nClass names are problematic since device builds are obfuscated, you should only use literals which the\nobfuscator detects and handles correctly.\nAndroid Native Gradle Support Google made a lot of changes to their native tooling since we launched Codename One. Up until now we\nare still using Ant on our servers to build the native Android apps. This has been rather convenient but as\nGoogle is migrating away from Ant to Gradle its becoming an issue where some features can’t be supported\nby the build system.\nSo we introduced the new build hint: android.gradle. This hint can be either true or false and\nwill default to true once 3.3 launches so we suggest kicking the wheels right now by setting it to true and\nreporting issues!\nOne of the really great features you get by building with Gradle support is that you will now be able to just\nopen the Android project in Android studio when using\ninclude source\nand just run them as usual! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDiamond — November 23, 2015 at 9:51 am (permalink) Diamond says:\nMy Christmas came early this year as this is the biggest gift I ever received. 2 of my apps have reached a deadlock as they both require background location polling when app is not running.\nThank you for the implementation. I can’t wait for the next plugin update.\nCould you please share a sample usage snippet of background location polling to help kickstart the implementation with less errors.\nChen Fishbein — November 23, 2015 at 10:25 am (permalink) Chen Fishbein says:\nHi,\nThis really depends on your use case, but in most cases when you are in the background you usually want GeoFencing.\nWith GeoFencing you can ask for an event from the device when the user gets near a certain location or walks away from a certain location.\nSee the new addGeoFencing method in the LocationManager, when you get the callback check if the app isMinimized and if true you usually want to alert the user that he is now near a certain place, the only way to communicate with the user when you are in the background is by sending a local notification to the user, see:\nhttp://www.codenameone.com/…\nbryan — November 23, 2015 at 9:36 pm (permalink) bryan says:\nCan I use the FontImage images to automagically work in different resolutions in place of multi-images ?\nShai Almog — November 24, 2015 at 4:19 am (permalink) Shai Almog says:\nYes. That’s the general idea.\nScaling a font image is effectively just drawing the text larger. It uses the native device kerning so anti-aliasing will be gorgeous.\nA huge bonus is that the font color auto-adapts to the color palette.\nChidiebere Okwudire — December 9, 2015 at 11:34 am (permalink) Chidiebere Okwudire says:\nHi,\nWith regard to background location updates, what is the frequency with which the listener will be invoked? Is it configurable?\nShai Almog — December 9, 2015 at 12:04 pm (permalink) Shai Almog says:\nHi,\nthe LocationRequest class receives an interval which is the time in milliseconds for polling as far as I understand.\nChidiebere Okwudire — December 9, 2015 at 8:45 pm (permalink) Chidiebere Okwudire says:\nHmmm… I still don’t get it: A LocationRequest object is not a parameter of the setBackgroundLocationListener() method…\nShai Almog — December 10, 2015 at 3:38 am (permalink) Shai Almog says:\nI think wires got crossed in my brain as I never used the background location listener.\nI think its always coarse and polls in a system defined way to preserve battery life but Chen or Steve can probably give a better answer here.\nChen Fishbein — December 10, 2015 at 8:10 am (permalink) Chen Fishbein says:\nThe LocationRequest is useful for foreground location listening to preserve battery state.\nBackground location is different and should be used when the app is not running, the app gets updates only when significant location change happens\nChidiebere Okwudire — December 10, 2015 at 11:56 am (permalink) Chidiebere Okwudire says:\nHi Chen, thanks for the clarification though my question remains unanswered. What is a ‘significant location change’ in this context?\nChidiebere Okwudire — January 20, 2016 at 12:04 pm (permalink) Chidiebere Okwudire says:\nHi,\nWith regards to material icons, as far as I understand, these are Google’s icons (so most suited for Android), right? When creating an app with native look-and-feel, I’d really love to have iOS icon style on iOS, WP icons on WP, etc. This will make for a richer native experience instead of having the same icons on all platforms. What’s the recommended way to realize this in CN1?\nhttps://icons8.com/ provides what am looking for but the problem is that I have to download several images possibly in different colors to meet my needs. Is there a better way (e.g., an icon font that provide platform-specific versions of icons)?\nShai Almog — January 20, 2016 at 2:16 pm (permalink) Shai Almog says:\nHi,\ntrue. We thought about this quite a bit before settling on the material icon set and not something with wider reach.\nThe reason we added it was to enable us and you guys to prototype things that look good on all platforms without worrying about the \u0026ldquo;art\u0026rdquo; side of the fence. This helps smaller apps, internal apps and demos look reasonable and even more native as the icons adapt to the specific platform convention colors. Material icons are free, unencumbered and cheap in terms of size overhead so they were pretty easy to add out of the box.\nWith a refined design as we see in most of our professional grade apps, you wouldn’t use any of our builtin icons and focus on your own so having icons for everything would be redundant.\nYou can have platform specific icons like these guys offer thru the resource file override feature which was designed with this exact thing in mind: https://www.codenameone.com…\nHowever, I think this is often overstated. I think 99% of users care don’t really care that much about these conventions. If your app looks good and respects the general platform paradigm (e.g. Menu button, back button behavior etc.) it should be good.\nChidiebere Okwudire — January 25, 2016 at 9:16 am (permalink) Chidiebere Okwudire says:\nThanks for the explanation\nayush jagga — June 23, 2020 at 7:28 am (permalink) ayush jagga says:\nGeofencing remains relatively new. While more businesses experiment with technology, creative marketers will come up with more innovative ways to maximize their potential for long-term benefits. If you are thinking of experimenting with geofencing for promotion, confirm you are qualifying your prospects supported supply and demand, and make an irresistible offer for the simplest results.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/material-icons-background-music-geofencing-gradle/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/material-icons-background-music-geofencing-gradle/material-icon-fonts.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe became infatuated with \u003ca href=\"http://codenameone.com/blog/icon-fonts-oldvm-swan-song.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eicon fonts\u003c/a\u003e\u003cbr\u003e\na while back and used them quite a bit, recently we added the\u003cbr\u003e\n\u003ca href=\"http://codenameone.com/blog/icon-fonts-oldvm-swan-song.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFontImage\u003c/a\u003e class that made\u003cbr\u003e\nthem really easy to use.\u003cbr\u003e\nHowever, up until now you had to download a font. Look up the value and enter it in. This was OK but not\u003cbr\u003e\nideal in terms of syntax/availability especially for simpler apps.\u003c/p\u003e\n\u003cp\u003eGoogle’s material design includes a really cool mobile friendly icon font and using that for all our builtin features\u003cbr\u003e\nseems like a no-brainer. This reduces the total download size while making the fidelity of the UI much higher.\u003cbr\u003e\nAs a result of this features like pull-to-refresh, infinite progress, share button etc. will implicitly look different and use\u003cbr\u003e\nthe icon font.\u003cbr\u003e\nYou can also use one of the huge list of Google’s material design fonts with just one line of code!\u003c/p\u003e","title":"Material Icons, Background Music, Geofencing \u0026 Gradle"},{"content":"\nIf anything, they are rearranging the deck chairs on the Hindenburg!\nStephen Colbert\nWe really depend on JavaFX at Codename One, our simulator needs it. Our desktop build uses it and our\ndesigner tool is based on Swing. We want it to succeed, its important to our business!\nWe are not alone, even if you are a Java EE developer and don’t care about desktop programming, keep in\nmind the fact that today’s desktop technology is tomorrow’s server technology.\nE.g.: C++ and Windows (a desktop technology) took the servers from Unix and C. Only to be replaced by\nJava (up until then a web based Applet language) and Linux. JavaScript might not look as a JavaEE contender\ntoday but as more developers come out of college liking JavaScript and not Java this will affect us all.\nNote: If you are a fan of JavaScript/NodeJS or any other such scripting language then\nyou are not the intended audience for this post…\nThis post is for people who love working with Java and want it to move forward.\nWhen we rented a booth at JavaOne 2014 we got the impression that 90% of the Java developers we talked\nto were enterprise developers. Most of the exhibitors and the highest attended talks were also enterprise oriented.\nAs a mobile tool vendor this is a much harder divide to cross than the one between desktop development and\nmobile. It highlights the fact that we need JavaFX to work or make way for something better but we need a\nGUI solution now.\nThis post isn’t about whether JavaFX sucks or not. Its not about whether its a good API and it isn’t about\nwhether you can create nice looking apps with it (you can). Its about fixing JavaFX or moving away from it\nto something else, its about acknowledging the problems within it rather than presenting an aura of \u0026ldquo;everything’s\nfine\u0026rdquo; to fresh Java developers.\nInitially I wrote about some technical issues in JavaFX as well. I decided not to go into that discussion. I have the\nutmost admiration and respect to the guys who created JavaFX. Its impressive in many ways. But good technologies\nalso fail and in the next few sections I’ll try to elaborate on this:\nReasoning – Why we all need a Java desktop API strategy Proof – read this if you don’t think there is a serious problem with JavaFX’s traction Why Should We Care? – If you are a Java EE developer who thinks this isn’t your concern please read this. What Are The Options? – how do we move Java forward. How did we get here? – if you are new to Java and this discussion is missing historical context read this first. Final Word – my personal take on the facts I listed here. Reasoning The first step in solving a problem is admitting that we have one and right now JavaFX is a problem that the\nJava community tries hard to avoid. Swing was pretty stable and while it had its share of issues/pitfalls\nit had its own reasonable traction. JavaFX still hasn’t attained that status but\njust in case you aren’t on the same page as I am we’ll review the evidence in the next section.\nThis isn’t an easy post to write and I’m sure it isn’t easy to read, but its a discussion that just isn’t happening\nin the Java community and should happen. New developers coming into Java every day are introduced\nto JavaFX without truly understanding its problems.\nThe thing that made me write this post was this\nblog post\nthat was mirrored by\nJava Code Geeks here.\nI would argue that while the post is truthful (in a very subjective way) it also enforces a false impression\nof the status and perception of JavaFX. This is very troubling when we try to convince young students to\npick up Java, we don’t want them to be disillusioned later on.\nThe problems with JavaFX can’t be addressed if we don’t accept they exist.\nThe current users of Java FX consist of 3 archetypes:\ncorporations with huge Swing investment, students \u0026amp; hardcore diehard fans.\nWhile all of the above are totally fine, you can’t grow a community based on that. The corporations aren’t building\nnew things, the students will graduate to do something else and the hardcore fans…\nThey might be left with nothing as the platform declines.\nI’ll cover the \u0026ldquo;why should we care\u0026rdquo; down this post but first lest talk about the proof for the hardcore fans.\nProof JavaFX Doesn’t Have Traction Exhibit A: Oracle Doesn’t Use JavaFX\nI can go on about this but the facts are pretty clear. Even Swing based Oracle products aren’t moving in the\ndirection of JavaFX. I can go into the firing of the evangelists and some of the teams within Oracle working\non JavaFX but that seems redundant.\nI would like to point out though that Oracle no longer distributes Scene Builder, yes I know its still available elsewhere\nbut if you are looking for signs of what Oracle is thinking… The messaging is pretty loud and clear.\nExhibit B: JavaFX Hasn’t Gained The Traction Of Swing\nStack overflow was launched on \u0026ldquo;September 15th, 2008\u0026rdquo;, this is important since JavaFX was launched released\non \u0026ldquo;December 4th, 2008\u0026rdquo;. Effectively StackOverflow was brand new when FX came out with all of its PR glory\nand Swing should have been on the decline. There was very little time where StackOverflow existed and JavaFX\ndidn’t exist.\nThe above essentially means Swing should have far less question tags on StackOverflow compared to FX,\nsurprisingly the numbers here are pretty staggering and decisive…\nThere are 11,565 questions tagged JavaFX, this makes sense for a 7 year old highly visible and widely\npromoted project. However, Swing which should have declined during this time has 56,434 questions which\nindicates to me that even the Swing developers who are the CORE demographic of developers for FX\nhaven’t migrated.\nNow to be fair, JavaFX transitioned between JavaFX script to the Java based JavaFX. But that should have\ncaused far more questions and confusion within the community. The \u0026ldquo;reboot\u0026rdquo; so to speak generated attention\nall over the place and should have mapped to usage numbers.\nThis is really punctuated by this illuminating graph from Google trends:\nNotice that Swing (which had some traction) declined, JavaFX remained low and effectively competes for attention\nagainst Swing rather than growing. This chart might be read as \u0026ldquo;desktops lost interest to mobile and web\u0026rdquo;,\nwhich would be true and acceptable as an answer (see my discussion below) but the fact that FX can’t even\nbeat Swing indicates a far larger problem at play.\nBut lets compare it to another company in a similar situation that had a desktop oriented tool that was popular\nand got swept by web/mobile:\nAs you can see, the much maligned Adobe Flash is more relevant than Swing/FX by orders of magnitude\naccording to the (unscientific) Google trends.\nExhibit C: Dice.com Agrees\nWhile I don’t think you should pick a technology because of the job market, it is an indication of the state of the\nmarket. Searching thru dice.com for JavaFX netted me 28 positions of which only 4 placed Java FX as a requirement\nto the job (I checked one by one which is possible when you only have 28!).\n\u0026ldquo;Java FX\u0026rdquo; only listed 12 options. But this is where it gets interesting… Swing had 198 positions!\nJavaEE had 16,752 positions and Android had 2,333 positions.\nTo be fair there was a job as a NASA contractor that did look pretty sweet in the Java FX search but I think that\ncombining all of the above conclusively demonstrates that JavaFX lacks traction.\nWhy Should We Care? If you are a fan of JavaFX then this is a no-brainer. Skip ahead.\nBut the rest of us should care deeply since desktop programming is important to the health of the Java ecosystem\nas a whole. One of the big benefits of Java was the skill transferal/tool portability between mobile,\ndesktop and backend. The ability we had as developers to move between the datacenter and the front office\nwas unparalleled in our industry!\nJava is now challenged on all fronts: NodeJS/Ruby etc. on the server side, iOS on mobile \u0026amp; HTML+JavaScript\non both mobile and desktop. If the client team doesn’t write the app in Java then why use Java on the server?\nWon’t it be more convenient if the client team and server team speak the same language?\nYes mobile plays a big role here and JavaFX (or desktop) wouldn’t take over from the web.\nHowever, in the enterprise Swing dominated well after the rise of the web and JavaFX was able to lose that\nadvantage. Losing that ground might cost Oracle the very lucrative JavaEE market and it might cost us\nin skill decline as our specific set of skills experience less demand (yes we’d still make money just like the\nCOBOL guys do, it just won’t be as much fun maintaining a legacy system over cutting edge stuff).\nWe still need a desktop development API to build our IDE’s, our control consoles and do practically everything\non our machine. Desktop development API’s are also tremendous teaching aids, getting a UI up and running\nis far more conductive to the teaching process than getting some webservice deployed.\nIf you want a future generation of Java developers we need a decent UI option. Some of you\nJavaEE developers out there (or play framework fans) might jump on the HTML bandwagon for teaching…\nI think that’s a better solution than teaching Java FX but effectively its still harder than desktop programming\nand you are then in direct competition with JavaScript tools which have a \u0026ldquo;home court advantage\u0026rdquo; as\nstudents would probably rather learn 2 languages instead of 3 (HTML+JavaScript only).\nTodays students sometimes learn JavaFX or Swing in class and often find out that they learned yesterdays\ntechnologies as they leave the classroom!\nEven if you never intend to write such a UI the ability to do so in Java is crucial to all Java developers!\nWhat Are The Options? Hopefully you reached this point agreeing (at least partially) that there is a problem. I think one of the problems\nis unclear messaging from Oracle about its commitment (or lack thereof) to JavaFX. Their representatives\nsay unofficially that Oracle never discontinues products. That’s pretty accurate.\nHowever, Swing has been pretty much abandoned and it feels that way.\nFix \u0026amp; Promote JavaFX\nOnly Oracle can do this. While Java is bigger than Oracle and would continue even if Oracle stops all activity\nthe same cannot be said for JavaFX. The community has made some efforts for quite a while but something\nas ambitious as JavaFX requires serious backing and if Oracle can’t get behind JavaFX 100% then it will\nkeep declining and drag Java down with it.\nAcknowledge That JavaFX Will Never Pickup\nThis is what I’m advocating. JavaFX is here to stay in the same way that AWT was, but once we accept that\nits never going to amount to more than its current limited scope this opens up the possibilities for client\nside development in Java. It also means we should start focusing on new things and maybe something\ncan emerge as a replacement.\nI think that the most important thing to do here is to move students off of JavaFX and into more sustainable\nareas in Java such as the newer server/HTML frameworks or to mobile, this will still provide some of the\npleasurable \u0026ldquo;tingle\u0026rdquo; of seeing your UI run but would provide a more sustainable skill set.\nI’ve spent several days trying to come up with a potential replacement to JavaFX on the desktop and\nunfortunately there are no serious contenders at this point in time. Maybe one of the contenders I listed below\nwill rise to the task:\nSWT – SWT hasn’t matured well. When it was designed modeling it to the Win32 API seemed like the\nright thing to do but with the move to mobile and Macs its now a problematic contender. It is mature though\nand well understood. Swing – going back to Swing is probably not an option, too much time has passed. Because its integrated\nwith the JDK anything needs to go into the JVM and thru Oracle. QT – I used to really like QT back in my C++ days. It since added some things but ever since the Nokia\npurchase it was mostly stuck in place. Adding to that the fact that most of the code base is in C++ makes\nthis a non-started for most Java developers. Native – this is actually something we are considering for Codename Ones desktop port. Just calling\nthe OS native API’s directly using a native to Java mapping API. For Codename One this is pretty simple since\nwe can use Open GL and very few peers but I don’t think this will be useful for Java developers as a whole. HTML5 – I think that JavaScript has a huge advantage when it comes to HTML. If HTML or browsers\nare the dominant players then why use Java? JavaScript already has the traction \u0026amp; toolkits in the\nHTML world and Java seems alien there. DukeScript/TeaVM/GWT – I really like all of these and the ability to integrate with HTML is powerful,\nbut I think focusing everything on these tools could ultimately relegate Java to a coffeescript substitute\nwhich seems like a demotion. Android – like Codename One Android wasn’t designed for the desktop. But unlike us its being adapted\nto the desktop (replacing Chrome OS according to rumors). Its a huge, complex and pretty complete API\nmissing a few key features but its still pretty powerful. The only problem is that this would require quite a bit of\neffort both in the porting effort and in adding desktop \u0026ldquo;concepts\u0026rdquo; to the API (Windows etc.) which was very\nmuch mapped to mobile. How did we get here? This section is probably redundant for most readers but after writing everything above it occurred to me that\na fresh Java developer reading my huge rant will have very little historical context. Luckily I can tell recite\nthe history rather easily as I had a front row seat working at Sun Microsystem during the peek of Java FX\nand at Oracle as it failed to materialize.\nJava launched with AWT which was a pretty problematic \u0026ldquo;rushed to market\u0026rdquo; GUI API.\nSun wanted to improve AWT and replace it with Swing unfortunately at that time Netscape (the leading browser\nvendor by a good margin) had standardized on Java 1.1 and Microsoft was also stuck there.\nSo Swing was developed with compromises designed for it to work within the browsers who were the main\nusers of Java at that time. This bit of history is important since it punctuates the problems in FX perfectly.\n10 years or so ago Chris Oliver (a Sun engineer) introduced a rather cool scripting language he wrote and it\ngained some traction within Sun. At that time Swing was popular with the enterprise but slowly losing ground\nto Flash in the consumer market.\nThe managers at Sun decided to promote the idea and placed a lot of effort, resources into this new language\nwhich was eventually christened as JavaFX Script. A lot of developer resources were removed from Swing\nand placed into the JavaFX script project and a lot of promises were made to developers. I actually helped\nsome of the related projects such as the mobile phone ports etc.\nThere were many problems with JavaFX Script and they were further compounded by Sun’s troubles and notoriously\nloose management style. Swing was declining rapidly as Oracle purchased Sun. Oracle killed JavaFX Script but\nliked a lot of the API ideas behind it so they re-targeted the JavaFX effort as a Java based API. Generally a\ngood idea, but in a typical corporate fashion everyone who used JavaFX Script had to port their apps at once\nto the new JavaFX or be stuck without the ability to download the VM (they later reversed that decision but\nits not the best way to treat early adapters).\nThe new JavaFX API took years to materialize and for quite a while wasn’t even open or properly integrated in the\nJDK. Its integration is partial to this day and its still not a part of Open JDK (which is important on Linux).\nWhen the JavaFX team was assembled and grew they made an important decision that came back to\nhaunt them: Don’t repeat the mistakes of Swing/AWT – build a clean API unburdened by legacy.\nUnfortunately, being a product of a major corporation in the developed world they needed to support\na lot of things (e.g. accessability) and so a huge amount of code needed to be written from scratch.\nSo the team created a well designed API but there was no decent migration path to Swing developers\nand to some degree the path from Swing problematic to this day (despite many improvements). The API is\nhuge but still incomplete at some parts because the required breadth for such an API. In the meantime Swing\ndevelopers who got no real updates for years mostly evaporated to other platforms and now we have Swing\nand FX one of which is outdated and the other brand spanking new but has no real traction.\nI think the biggest lesson from JavaFX is to always \u0026ldquo;think small\u0026rdquo; and release often. Trying to build a complete\nsolution from day one rarely works even if you have the full set of resources that Sun/Oracle were able\nto wield. I would argue that all the problems in JavaFX are a result of mismanagement.\nFinal Word One of the things I hated the most about Google under Larry Page was the Spring cleaning, since Android\nGoogle has failed to create anything that enjoyed that level of traction. That was not due to lack of trying,\nit was due to lack of commitment to anything. Most people don’t remember this but Android was a failure\nwhen it was initially released (G1) and the iPhone had a very small niche following (relatively to the mobile market\nas a whole).\nBoth companies stayed the course and invested in the product/partnerships while slowly iterating on the product.\nThis took money, time and commitment which is pretty hard to do.\nUnfortunately, looking at the current state of JavaFX and Oracles backing of it. Its pretty obvious that it was\nalready moved to maintenence mode and won’t get the resource commitment it needs to grow. I think we\nmight be better off moving it aside and allowing other technologies to rise to prominence. Even if you disagree\nwith that opinion I hope we can all agree that there is a serious problem here. To me the problem is mostly\nwith students picking up JavaFX either thru universities or online courses. We might as well teach them\nCOBOL, there are jobs writing COBOL too.\nWith the current state of JavaFX and the lack of any contender to occupy its space (which is currently not officially vacant)\nI get a sense that we might be better off with nothing. At least then we’d have a big \u0026ldquo;vacancy\u0026rdquo; sign in our\nvirtual front yard where our desktop API should reside. This will let one of the options I listed above (or something\nbrand new) occupy that spot…\nMaybe it will trigger someone at Oracle to finally give JavaFX the resources needed to turn it into a viable\ntool but knowing Oracle… I’m not holding my breath. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAndrea Liana — November 19, 2015 at 11:18 am (permalink) Andrea Liana says:\nHallo, I liked your post because I share many of your worries about Java future. I had great expectations from Java One 2015, but except for the module feature, I wanted to hear too a clear and resounding message from Oracle about desktop commitment. And that did not came.\nI have a large codebase running on a custom fork of a very old AWT based framework and at the moment I am working on a little pure JavaFX framework because I expect soon or later to read an Oracle message like \u0026ldquo;JDK 1.xx will no more support AWT\u0026rdquo;.\nWhat I still don’t understand on Oracle policy, like:\n– letting RoboVM being acquired by Xamarin instead of buying it and use its codebase for the recent accounce of a project about JVM for iOS / Android;\n– delegating SceneBuilder to GluOn instead of keeping it as an official Java branded tool;\n– why is it so hard to extends JavaFX components considering all the customization required by current AWT/Swing project to meet our customer needs.\nI chose Java becuase I trusted that platform with the \u0026ldquo;Write once, run everywhere\u0026rdquo; key feature. I just only hope not to be forced to abandon it because of Oracle foggy decisions…\nShai Almog — November 19, 2015 at 11:43 am (permalink) Shai Almog says:\nAs a former Sun guy I can answer this pretty clearly.\nIf Oracle would have bought RoboVM then someone was clearly asleep at the wheel which is rare for Oracle who are normally very calculating. RoboVM relies on 3rd party projects with mixed licensing some of which potentially conflict with Oracles goals. For Oracle lawyers just evaluating RoboVM would be an IP nightmare.\nFurthermore, RoboVM doesn’t make anything that Sun/Oracle needs. We had VM’s running on iOS back before Oracle acquired Sun. We even demoed them and we had really brilliant compiler engineers some of which are still at Oracle. RoboVM’s traction is noticeably lower than Codename One and we both don’t have a fraction of the marketing muscle Oracle has. So that’s not a reason for an acquisition either.\nJavaFX has inherent technical problems it will never work on iOS properly and neither will the full JVM because mobile is pretty different to desktop. I didn’t want to get into the technical aspects there and didn’t want to get too deep into mobile as this might have shifted the discussion into me trying to promote Codename One.\nOracle didn’t delegate anything to Gluon, they just abandoned scene builder and the Gluon folks couldn’t take a hint.\nAs a guy who built VM’s and done mobile since the 90’s Gluon really gets under my skin. They are trying to sell something that isn’t technically viable as if its a real world tool that can actually work in production. There are basic things both in Java FX and Java’s network stack that can’t be implemented correctly/efficiently in iOS e.g. java.net.* (posix sockets don’t turn on radio), sub pixel anti-aliasing etc.\nAndrea Liana — November 19, 2015 at 12:02 pm (permalink) Andrea Liana says:\nThank you four your prompt reply and clarifications.\nOne more question… am I wasting my time and efforts on JavaFX for desktop applications?\nShai Almog — November 19, 2015 at 12:07 pm (permalink) Shai Almog says:\nHard to tell.\nI don’t share your immediate concern about AWT. It wasn’t even officially deprecated so I can’t really see it going away \u0026ldquo;soon\u0026rdquo;. Since Java release cycles are around 18-24 months assuming Java 9 deprecates AWT you would still be clear for another 2 years after that…\nJavaFX is way better than Swing and AWT as you probably noticed. Its more modern and easier to use.\nIt has its faults but if you need a desktop API at this point in time and like Java then its a reasonable enough choice. As you saw from the article above, we are in the same boat. Codename One currently uses JavaFX \u0026amp; Swing for our desktop builds and for our mobile device simulators.\nAndrea Liana — November 19, 2015 at 12:53 pm (permalink) Andrea Liana says:\nConsidering that Java 9 is more concerned about solving the package hell, I hope Java 10 will be more focused on giving us developers a clear and convinced path for forging our user interfaces. Desktop or mobile….\nMichael Stover — November 19, 2015 at 6:22 pm (permalink) Michael Stover says:\nThe list of alternative options seems to include only one real choice: SWT.\nAnd I say that having despised the creation of SWT for my entire career.\nbryan — November 19, 2015 at 11:44 pm (permalink) bryan says:\nI’m in the same position re developing desktop app in FX.\nI’m not quite as pessimistic as Shai. As far as I know Oracle will continue to ship FX as part of the standard JRE runtime. The OpenJDK mailing list seems to reasonably active on the FX front. IMO, FX with SceneBuilder is probably the best GUI development environment I’ve used – CN1 is close 🙂\nI was a big fan of GWT and the app I’m currently developing with FX was going to be GWT. Unfortunately, most of the stuff that (to me) makes GWT a value proposition is going to be deprecated in the 3.0 release.\nIt will be interesting to see what the merging of ChromeOS/Android brings. I think some of benefits of web apps (i.e. zero footprint deployment) are disappearing with the App Store model of deployment, and given that it’s impossible to be sure any Javascript framework will be around next week let alone in 5 years.\ncritic — November 20, 2015 at 7:19 pm (permalink) critic says:\nJavaFX API was made as heavy as Swing API was. It looks like object oriented concepts were intentionally avoided. Maybe it’s a reason why JavaFX is pretty fast. If one needs fast dynamic imaging, forget about Swing, take side of JavaFX. Not sure? Compare CPU percentage in Task Manager. But what could break any business is a tolerance to failures. When something fails in Swing, one will likely recover the application. When such accident happens with JavaFX, the best choice would better kill the application. Sounds bad for business.\nJeff Martin — November 23, 2015 at 4:48 pm (permalink) Jeff Martin says:\nInteresting post – I would be curious to hear your suggestions for specific improvements to fix JavaFX (or what a replacement would look like).\nShai Almog — November 23, 2015 at 8:03 pm (permalink) Shai Almog says:\nA replacement IMHO should be simple and not over ambitious as JavaFX.\nWhile you can outline a lot of mistakes made on the managerial, strategic levels with JavaFX the biggest technical mistakes I personally perceived are:\na. Not providing easy interaction with Swing from the start (throwing away existing traction).\nb. Building something huge that’s very hard to move and adapt\nThe project is generally over ambitious and tries to be \u0026ldquo;all that\u0026rdquo;. Its admirable but really hard to get a battle-cruiser of this size into production quality. Then it takes a huge amount of maintenance. This is astounding to me as the original proof of concept for JavaFX Script was the work of one guy…\nJeff Martin — November 23, 2015 at 8:52 pm (permalink) Jeff Martin says:\nVery good points – particularly in light of recent staff reductions.\nPablo Rodriguez Pina — November 25, 2015 at 1:27 am (permalink) Pablo Rodriguez Pina says:\nHey Shai,\nJust a opinion from a hands on JavaFX software company. We have been building all our enterprise apps with a JavaFX frontend and a JavaEE backend, all traffic between server and client in pure java usign either native java serialization or java serialization frameworks such as hessian or kryo.\nFrom our experience, JavaFX is working great, there may not be many stackoverflow questions, or many developers in the world using JavaFX or the evangelists may have gone to hell, but it is just working great for us. The JavaFX support team as Oracle has been pretty good in looking at issues and communicating and we find building frontends in JavaFX far more practical than web based interfaces. We can use JMS easily to receive push notifications on the client, and it just feels way more relaxing using strongly typed Java 8 and moreover Java EE (CDI, JMS, etc) on the client with all its glory.\nThe core JavaFX controls provide us pretty much all the functionality we need, we have had to resort to controlsfx or jfxtras for a coupl of things, but overall, the core javafx controls do the job.\nThat’s all, happy to be the rare case in the javafx community, but we are as happy as chips with it.\nIn 2000, during the dot com boom, everyhting had to be web based, it was either web based or good for nothing. Similarly in recent times, we have seen an insane Objective-C universe expansion and contraction that took Objective-C from nothing to rank #3 on the tiobe index and it has now disappeared from the top 10.\nHaving done swing earlier and still mantaining legacy swing applications, I still don’t see how, regardless of how much growth energy Oracle puts into JavaFX, any other alternatives are going to be in the best interest of our clients over the next 10 years.\nIf we are talking about traction, yes, javascript has traction even thought the fricking programming language hasn’t moved fro 20 years and even Google has stated that the limitations of the language make it almost impossible to build large applications and there is a universe of javascript producing frameworks and languages like Dart, GWT, vaadin, JSF, etc. But that traction the javascript language has is not so easy to find in the actual frameworks software vendors need to choose to develop an application UI.\nWith all the glory of javascript and html, still one needs to choose JSF 1 or 2 and a JSF component library or a javascript framework and these js frameworks seem to appear and disappear in a shorter amount of time and don’t make it so easy for the developer to upgrade to the following version. I wrote a JSF about 8 years ago app using the Sun woodstock JSF library, got dephased before I finished, what do I migrate it to to keep it up to date without a massive UI rewrite ? then did another one on IceFaces 1.8, want to migrate it to IceFaces 3.0? not even that was straight forward.\nWe have migrated apps from JavaFX 2 to JavaFX 8 with minor complications, and it was only a bit of an effort migrating the first application, once the regressions were located, the other apps took no time to migrate.\nIn our case, as we mainly build enterprise apps, there is no much need for running apps on mobile phones. If we need to run on tablets, We can get decent windows tablets that can run JavaFX at decent performance (I’d probably prefer linux tablets but windows seems to have monopolized the intel bay trail tablet market as it has done with laptops). Hang on, we do have a JavaFX app running on a linux based touch device.\nWe have built about half a docen enterprise apps using JavaFX as a front end and haven’t experienced hughe maintenance caused by JavaFX. In fact, we have probably only bumped into a handfull of bugs that got resolved by the JavaFX team in a mater of a jre update.\nWe gave up on scenebuilder a long time ago, mainly due to its blindness of the maven classpath, but one way or another, I didn’t like the generated FXML code, today, we are coding the FXML and we have a shortcut in our apps that reloads the FXML by doing Ctrl+F so we can reload changes instantly and are able to test the UI with fully working controllers as the FXML reloads (takes 2 seconds). So personally, I don’t miss SceneBuilder at all.\nI have also felt the JavaFX team has at times trying to set a too wider scope, specially when it comes to hardware acceleration, mobility, accessibility, but they are doing a good job overall hey. And it does seem they have energy to look into mobile device builds.\nSun supported swing, had traction and did a good job, we all loved Sun, as a whole, they always seems positive, creative, good hearted people. Went bankrupt though.\nOracle picked up Java, they have been doing more good to the JDK than Sun had in the 5 years prior to the merge, yes, we know what they are like with dollars, licenses and courts, but who is financially contributing to the JavaFX growth?, I recently looked into the SE support options and I am still trying to gather the 10K USD for commercial JavaSE support.\nFrom my point of view, I think we have gone way past the turnaround point of ejecting from JavaFX into a new UI, Oracle supported, JDK bundled UI toolkit. If you feel JavaFX doesn’t have traction, I don’t see Oracle even engaging on a ‘let’s start all over again’ java se desktop framework conversation at a cofee break.\nI am sure it could have been done better, like anything on this world, but I’d say that as a community, we are better off contributing and supporting to what is there today and taking it all the way to mobile builds than aiming at a new UI toolkit. After all, if we are looking at traction levels, how would a new UI toolkit from scratch would get the traction we are talking about?\nTalking of traction, I still don’t get my head around the node.js thing and having a 20 year old programming language for backend processing. I do see that there are more js / html developers (or maybe more the graphic designer profile) that think ok, hang on, I’ve learned javascript as part of my web designing career, now i can do backend logic myself with my javascript skills, fantastic, let’s go node.js but that is not me. I am happy with my JPA, JMS, EJBs.\nApple came up with this iPad tablet that had a super cool screen and an 8 hour battery life and everyone went insane with their iphone apps when the desktop environment was just deemed as out of fashion. I don’t think they planned for Objective-C’s traction. They may have planned for the iPad sales, but I doubt at the time of engineering the iPad people at apple could have predicted the boom in iOS apps that was about to happen.\nWhen it comes to ‘engineering’ the process of a framework’s traction, we can either approach it the software engineering way (maintainability, escalability, backwards compatibility, etc) or we can go left brain and do the rain dance to see if the way it implemented converts plumbers into develoeprs.\nPersonally, I always prefer to stick to core Java / Java EE frameworks than going too much out of the box into things like spring, or plain hibernate or propietary gui toolkits, the main reason for my view is based on long term maintenance and upgrade. Yes, the JSRs are always running a few years behind the frameworks with the actual creative ideas, but I just find it more cost effective in the short and long term. From training materials for develoeprs, to java certifications, to release notes, upgrade manuals, etc. Loosing a bit on those edgie latest features pans out to me.\nSame thing with the Jvm languages, how many jvm have come up in the last 7 years: redhat has one, scala, jruby, and even IntelliJ knocked one up, what are they going to do abou the traction of their -in deed more pracical than java- cool jvm language?\nSwing got tracking because Java was the word on the street then, at the time, everyone looked into JSRs and the Java community process, the community was more focused into the core releases (java, java ee, jsrs, jcp), today are way more scattered. May be be bacause java lost momentum in the last years of Sun , maybe because of the JDK license, may be because Android did what they did. But if we do want to concentrate our energies into a more focalised point, the most democractic option is still the JCP. With all the Apache piss off and with all the who trusts oracle, it is still the JCP. Except for Google and Apache, most of the big players are still there. The problem may be us, java community members that we have grown an ego thing against the JCP. Look at any other platform outhere, go .NET, that’s it, microsoft, not much open source. Go Apple, go the most propietary platform in the world. Go google, go Google Ads and boicot anything other than a web browser or Android.\nIf the entire java community started gravitating back to the JCP as it happened in the begining, we would be looking at lots of new vertical JSRs emerged from community driven proposals, a well organised, regulated, participative, collaborative community driven effort more estable, innovative, maintainable platform which would allow us to produce more with less effort while keeping the java programming language at it’s all time high.\nAbout the sacking of the evangelists, you probably know better Shai, but one thought that it came to my mind, is that java does seem to be picking up (i look at tiobe, not perfect, i know, but i look at it) and does have a self selling road map with modularity ahead of us. Not so sure how much evangelists were earning vs producing. But I think the features and evolution of java itself is the best form of evangelization. But yes, you probably know better what is happening over there.\nShai Almog — November 25, 2015 at 3:25 am (permalink) Shai Almog says:\nWow that’s practically a guest blog post 😉\nI get what you are saying entirely and I don’t think its in conflict with what I’m saying.\nRuRu — November 25, 2015 at 9:58 am (permalink) RuRu says:\nIn the defence of students and recent graduates, not all are attracted by JavaScript and Html. My self personally, I despise the idea of using something like JS (Node.js) in the backend and in general. I will use it for the front end in the website if my job requires to do so (Part time student software developer), but never in the backend, I would quit my job.\nThat’s for trusted languages that are designed to be used for the backend, such as Java. I am personally a Java fan boy.\nAs for JavaFX, it is a shame I never had a chance to really get into it, when I started programming I really wanted to be a Desktop developer, and it does sadden me the fact that everything is going web and cloud based. I only dealt with .NET such as WinForm for desktops. But even WinForms are decreasing in popularity and use.\nI hope Oracle makes fixes and supports JavaFX and desktop development a bit more.\nRuRu — November 25, 2015 at 10:03 am (permalink) RuRu says:\nThat would be great. Since Java is making a native Java MVC framework, for the JAVA EE (of course for the web). It could also transition to desktop with an API that allows good integration with object oriented features and great looking ui components. At least something I hope for\nSid — November 27, 2015 at 4:20 pm (permalink) Sid says:\nWhy does the Java community care so much about corporate backing? So what if Oracle has no interest in desktop Java. JavaFX is obviously better than Swing and open source too. Why can’t the community invest its efforts into making it a better product. Look at the Linux world. I don’t know of any billion dollar company that invests and promotes GNU utilities, KDE, GNOME, hundreds of distros and yet every such project has an active community around it no matter how small.\nShai Almog — November 27, 2015 at 4:51 pm (permalink) Shai Almog says:\nThat’s a great example of why corporate backing is essential. The Linux kernel is one of the rare true large scale open source projects that thrived before corporate backing. However, today saying that it doesn’t have corporate backing ignores the salaries top hackers get from major corporations. If you doubt the importance of that then look at BSD, Gnu Hurd etc.\nPretty much all of the major distros are backed by pretty big corporations. There are unaffiliated distros but they are pretty small by comparison.\nBut Gnome/KDE are far better examples… KDE didn’t have corporate backing and was winning.\nRedHat and most corporate Linux vendors standardized on Gnome and invested many millions into it. At Sun we specifically invested a huge amount of effort on many \u0026ldquo;unsexy\u0026rdquo; endeavors such as accessibility etc.\nThis was all part of a proxy war against Microsoft that the open source community benefited from.\nWe’re an open source company and I’ve been running open source projects for many years so I’m a big fan of open source. But the \u0026ldquo;oh open source it and let the community take over\u0026rdquo; is one of the things that crashed Sun.\nPablo Rodriguez Pina — November 30, 2015 at 7:49 am (permalink) Pablo Rodriguez Pina says:\n🙂\nPablo Rodriguez Pina — November 30, 2015 at 7:53 am (permalink) Pablo Rodriguez Pina says:\nJust to provide grounded evidence to Shai’s statement on open source crash, here is some archive video https://www.youtube.com/wat…\nFirst Last — March 27, 2016 at 11:02 am (permalink) First Last says:\nHahaha, the Flash to JavaFX/Swing interest chart is so dumb. Sorry but you are comparing widely known technology which is used as a runtime (and Googled for in that purpose) to a user-invisible technologies, only developers know. Hillariuos.\nShai Almog — March 27, 2016 at 11:11 am (permalink) Shai Almog says:\nFixating anonymously on one small pet peeve in an article that contains many solid arguments is what? Smart?\nJava was branded to users just like Flash. FX was branded as a user oriented technology for years with visual tools to compete with Adobe so no. Hell, I’ll even go further: https://www.google.com/tren… how dumb is that?\nOr maybe that: https://www.google.com/tren…\nI suggest working on your research skills and maybe making statements you wouldn’t be ashamed to make with your actual name.\nShai Almog — September 14, 2016 at 5:19 am (permalink) Shai Almog says:\nFlash performed very badly on Android devices as well one of its core problems was that it expected very specific behaviors from the low level drawing primitives. This can be mitigated in desktop GPU’s but not so much on mobile GPU’s which are both flaky and varied.\nFX has issues with desktop GPU’s and I doubt it has resources to deal with the huge complexity that is mobile. It is over ambitious. Being over ambitious is a problem as it creates an \u0026ldquo;all or nothing\u0026rdquo; situation. HTML/JS/CSS shares that over ambitious nature and has some failings because of that.\nShai Almog — September 15, 2016 at 4:15 am (permalink) Shai Almog says:\nThe goal of the post was to talk about the problems in FX not HTML. The fact that I don’t like HTML is a given…\nI detailed a lot of the problems in Gluon in a comment a while back: http://www.codenameone.com/…\nThis created an unpleasant exchange with a \u0026ldquo;colorfull\u0026rdquo; person who then proceeded to harass me personally going so far as to create fake accounts on dzone with word plays on my name and post insulting comments to every social network post we make. He is the first and only person we ever blocked from commenting…\nThe problems I detailed with Gluon just got far worse since I wrote what I did, they are now building their own OpenJDK AoT compiler which is insane. Besides the amount of work/maintenance which is already impractical, JavaFX depends on a huge number of classes and including them will produce binaries unfit for mobile distribution as iOS requires 2-3 platforms in a fat binary…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/should-oracle-spring-clean-javafx/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/should-oracle-spring-clean-javafx/should-oracle-spring-clean-javafx.jpg\"\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eIf anything, they are rearranging the deck chairs on the Hindenburg!\u003c/p\u003e\n\u003cp\u003eStephen Colbert\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eWe really depend on JavaFX at Codename One, our simulator needs it. Our desktop build uses it and our\u003cbr\u003e\ndesigner tool is based on Swing. We want it to succeed, its important to our business!\u003cbr\u003e\nWe are not alone, even if you are a Java EE developer and don’t care about desktop programming, keep in\u003cbr\u003e\nmind the fact that today’s desktop technology is tomorrow’s server technology.\u003cbr\u003e\nE.g.: C++ and Windows (a desktop technology) took the servers from Unix and C. Only to be replaced by\u003cbr\u003e\nJava (up until then a web based Applet language) and Linux. JavaScript might not look as a JavaEE contender\u003cbr\u003e\ntoday but as more developers come out of college liking JavaScript and not Java this will affect us all.\u003c/p\u003e","title":"Should Oracle Spring Clean JavaFX?"},{"content":"\nToday we dealt with some push messages overloading our servers, some of the apps developed in Codename One\nare remarkably successful and as a result our push servers got bogged down.\nTo mitigate that and prevent service interruptions we moved all push activity to the new servers, this effectively\nmeans that a push operation on the old servers will map to the new servers seamlessly. This also means\nthat we no longer support the null push target even for the old push servers. Its just too expensive to support\non scale of 150M+ devices.\nUnless you use null pushes this should have no effect on your code. It does mean though that we see the new\npush infrastructure as solid enough for production usage. We now recommend that you migrate\nto the new push infrastructure as that will increase the performance of your push by eliminating a stage\nin the push process and will remove a potential failure point. You should do that anyway in the long term so you\nmight as well do it right now…\nThe Next Step We intend to change the behavior of the registerPush call to return the new push key format\n(cn1-*) which will simplify our server code considerably and should work seamlessly with code that doesn’t\nmake assumptions about key length.\nE.g. up until now the servers would return a numeric device ID, so if you relied on this key being numeric or\nhaving a length below 20 decimals this won’t be the case anymore.\nThis is generally a good thing for moving forward as it will simplify the migration process to the new push servers\neven further.\nDeprecation Of The Old Push Servers The obvious question is when we will take down the old push server API support. This will not happen before\nthe 3.3 time line and probably not before the 3.4 timeline. When 3.3 rolls out (it is scheduled for January) we\nwould deploy server code that will let us know who is still using the old API and we will work with individual users\nof the old push API to migrate their code.\nIf you have device code that calls the Push API’s then we urge you to start migrating right away since\nyou would need to update all the client side calls. If this isn’t the case and you only initiate push from the server\nthen the migration process should be really simple. I can attest to that personally as it took us under an hour to\nmigrate our old push servers to use the new push service internally.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/migration-to-the-new-push-servers-completed/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/migration-to-the-new-push-servers-completed/push-megaphone.png\"\u003e\u003c/p\u003e\n\u003cp\u003eToday we dealt with some push messages overloading our servers, some of the apps developed in Codename One\u003cbr\u003e\nare remarkably successful and as a result our push servers got bogged down.\u003c/p\u003e\n\u003cp\u003eTo mitigate that and prevent service interruptions we moved all push activity to the new servers, this effectively\u003cbr\u003e\nmeans that a push operation on the old servers will map to the new servers seamlessly. This also means\u003cbr\u003e\nthat we no longer support the null push target even for the old push servers. Its just too expensive to support\u003cbr\u003e\non scale of 150M+ devices.\u003c/p\u003e","title":"Migration To The New Push Servers Completed"},{"content":"\nI’ve spent a lot of time working with and reviewing other cross platform tools this past month, mostly with Cordova\ndue to our recent announcement that\nwe support Cordova.\nI hope it doesn’t come off as too arrogant but our \u0026ldquo;onboarding\u0026rdquo; experience is pretty amazing in comparison\nto pretty much everything else. Just install IDE, type in Codename One and follow wizard for new app.\nThe only tools that are simpler than that are the rather limited web based solutions.\nBut we do fall short in one major way, our \u0026ldquo;hello world\u0026rdquo; apps look bad by default when compared to pretty much\nany tool out there. There are a lot of reasons for this but none of them are good reasons and this gives a horrible\nfirst impression to any developer picking up Codename One for the first time.\nE.g. this is what our new Hello Cordova demo looks like when creating a hello world on Codename One:\nWhat isn’t obvious in this screenshot is that the text on the bottom animates in a very pleasant subtle way\nto complete the experience. It just looks great and inviting to explore!\nBy comparison this is what we have today if you just use the new project wizard all the way thru without\nchanging the defaults:\nI think picking the flat blue theme as the default would be a slight improvement but this is not an inviting\nfirst impression. We created this because we think like developers (\u0026ldquo;get a hello world out\u0026rdquo;) but we should\nthink like a product where the end result matters.\nSeveral things need fixing here:\nDefault color scheme – the blue theme should be the default, lighter more inviting colors We need better more modern fonts by default – see below We need a more animated/image based output We still want to keep the code short and simple So right now this is what we have in terms of a new \u0026ldquo;hello\u0026rdquo; world, the Apple logo in dukes hand\nis replaced dynamically with android/windows logos:\nThe code for this entire thing is pretty small as well so it should be really easy.\nNotice that we will still have the plain hello world app, \u0026ldquo;we’ll just rename it to \u0026ldquo;barebones\u0026rdquo; which is more\nrepresentative of its function/use.\nSimpler Fonts Fonts have always been a hassle with Codename One because of the low end platform legacies. The main\nproblem is that even if we want to support something like truetype fonts only on smartphones, we still need\nto change rather complex API’s and the designer UI.\nWe normally just recommend that people embed a TTF file which solves the problem for some use cases, but\nits often not intuitive and doesn’t work well for the \u0026ldquo;good looking by default\u0026rdquo; goals stated above. Modern Android\ndevices have roboto font builtin to them and modern iOS devices have HelveticaNeue both are gorgeous fonts\nthat can really make a huge difference to an app.\nSo we introduced a new scheme into the Font.createTrueTypeFont method, if you use one of\nthe hardcoded font names on a device that supports it you will get a font object that is similar to a TTF loaded\nfont but was generated by the platform. To detect if a platform supports this use Font.isNativeFontSchemeSupported.\nThis might be challenging for most developers so we enhanced the designer to include all of the options:\nnative:MainThin, native:MainLight,\nnative:MainRegular, native:MainBold,\nnative:MainBlack, native:ItalicThin,\nnative:ItalicLight, native:ItalicRegular,\nnative:ItalicBold, native:ItalicBlack.\nEach option here maps to either roboto on Android or HelveticaNeue on iOS with the equivalent weight/italic\nbehavior.\nDetecting The Simulator/Simpler Crash Reports One of the long time requests we always had was detecting whether we are running in the simulator or not.\nIn the past no one opened an issue on that and most were OK with using some System.getProperty()\ntrickery.\nWhile these tricks work, they still have issues with the desktop port. There is also the very valid use case of\ndetecting the simulator to disable crash protection and to implement development time logic (e.g. skipping login process).\nWe now have a new method in Display: isSimulator which I would say is pretty\nself explanatory.\nOne of the triggers for this is the new Log.bindCrashProtection(boolean) API which ignores\nthe simulator and doesn’t bind crash protection logic there. This method accepts a boolean flag indicating whether\nthe exception on the EDT should be swallowed. It simply grabs all exceptions thrown on the EDT and sends the\nlog to us by email, its restricted to pro developers as part of the crash protection feature..\nMore Terse Layouts We added a lot of new terse layout API’s into the layout class specifically LayeredLayout now\nhas an encloseIn method of its own. So does FlowLayout, however it also added\nmany methods to allow enclosing in all the available variation of flow loyout types, specifically:\nencloseCenter, encloseRight, encloseMiddle,\nencloseCenterMiddle, encloseRightMiddle, encloseBottom,\nencloseCenterBottom, encloseRightBottom.\nNew Label Constructors We recently added the ability to create a Label with UIID and now we added the ability to\ncreate a label with both text and an image in a single constructor (I’m a bit shocked we didn’t have this).\nWe also added a constructor for text, image and a UIID. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — November 17, 2015 at 9:25 am (permalink) Chidiebere Okwudire says:\nThe new ‘hello world’ is definitely more attractive… Personally though, if feels less ‘CN1-like’. Why not the image/animation in the kitchen sink demo splashscreen? http://www.codenameone.com/… That includes the CN1 logo, a nice animation and is also pretty in my opinion.\nBTW: There’s a typo in the text: \u0026ldquo;Lets\u0026rdquo; should be \u0026ldquo;Let’s\u0026rdquo;\nShai Almog — November 18, 2015 at 3:43 am (permalink) Shai Almog says:\nThanks!\nFixed the Let’s typo.\nI liked the usage of the mascot that Cordova did and I always liked Duke, I think he is more recognizable than our logo. Being at JavaOne you see grown men stand in line for a photo-op with duke (and James Gosling who I guess is the human version of Duke). I did think about photoshopping a Codename One Tattoo on his belly though and I might just do it.\nThe beaker says to me that this is a Lab (like the kitchen sink was), its also a \u0026ldquo;one off\u0026rdquo; animation so if you run it and go get some coffee you come back and the animation is gone.\nbankifsc codes — December 15, 2015 at 4:53 am (permalink) bankifsc codes says:\nMobile tracker with name and address\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/good-looking-by-default-native-fonts-simulator-detection-more/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/good-looking-by-default-native-fonts-simulator-detection-more/new-hello-world-look.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve spent a lot of time working with and reviewing other cross platform tools this past month, mostly with Cordova\u003cbr\u003e\ndue to \u003ca href=\"/blog/phonegap-cordova-compatibility-for-codename-one.html\"\u003eour recent announcement that\u003cbr\u003e\nwe support Cordova\u003c/a\u003e.\u003cbr\u003e\nI hope it doesn’t come off as too arrogant but our \u0026ldquo;onboarding\u0026rdquo; experience is pretty amazing in comparison\u003cbr\u003e\nto pretty much everything else. Just install IDE, type in Codename One and follow wizard for new app.\u003cbr\u003e\nThe only tools that are simpler than that are the rather limited web based solutions.\u003cbr\u003e\nBut we do fall short in one major way, our \u0026ldquo;hello world\u0026rdquo; apps look bad by default when compared to pretty much\u003cbr\u003e\nany tool out there. There are a lot of reasons for this but none of them are good reasons and this gives a horrible\u003cbr\u003e\nfirst impression to any developer picking up Codename One for the first time.\u003c/p\u003e","title":"Good Looking By Default, Native Fonts, Simulator Detection \u0026 More"},{"content":"\nWe just released the first version of the open source\nCN1Cordova project on github. This\nmeans you can take a common Cordova/PhoneGap app, import it into NetBeans and\nbuild a native app using our cloud build servers without any changes!\nBefore we delve into the exact process of converting an app lets start by reviewing the exact benefits\nPhoneGap/Cordova developers can gain from Codename One. You can also check out the video tutorial and\nslides below.\nWhy Would I Want To Convert? What Advantages Does Codename One Hold For PhoneGap/Cordova Developers?\n____Build Cloud On Steroids\nCodename One provides a build cloud similar to PhoneGap build only far more advanced.\nIt can translate Java bytecode into native thus allowing you to write a great deal of your \u0026ldquo;native\u0026rdquo; API\nin Java instead of writing it again and again for every platform.\n____Better Native Code Support\nYou can and should write your \u0026ldquo;native\u0026rdquo; code in Java thus removing\nthe need to write Objective-C/Swift code when building a plugin. However, you can still use\ncn1lib’s and\nnative interfaces\nto implement pretty much anything using true native calls to Objective-C, Dalvik/ART runtimes.\n____Better Protection Of IP\nCordova/PhoneGap apps are effectively just a set of HTML/JavaScript \u0026amp; CSS files.\nSince native packaging is \u0026ldquo;just a zip file\u0026rdquo;, it triggered a cottage industry of unzipping such applications and reselling them thru\nother accounts/stores.\nIts much harder to do this for compiled applications, making the Java code in Codename One more opaque to the\ncasual hacker. If your application contains sensitive logic you can code it in Java for extra security. We are also considering\na hardened version of the PhoneGap integration that will encrypt the files within making the process even more secure.\n____IDE Integration Java – JavaScript – HTML\nNetBeans has remarkable JavaScript \u0026amp; html/css support. It\nalso supports all the common web frameworks such as react, angular etc. while being completely free…\nNetBeans is also one of the best Java IDE’s in the market and having one single all encompassing environment\nis a huge benefit.\n____Easy, Doesn’t Require A Mac, Automates Certificates/Signing\nCodename One’s environment works on Mac, Linux \u0026amp; Windows\nwithout a problem. One of the \u0026ldquo;killer features\u0026rdquo; of Codename One is the\ncertificate wizard that makes the normally nightmarish\nprocess of signing an iOS app, bare-able.\n____Migration To Java\nIf your team prefers Java you can move to a Java application in\nstages or even integrate pieces that are written in Java with Cordova elements.\nWhat Are The Limitations? The first version of the converter doesn’t currently translate plugins, it does have some builtin plugins for features\nsuch as camera etc.\nThis is something we intend to address soon so the translation process will be smoother.\nSince the native implementation of plugins in Codename One differs a great deal from native plugins in\nPhoneGap/Cordova there will be some manual work required to migrate plugins. Thankfully since most\nplugin functionality is already supported in the core Codename One Java API, this is relatively trivial work\nfor most cases.\nCurrently the browser component used in Codename One is based on the JavaFX browser component which\nis pretty awful. Its based on webkit but has many limitations in regard to full HTML5 compliance and doesn’t\ncorrectly specify things such as user-agent. It does work with most JavaScript frameworks correctly though.\nWe have plans to replace that component with a more mature browser component based on chromium\nif there is enough community interest to justify the effort.\nWhy Didn’t You Do This Sooner? We were (and still are) concerned about confusion. Codename One uses a rather elaborate architecture of\nconverting bytecode to native code. This is coupled with an OpenGL ES based rendering pipeline and native\nwidget mixing. Yet despite that fact and the fact that we specifically wrote in the top bar of the page that\nCodename One is NOT an HTML5 solution we still got the feedback of \u0026ldquo;well another HTML5 framework\u0026rdquo;.\nOur concern was that if we would include PhoneGap this confusion and ambiguity would just grow and hinder\nour ability to differentiate Codename One in a market dominated by 3 core ideas (HTML5, native \u0026amp; porting tool)\nas something that doesn’t fit in either one of those 3 pillars.\nHowever, a few months ago we started adding things like\nJavaScript support which uses\nTeaVM and our own set of complex libraries to facilitate\nWORA (Write Once Run Anywhere). Which makes our offering even more complex…\nFurthermore, at this point with so many other projects making noise about cross\nplatform mobile development, we came to the conclusion that \u0026ldquo;avoiding confusion\u0026rdquo; isn’t the right\nstrategy.\nDoes This Mean a Shift In Focus For Codename One? No!\nOur core competitive advantage has always been our huge API and client UI libraries, even with the support\nabove it is still one of the key advantages.\nPlaying with PhoneGap and some other tools these past few months has further cemented our conviction\nthat despite the fact that almost 4 years have passed since launching Codename One we are still in a league\nof our own.\nPorting A Cordova/PhoneGap app To Codename One Pre-requisites for this are: NetBeans IDE with the Codename One Plugin installed,\nJDK 8 (not Java JRE.. JDK!) \u0026amp; Apache Ant.\nDownload cn1-cordova-tools.zip\nand extract.\nFrom the terminal or command prompt\n$ cd cn1-cordova-tools $ ant create -Dsource=/full/path/to/cordova/app Note: make sure you are using Java 8 and if not make sure your JAVA_HOME environment variable points\nat the Java 8 home directory otherwise you might get an UnsupportedClassVersionError.\nAlso make sure you are using the full path to the Cordova app and not a short path or this won’t work (no relative\npaths etc.).\nThis will create Netbeans Project inside the cn1-cordova-tools directory with settings (package id and name)\nmatching the app specified in the -Dsource argument. The contents of the app’s\nwww directory will be copied to the project’s src/html directory.\nYou can open this project up in NetBeans to start working on it. You will be able to run and debug the Java\nsource files in the project. To send a cloud build or change project configuration just use the right click menu\nand select the correct options.\nAs mentioned above plugins won’t be imported. If the app has plugins installed, you’ll see a warning printed.\nFuture versions should add support for this in some form (e.g. replacing well known plugins with Codename One plugins).\nThere is already support in Codename One for developing Cordova plugins and distributing them as cn1libs\n(Codename One’s native library/plugin format). We will publish the instructions for this as the integration matures.\n**Codename one Cordova/PhoneGap Support ** from Shai Almog Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nsao — November 12, 2015 at 10:33 am (permalink) sao says:\nThis is great feat.\nAfam Okonkwo\nshannah78 — November 12, 2015 at 3:57 pm (permalink) shannah78 says:\nNice video and slides, Shai. One note: You should be able to use relative paths for the -Dsource parameter. You just can’t use the \u0026ldquo;~\u0026rdquo; tilde shorthand for home directory. Paths like \u0026ldquo;../myapp\u0026rdquo; or \u0026ldquo;myapp\u0026rdquo; should work though.\nValeriy Skachko — November 29, 2015 at 2:18 pm (permalink) Valeriy Skachko says:\nHi! I have some strange error.\nCreate cordova app – ok Porting A Cordova/PhoneGap app To Codename One -ok Launch on emulator – ok Send build – Updating libraries – ok, build succesfull After that if i run on emulator i see next:error: cannot find symbol\ntheme = UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;);\nsymbol: method initFirstTheme(String)\nlocation: class UIManager Now i cant run on send build after Updating libraries Shai Almog — November 29, 2015 at 2:47 pm (permalink) Shai Almog says:\nThat’s odd maybe there was a regression here.\nCopy over the jar files on top of the existing jar files (both JavaSE.jar and the jars in the lib directory).\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/phonegap-cordova-compatibility-for-codename-one/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/phonegap-cordova-compatibility-for-codename-one/cordova.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe just released the first version of the open source\u003cbr\u003e\n\u003ca href=\"https://github.com/codenameone/CN1Cordova\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCN1Cordova project\u003c/a\u003e on github. This\u003cbr\u003e\nmeans you can take a common Cordova/PhoneGap app, import it into NetBeans and\u003cbr\u003e\nbuild a native app using our cloud build servers without any changes!\u003cbr\u003e\nBefore we delve into the exact process of converting an app lets start by reviewing the exact benefits\u003cbr\u003e\nPhoneGap/Cordova developers can gain from Codename One. You can also check out the video tutorial and\u003cbr\u003e\nslides below.\u003c/p\u003e","title":"PhoneGap/Cordova Compatibility For Codename One"},{"content":"\nA common trick for animating Components in Codename One is to set their preferred size to 0 and then invoke\nanimateLayout() thus triggering an animation to hide said component. There are several issues\nwith this trick but one of the biggest ones is the fact that setPreferredSize has been deprecated\nfor quite a while.\nWe recently added a setHidden/isHidden method pair that effectively encapsulates\nthis functionality and a bit more. This shouldn’t be confused with setVisible/isVisible\nthat just toggle the visibility of the component.\nOne of the issues setHidden tries to solve is the fact that preferred size doesn’t include the margin\nin the total and thus a component might still occupy space despite being hidden. To solve this the margin is set to 0\nwhen hiding and restored to its original value when showing the component again by resetting the UIID\n(which resets all style modifications).\nThis functionality might be undesired which is why we have a version of the setHidden method that\naccepts a boolean flag indicating whether the margin/UIID should be manipulated. You can effectively\nhide/show a component without deprecated code using something like this:\nButton toHide = new Button(\u0026quot;Will Be Hidden\u0026quot;); Button hide = new Button(\u0026quot;Hide It\u0026quot;); hide.addActionListener((e) -\u0026gt; { hide.setEnabled(false); boolean t = !toHide.isHidden(); toHide.setHidden(t); toHide.getParent().animateLayoutAndWait(200); toHide.setVisible(t); hide.setEnabled(true); }); Notice that in the first/last lines of the event processing I block the button from getting additional events. Since\nthe code is sequential this works rather well and the button won’t get duplicate events during the animation.\nCodename One currently doesn’t support concurrent animations so its up to you as a developer to serialize\nyour animation requests in the framework.\nAccessing Insecure URL’s In iOS 9 Due to recent security exploits Apple blocked some access to insecure URL’s which means that http code that\nworked before might stop working for you on iOS 9. This is generally a good move, you should use https and\navoid http as much as possible but that’s sometimes impractical especially when working with an internal\nor debug environment (setting up SSL is a pain).\nWe considered adding the required build hints by default but it seems that Apple will reject your app if you just\ninclude that and don’t have a good reason. We could have done it for debug only but then people might have\nrun into it in production.\nThe solution at the moment is to use the venerable ios.plistInject build hint and set it to:\n\u0026lt;key\u0026gt;NSAppTransportSecurity\u0026lt;/key\u0026gt;\u0026lt;dict\u0026gt;\u0026lt;key\u0026gt;NSAllowsArbitraryLoads\u0026lt;/key\u0026gt;\u0026lt;true/\u0026gt;\u0026lt;/dict\u0026gt;\nRead more about this in the discussion forum post.\nNew Advocacy Group We’ve posted about this to the discussion forum but if you subscribe via email it might have gotten buried.\nIf you want to help Codename one and its related 3rd party projects by contributing at most 5 minutes per\nday please join this group.\nThru this group we (and you if you have a Codename One relevant project such as an advocacy site, tutorial,\nlibrary or blog post) can post links and ask for social help: e.g. upvote, like, share, retweet, etc.\nWith social networks its pretty hard to get your voice out as people get drowned with messaging from all directions.\nIn this way we can both help you guys to get noticed by the community at large and you can help us to spread\nour message further thru social clout.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/hiding-url-security-advocacy/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/hiding-url-security-advocacy/hiding-security-advocacy.png\"\u003e\u003c/p\u003e\n\u003cp\u003eA common trick for animating Components in Codename One is to set their preferred size to 0 and then invoke\u003cbr\u003e\n\u003ccode\u003eanimateLayout()\u003c/code\u003e thus triggering an animation to hide said component. There are several issues\u003cbr\u003e\nwith this trick but one of the biggest ones is the fact that \u003ccode\u003esetPreferredSize\u003c/code\u003e has been deprecated\u003cbr\u003e\nfor quite a while.\u003c/p\u003e\n\u003cp\u003eWe recently added a \u003ccode\u003esetHidden\u003c/code\u003e/\u003ccode\u003eisHidden\u003c/code\u003e method pair that effectively encapsulates\u003cbr\u003e\nthis functionality and a bit more. This shouldn’t be confused with \u003ccode\u003esetVisible\u003c/code\u003e/\u003ccode\u003eisVisible\u003c/code\u003e\u003cbr\u003e\nthat just toggle the visibility of the component.\u003cbr\u003e\nOne of the issues \u003ccode\u003esetHidden\u003c/code\u003e tries to solve is the fact that preferred size doesn’t include the margin\u003cbr\u003e\nin the total and thus a component might still occupy space despite being hidden. To solve this the margin is set to 0\u003cbr\u003e\nwhen hiding and restored to its original value when showing the component again by resetting the UIID\u003cbr\u003e\n(which resets all style modifications).\u003cbr\u003e\nThis functionality might be undesired which is why we have a version of the \u003ccode\u003esetHidden\u003c/code\u003e method that\u003cbr\u003e\naccepts a boolean flag indicating whether the margin/UIID should be manipulated. You can effectively\u003cbr\u003e\nhide/show a component without deprecated code using something like this:\u003c/p\u003e","title":"Hiding, URL Security \u0026 Advocacy"},{"content":"\nWe’ve been working on some pretty exciting things recently trying to get them out of the door. As part of\nthat work we added some API’s specifically one that probably should have been a part of Codename One 1.0:\nProperties file support…\nWorking with properties files under Codename One should be identical to working with them under standard\nJava only instead of using java.util.Properties we need to use com.codename1.io.Properties.\nThis allows the implementation to be updated more easily and more consistent across platforms. We\nalso fixed some minor historic behaviors in properties e.g. making it derive from HashMap\u0026lt;String, String\u0026gt;\ninstead of Hashtable which makes it both faster and removes the need for casts when working\nwith it!\nI find properties to be much easier to work with than XML for simple key/value cases.\nTerseness Continues I’ve been on a terse code mission for a while, trying to reduce verbosity in our code which now thanks to lambdas\nis truly standing out. As you recall we added an encloseIn API to Container,\nthis allowed great code like:\nContainer c = Container.encloseIn(new BoxLayout(BoxLayout.Y_AXIS), myFirstCmp, mySecondCmp, myThirdCmp); Which is way better than:\nContainer c = new Container(new BoxLayout(BoxLayout.Y_AXIS)); c.addComponent(myFirstCmp); c.addComponent(mySecondCmp); c.addComponent(myThirdCmp); But its still not great, the part that bothered me is the layout creation code… What we really need is the layout\nand this allowed me to re-think this API and instead come up with this:\nContainer c = BoxLayout.encloseY(myFirstCmp, mySecondCmp, myThirdCmp); Which I think expresses what we are trying to do just as well, while removing some boilerplate. Obviously there is\nalso an encloseX method to correspond. I’ve also encapsulated a similar common use case for BorderLayout\nusing:\nContainer c = BorderLayout.center(centerCmp); Which is equivalent to:\nContainer c = new Container(new BorderLayout()); c.addComponent(BorderLayout.CENTER, centerCmp); Another long term pet peeve I addressed was that Form is missing a layout constructor. This\nis problematic especially due to the fact that we repeated Swing/AWT’s mistake of using FlowLayout\nas the default layout!\nIn terms of performance this means that every form created allocates a FlowLayout and then\nallocates a new layout to replace it. By adding the layout for the content pane in the constructor we effectively\nsolve that issue and reduce a line of code.\nAnd finally I also added an add(Image) method to Container which is similar\nto the add(String) method and is really a shorthand for add(new Label(img)).\nIts not a big deal but small things like that make the code slightly more readable. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\ndavidwaf — November 4, 2015 at 9:35 pm (permalink) davidwaf says:\nProperties are so so welcome !\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/properties-continued-terseness/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/properties-continued-terseness/cross-platform-shoes.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve been working on some pretty exciting things recently trying to get them out of the door. As part of\u003cbr\u003e\nthat work we added some API’s specifically one that probably should have been a part of Codename One 1.0:\u003cbr\u003e\n\u003ccode\u003eProperties\u003c/code\u003e file support…\u003c/p\u003e\n\u003cp\u003eWorking with properties files under Codename One should be identical to working with them under standard\u003cbr\u003e\nJava only instead of using \u003ccode\u003ejava.util.Properties\u003c/code\u003e we need to use \u003ccode\u003ecom.codename1.io.Properties\u003c/code\u003e.\u003cbr\u003e\nThis allows the implementation to be updated more easily and more consistent across platforms. We\u003cbr\u003e\nalso fixed some minor historic behaviors in properties e.g. making it derive from \u003ccode\u003eHashMap\u0026lt;String, String\u0026gt;\u003c/code\u003e\u003cbr\u003e\ninstead of \u003ccode\u003eHashtable\u003c/code\u003e which makes it both faster and removes the need for casts when working\u003cbr\u003e\nwith it!\u003c/p\u003e","title":"Properties \u0026 Continued Terseness"},{"content":"\nI got into a discussion with a colleague on the Java vs. JavaScript subject, which is a problematic subject to\nbegin with. He then mentioned how great React Native is, I decided I have to look into it and maybe grab\nsome ideas for Codename One.\nThere are some nice ideas there, but none of them is revolutionary or exceptional and most of them are pretty\nold news for Codename One developers running in Java 8.\nOne thing I did like was how short the React demo code seemed to be, so I ported it to Codename One and ended up with roughly the same amount of code and arguably better/simpler code! Check out the full listing at the end of the article or in the github project here, but lets first review why the Java code is \u0026ldquo;better\u0026rdquo;.\nSynchronous Execution JavaScript fans hate this but its still a fact that synchronous code is simpler to read, follow and debug. E.g. this\nis the React Native version of the code that fetches the data:\nfetchData: function() { fetch(REQUEST_URL) .then((response) =\u0026gt; response.json()) .then((responseData) =\u0026gt; { this.setState({ dataSource: this.state.dataSource.cloneWithRows(responseData.movies), loaded: true, }); }) .done(); }, I have well over 20 years of professional programming experience and this is still hard to follow. Apparently if\ndone() is omitted you won’t get any error handling?\nIts weird and error prone. I feel like a lot of code is hidden behind this which makes the terseness more\nconfusing than simplifying (kind of like following a political debate thru Twitter).\nTo me our code is way simpler:\nreact.add(BorderLayout.CENTER, new InfiniteContainer() { public Component[] fetchComponents(int index, int amount) { try { Collection data = (Collection)ConnectionRequest.fetchJSON(REQUEST_URL).get(\u0026quot;movies\u0026quot;); Component[] response = new Component[data.size()]; int offset = 0; for(Object movie : data) { response[offset] = createMovieEntry(Result.fromContent((Map)movie)); offset++; } return response; } catch(IOException err) { Dialog.show(\u0026quot;Error\u0026quot;, \u0026quot;Error during connection: \u0026quot; + err, \u0026quot;OK\u0026quot;, null); } return null; } }); Notice that this isn’t the exact equivalent of the code above as we also create components, add them to the UI\nand handle the resulting error!\nA more fair comparison would be:\ntry { Collection data = (Collection)ConnectionRequest.fetchJSON(REQUEST_URL).get(\u0026quot;movies\u0026quot;); ... } catch(IOException err) { ... } That’s effectively one line of code that could even be shorter after which we have the result… No flow, no callback!\nDevelopers often pour hate on the Java checked exceptions feature and I have to agree that they are sometimes painful.\n(f’ing InterruptedException is stupid) but this is a great example of why checked exceptions matter.\nWe MUST handle errors properly and we can’t just ignore it until our code reaches production with this\nlovely \u0026ldquo;TODO\u0026rdquo; comment that no one bothered reading.\nOne Language – Less Code The listings seem roughly equivalent in size but you will notice the react code ignores the native platform\nspecific code when dealing with the JavaScript code. Our listing is all encompassing, no additional code is needed\nand no further boilerplate, projects etc.\nReact Native takes this even further by mixing tags with the JavaScript code effectively mixing declarative code into\nthe regular flow. Yes it shortens the code, but also removes a huge part of the value of declarative programming\nwhich is the separation of responsibilities.\nReload == Apply Code Changes React Native can be debugged by reloading which is there to help when working with the awful Android emulator.\nLuckily Codename One doesn’t need that emulator, you also don’t need to restart your app to reload compiled changes… E.g. in NetBeans just use \u0026ldquo;Apply Code Changes\u0026rdquo; in the debugger and your changes are instantly mirrored into a running app.\nScripting Languages Are Problematic \u0026ldquo;On Device\u0026rdquo; This isn’t quite a \u0026ldquo;React Native\u0026rdquo; specific rant, its related to all tools packaging JavaScript in the app bundle.\nScripting languages are great for the web, they are like \u0026ldquo;duct tape\u0026rdquo;. Show me a hacker who doesn’t LOVE duct tape!\nThe temptation to ship an app built with such duct tape is big, but unlike the web where you can just fix that \u0026ldquo;weird undefined\u0026rdquo; bug in production by deploying a new update. With apps you need to go thru Apples approval process… This means production bugs that stay while you watch your rating drop.\nYes, unit tests, lint and a lot of other solutions are supposed to catch those things but when you use a modern IDE and it detects potential null inference thanks to the strict language syntax its pretty amazing!\nE.g. a great example for JavaScripts over simplification of problems would be in code like this:\nfunction reduce(var a) { if(...) { a = a - 1; } else { a = a + 1; } } If this was Java code we could tell exactly what would happen here… In JavaScript this isn’t quite the case!\nLets assume that due to a bug a was somehow a string that is \u0026quot;11\u0026quot; as long as the condition is true (which might be the case in all test cases) this will act like a number. E.g. a will become \u0026quot;10\u0026quot;.\nBut in production if the condition becomes false for some reason a would become \u0026quot;111\u0026quot;.\nIf a represents something of value (e.g. debt, credit etc.) having an app with this bug in the store\ncould be really painful.\nEnvironment React native uses the native development environments which means it needs a Mac for iOS development.\nIt also means you do part of the work in the Android IDE, part of it in Xcode and the JavaScript work using a\ntext editor.\nIts amazing to me that developers are willing to throw away 30 years of IDE evolution for some syntactic\ncandy???\nAre we that traumatized by Eclipse?\nTodays IDE’s are amazing and the fact you can track/debug your entire code via a single IDE is invaluable.\nThe ability we have as a team to instantly see who used what and for what purpose is astounding, I can’t fathom how something like this can be used by a team of more than 2 people especially in a distributed workforce.\nWhat I Liked About JavaScript The one thing I really like about working with JavaScript is the ease of working with JSON, while in the code below I reduced it significantly almost to the same size it’s still not as elegant.\nI’m still not a fan of duck typing or scripting languages but I’d really like to get something like property objects into Codename One and improve the integrated parsing.\nFinal Word One of the problems I find with terse programming is that people use it to hide basic concepts so too much happens in an \u0026ldquo;unspoken\u0026rdquo; way. This makes terse code as easy to read as a Tweet, unfortunately if you need to express even a moderately complex idea Twitter just doesn’t cut it and that’s a big problem with some of these API’s.\nReact native has its fans, after all its probably better than PhoneGap which has its own set of limitations. But its\nstill a limited concept standing on the chicken legs of a scripting infrastructure. It has no real advantage when\ncompared to Codename One and has some obvious potential issues.\nJava Listing public class ReactDemo { private static final String REQUEST_URL = \u0026quot;https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json\u0026quot;; private Form current; private EncodedImage placeholder; public void init(Object context) { UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;); } public void start() { if(current != null){ current.show(); return; } placeholder = EncodedImage.createFromImage(Image.createImage(53, 81, 0), false); Form react = new Form(\u0026quot;React Demo\u0026quot;, new BorderLayout()); react.add(BorderLayout.CENTER, new InfiniteContainer() { public Component[] fetchComponents(int index, int amount) { try { Collection data = (Collection)ConnectionRequest.fetchJSON(REQUEST_URL).get(\u0026quot;movies\u0026quot;); Component[] response = new Component[data.size()]; int offset = 0; for(Object movie : data) { response[offset] = createMovieEntry(Result.fromContent((Map)movie)); offset++; } return response; } catch(IOException err) { Dialog.show(\u0026quot;Error\u0026quot;, \u0026quot;Error during connection: \u0026quot; + err, \u0026quot;OK\u0026quot;, null); } return null; } }); react.show(); } Component createMovieEntry(Result data) { Container entry = BorderLayout.center( BoxLayout.encloseY( new SpanLabel(data.getAsString(\u0026quot;title\u0026quot;), \u0026quot;Line1\u0026quot;), new Label(data.getAsString(\u0026quot;year\u0026quot;), \u0026quot;Line2\u0026quot;))). add(BorderLayout.WEST, URLImage.createToStorage(placeholder, data.getAsString(\u0026quot;id\u0026quot;), data.getAsString(\u0026quot;posters/thumbnail\u0026quot;))); return entry; } public void stop() { current = Display.getInstance().getCurrent(); } public void destroy() { } } Write Once, Run Anywhere. Truly native cross-platform app development with Java or Kotlin for iOS, Android \u0026amp; Web. Get Started\nWhy Codename one? Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — November 2, 2015 at 10:20 pm (permalink) bryan says:\nI think you’ll need to be wearing your flame proof suit for a while – the Javascript guys always seem to take great exception to anyone dissing their baby.\nWhat you say about throwing away 30 years of IDE development is so true. I came across this http://www.fse.guru/how-to-… the other day, and I thought to myself, back the day you could use Delphi, say, to develop a desktop app, and now to develop a web app you apparently need a 1001 bits of stuff, to create something that in almost every way is inferior to a desktop app. Weird.\nShai Almog — November 3, 2015 at 4:27 am (permalink) Shai Almog says:\nThey REALLY hate me on Reddit 😉\nI can take it, otherwise I wouldn’t have written it.\nThat’s part of why we started Codename One, it seems innovation in this space is busy taking us backwards.\noojr — November 7, 2015 at 10:15 pm (permalink) oojr says:\nES7 async functions is coming next year and would make the code look even better, Javascript is shaping up to be \u0026ldquo;The Next Big Language\u0026rdquo; https://jakearchibald.com/2…\nShai Almog — November 8, 2015 at 4:23 am (permalink) Shai Almog says:\nIts been brought to my attention that JavaScript fans can’t read my code and misunderstand me when I say that the code is sync…\nWhat I mean is that the code \u0026ldquo;looks\u0026rdquo; synchronous but really works like async code by running on the event dispatch thread and yet allowing for events etc. to still process seamlessly. That’s a pretty neat trick called invokeAndBlock:\nhttp://www.codenameone.com/…\nhttp://www.codenameone.com/…\nI think JavaScript has its place as an important language, but even huge JavaScript fans find it hard to create large maintainable projects in it. The question of where the line passes where you probably should switch to a more \u0026ldquo;strict\u0026rdquo; language like Java (Scala if you prefer a more dynamic language etc.) is a matter of personal choice.\noojr — November 10, 2015 at 4:04 pm (permalink) oojr says:\nI went into a large corporation that had several lines of Java server code and discovered that \u0026quot; large maintainable apps in Javascript are harder to do than a language like Java\u0026quot; is a huge myth, writing several modular components that work seamlessly together is hard in any language, it is all about preference and what will make you more productive. Uber’s codebase is mostly Javascript/Node.js and they seem to be doing just fine at scale. It is better to have a language that has optional type checking than strict.\nBack to the blog though, I use React Native and can code in Objective-C and Java, why? React Native allows me to use a flexbox layout and has all the benefits of an open source platform/ecosystem\nShai Almog — November 11, 2015 at 5:26 am (permalink) Shai Almog says:\nI would tend to agree that you can write horrible messy code in any language and great code in any language. Developer skills are important.\nOne \u0026ldquo;illness\u0026rdquo; that Java developers have is over abstraction and over complicating everything, but it seems JavaScript developers have picked up some of that flu as well see: http://geek-and-poke.com/ge…\nAbout Uber, its a startup hence no legacy code maintenance and highly controlled architecture. Keep in mind that no corporation will advertise the \u0026ldquo;pain\u0026rdquo; of working on their codebase.\nBack to the blog post, Codename One has been open source since its inception (which was far before react native was even conceived) and has had flexible design layouts that work for all devices from before that.\nIf you prefer JavaScript as a language that’s totally fine, to each his own. The blog post is aimed at Java developers who sometimes get the sense of \u0026ldquo;the grass is greener\u0026rdquo; when JavaScript developers talk about how X is easier. That’s just not the case.\nJeff Carver — January 16, 2016 at 8:06 pm (permalink) Jeff Carver says:\nHi Shai,\nI ran across information about Codename One while researching Google Flutter. CN1 looks interesting but Java is one of the few languages I never bothered with. Someone in an earlier post mentioned Delphi and I still think that was the greatest language/IDE ever created.\nAnyway, for someone who has focused mainly on Actionscript, Javascript, and PHP for the last several years, what suggestions could you provide for getting started in Java and CN1? I guess I’m trying to figure out how comfortable one has to be with Java before attempting to use CN1.\nI have already evaluated numerous other products in this space including React Native, Native Script, and various HTML/PhoneGap platforms. The best I’ve found so far is Tabris.js but it doesn’t appear to have any serious backing, is almost completely unknown, and thus may not be around for long.\nThanks in advance for any information.\nShai Almog — January 17, 2016 at 4:39 am (permalink) Shai Almog says:\nHi,\nWe’re all big Java advocates around here and have been doing Java for so long we don’t even remember learning Java. So we’re possibly the worst possible reference for getting started if you don’t know Java to begin with.\nFor complete newbies there is http://codapps.io/ but I think it will be too simple for you as its designed for people with no coding experience.\nJava is a relatively simple and strict language so this might be a bit of a culture shock when coming from loose languages like JavaScript. Also a lot of our code/demos predate the Java 8 support so a lot of those would look very verbose to a guy coming from that background.\nSince you already know several languages I think just picking up Java and looking at the code should be pretty intuitive without an explicit tutorial but I don’t really know…\nvoid777 — January 25, 2016 at 11:19 pm (permalink) void777 says:\nJava works for iOS apps?\nShai Almog — January 26, 2016 at 3:13 am (permalink) Shai Almog says:\nAhem https://www.codenameone.com/\nadamski — January 30, 2016 at 9:30 pm (permalink) adamski says:\nI’m not a massive Javascript fan but I do think React Native has hit a good spot. I am using it for cross-platform UI and the core of my app is written in C++ with the JUCE framework. This gives me the best of both both worlds, tight performant code where I need it and quick to build UI across mobile platforms.\nHad I heard of Codename One before I started I might have given it a look 🙂\nGabriel Matusevich — March 11, 2016 at 6:43 am (permalink) Gabriel Matusevich says:\nhmmmmm I think you are being a bit unfair, react native has … a few years of development and it’s already cruising, also you are not talking about Rapid App Develpoment, with React Native I’m able to write apps in MUCH less time not to mention that Android Development in Java is a ginormous pain, with React and Redux, mobile dev is a paradise in comparison.\nShai Almog — March 12, 2016 at 3:28 am (permalink) Shai Almog says:\nI’m comparing it to Codename One which has only a slight advantage in terms of years so this is totally fair.\nAndroid development does suck. One of the problems in React Native is the fact that you need to setup an Android environment to get started.\nSimon — March 12, 2016 at 5:02 am (permalink) Simon says:\nWow I think you have to be a particular breed to think that the Java was simpler than the React code. For one it was about seven times as long and as soon as I see stuff like ‘public void’ and ‘private static final’ I have the urge to go running for the hills.\nShai Almog — March 12, 2016 at 5:12 am (permalink) Shai Almog says:\nIt isn’t longer as shown in the sample above its roughly the same size. Notice that Java 8 syntax is pretty terse when used effectively.\nYes there is some boilerplate but boilerplate isn’t program logic hence doesn’t add to complexity.\nType safety is commonly accepted as a preferable way for a large number of developers (e.g. Typescript) so if you prefer Java (which great many do) then React Native doesn’t add any advantage. If you prefer JavaScript then this becomes a religious debate as there is no debating programming preference.\nSimon — March 12, 2016 at 5:18 am (permalink) Simon says:\nActually its just over twice as long, (I did a character count in a text editor). Yes that’s what I mean by a ‘particular’ breed ie programmers. Anyone more casual will likely prefer javascript. But React Native is far from being just javascript.\nShai Almog — March 12, 2016 at 5:41 am (permalink) Shai Almog says:\nDid you include the embedded XML? Did you include their bootstrap files which aren’t listed in their code but do exist there? Our code is pretty complete (with the exception of the package/import statements) so it includes all the UI and lifecycle code. Their examples rely on some generated files that aren’t listed.\nJava IDEs make Java MUCH easier for novices and type safety removes a lot of newbie mistakes. For experienced developers the ability to refactor a Java application from a stranger is a huge advantage. So I would argue that Java is WAY easier than JavaScript but I’m obviously highly biased. Every coin has two sides and I gave the example above of JSON processing which JavaScript’s ducktyping really simplifies.\nSimon — March 12, 2016 at 5:49 am (permalink) Simon says:\nYou can’t include things that are embedded or not listed ‘cos they don’t bother you or make things more complex. The more stuff that is embedded or behind the scenes, the easier it is to just get on and program and the code itself looks much more simple.\nI truly wish Java was simpler ‘cos I would love to learn it. Tried and failed. Actually my favourite is PHP which is even more straightforward that javascript. I actually prefer Javascript variants like JQuery and React Native. The less characters typed to achieve something, the simpler it appears.\nShai Almog — March 12, 2016 at 7:34 am (permalink) Shai Almog says:\nDoes it not bother me?\nYou need to control lifecycle in any non-trivial application so it being hidden in a separate file is pointless. I could break my sample into two files and achieve the exact same results as react native so that doesn’t really measure anything realistic.\nIf you don’t like Java then you are clearly not in the demographic I aimed this article at. It’s aimed at people who like and appreciate Java and its advantaged but are looking at React Native thinking the other side of the fence might have greener pastures.\nAlex — March 28, 2016 at 2:36 am (permalink) Alex says:\nI just threw up in my mouth a little.\nadamski — April 6, 2016 at 8:17 pm (permalink) adamski says:\nReact Native is only partly about Javascript. Its more about the architecture. And the amount of 3rd party modules available via npm. And the amazing developer community, that i’ve not seen anything like before.\nI’ve settled on RN for the UI of my app, and thought its not been without its hurdles I feel like its a good way to do cross platform mobile development. I’m actually more comfortable writing C++11 (the other half of the app is in C++) than Javascript but since ES6 and ES7 things are looking much better. Yes it still has its warts but so does every other language in one way or another. I started writing my app UI in Swift for iOS with the intention to write the Android UI in Java but RN looked like a much better proposal to save rewriting all the UI logic for each platform. I’d have given your product a spin if I’d known about it sooner.\nYour comment \u0026ldquo;With apps you need to go thru Apples approval process\u0026rdquo; is not true for javascript only updates – there are tools to enable pushing javascript only updates to installed apps thereby circumventing the Apple approval process.\nShai Almog — April 7, 2016 at 3:18 am (permalink) Shai Almog says:\nYou can say that about any major framework. E.g. Java itself is not about Java as much as the JVM… The Java developer community has it’s own benefits so I wouldn’t go into an argument over those.\nDynamically downloading JavaScript is something that used to be prohibited, this makes sense as it somewhat eliminates the value of the human review process. Notice that you still can’t push out real updates and need to go thru review if you make major changes although it’s unclear how Apple can enforce such distinctions once they opened that door.\nOsei Fortune — April 7, 2016 at 8:19 pm (permalink) Osei Fortune says:\nI think typescript should help make large JavaScript projects easier to maintain\nDon\u0026rsquo;t Bother — April 20, 2016 at 11:22 am (permalink) Don\u0026rsquo;t Bother says:\nJavascript are harder to do than a language like Java\u0026quot; is a huge myth…\nIt’s not a myth it’s a sad truth. The reality is that on large JavaScript project people just afraid to make any serious refactoring because you never know what will break and when. I have experienced this many times. If you have not seen this it means you have not seen any large and complex project.\nDon\u0026rsquo;t Bother — April 20, 2016 at 11:24 am (permalink) Don\u0026rsquo;t Bother says:\nTrue but TypeScript is a not JavaScript. It is different language. And it has huge difference which is defined by world \u0026ldquo;Type\u0026rdquo; :-), and it has other things which are not present in JavaScript. It is same as if you say that Swift will make javaScript apps easier…\nChromonav Kulkarni — April 26, 2016 at 7:21 pm (permalink) Chromonav Kulkarni says:\nbro decide are you novice or a pro. Javascript is for people who learnt everything and are in search of superpowers.Js because of fluidity and simplicity and ability to implement suitable programming design pattern needed to get things done.\nChromonav Kulkarni — April 26, 2016 at 7:30 pm (permalink) Chromonav Kulkarni says:\nJava is a beautiful language and carefully designed with gr8 toolset; but lets face it: Javascript happened to be in middle of web evolution. It has simply evolved to a whole new level.\nOldies like you may not appreciate beauty and simplicity of current javascript ecosystem.\nBut theres one thing you should keep in mind : Atwoods Law:\nAny application that can be written in JavaScript will eventually be written in JavaScript. 😜😜\nChromonav Kulkarni — April 26, 2016 at 7:46 pm (permalink) Chromonav Kulkarni says:\nlets compare community following, rate of growth, current apps in production.\nShai Almog — April 26, 2016 at 8:06 pm (permalink) Shai Almog says:\nSo was Java, livescript was renamed to JavaScript to pick the traction of Java. Either way this isn’t so much a Java vs. JavaScript but rather a React Native vs. Java. So all/most of your points aren’t really relevant here. If you embed JavaScript in a native app you open up a lot of problems and lose a lot of benefits of JavaScript.\noojr — April 27, 2016 at 5:21 am (permalink) oojr says:\nTrue but you can say that about any large Java projects as well\nChromonav Kulkarni — April 27, 2016 at 2:21 pm (permalink) Chromonav Kulkarni says:\nReact Native inherits all the features of javascript essentially it is javascript++\nReact way of combining all concerns and dividing of problem has one major advantage:\nCode Reuse.\nThe massive scale of code reuse possible and with a vibrant Js community it is possible to production ready apps within fraction of time.\nReact Native inherits powers of both worlds and combines it with awesome react way (i love i don’t know abt you.)\nChromonav Kulkarni — April 27, 2016 at 2:24 pm (permalink) Chromonav Kulkarni says:\nEnd justifies the means. React works well for Facebook helps them churn feature updates faster. It is helping me the same way. I don’t care if i am going backwards and forward\nShai Almog — April 27, 2016 at 2:25 pm (permalink) Shai Almog says:\nSo it inherits DOM access?\nCan I take JavaScript code off the internet that relies on CSS and have it work?\nNope…\nIt’s either native or it’s web. React Native stands in the middle and it pays for that, compile time, build process, install native tools etc. It has some benefits from JavaScript (fast preview etc.) but don’t try to present it like a panacea.\nBen — May 9, 2016 at 9:31 pm (permalink) Ben says:\nSeveral moot arguments here:\nThe proposed async/await syntax is supported by default. You needn’t trifle with promises and can wrap fetch calls in try/catch blocks.\nSynchronous live reloading is supported, however, hot reloading will swap out individual components in realtime.\nJSX is completely optional, and compiles to plain JavaScript React.createElement() calls. These calls can easily be sugared using React.createFactory().\nFacebook’s own Nuclide.io is conspicuously missing from the Environment debate, as is the wealth of open source modules available from NPM. Facebook Flow is likewise excellent for terse static type support replete with compile time errors, and Jest was built specifically to unit test React components.\nAfter installing the Android SDK and necessary APIs, it takes only several brief commands to bootstrap then run a React Native app using the provided CLI. The same can be said for physical devices.\nI’m aware some of these features may not have been implemented or mature last November, but would like to ensure nobody is given a wrong or unilateral impression should they wish to try React Native.\nShai Almog — May 10, 2016 at 4:08 am (permalink) Shai Almog says:\nI don’t think react native lacks in the department of advocacy or visibility so if people get the wrong impression about it this usually biases in the other way.\nNotice that you need to install the Android SDK and then the iOS SDK and then the Windows SDK and then rewrite for web… You also need to adapt code as it isn’t a WORA solution… We actually allow you to install one plugin and it \u0026ldquo;just works\u0026rdquo; on everything.\nkhle — June 25, 2016 at 12:14 pm (permalink) khle says:\nInteresting take. You probably knew this would be an unpopular opinion. Anyway, I didn’t read through all the comments so maybe someone else already said this. But one advantage with React Native is the same skill set can be used to write web applications. And with JS, one can write NodeJS on the back end. So maybe the same devs can do mobile, web and back end. For some companies, this could be advantageous.\nShai Almog — June 26, 2016 at 4:50 am (permalink) Shai Almog says:\nIf you bring server programming into it then Java has a huge upper hand with more than a decade of scale in the enterprise and far more diversity there…\nNicolás Schürmann Lindemann — July 5, 2016 at 12:25 am (permalink) Nicolás Schürmann Lindemann says:\nJava 8 seems to have a lot of good features now!, i remember back in the old days making an ajax call in java was a pain!, even trying to simplify it with libraries was difficult. I agree that strong typing adds a lot of ease in development and mitigates bugs. I think that the only complain about this is that you are comparing 2 synchronous codes while the JS call is being asynchronous. And also is the implementation of promises and the fetch API in ecmascript 6. Also the promises API implements a \u0026ldquo;catch\u0026rdquo; method that is used for errors management (therefore, no try/catch) it accept functions as callbacks so you can compose more easily. The code that you written was very imperative. Also the advantage/disadvantage of javascript is in fact the loose typing. Some loves it, others hate it. It gives you a lot of freedom in expresion, but you can get bugs that you will only get in production unless you do a lot of testing or add strong typing (typescript, flow).\nI believe that something like this may be more comparable and will let understand the benefits of promises and js:\nfetchData: function() {\nfetch(REQUEST_URL)\n.then(toJson)\n.then((responseData) =\u0026gt; dispatch(updateRows(responseData)))\n.done();\n}\nand with a helper:\nconst disp = fn =\u0026gt; data =\u0026gt; dispatch(fn(data))\nfetchData: function() {\nfetch(REQUEST_URL)\n.then(toJson)\n.then(disp(updateRows))\n.done()\n}\nI think it’s cleaner, less imperative though.\nWhoIsMeekMill?\u0026amp;kidcudi — August 2, 2016 at 6:16 pm (permalink) WhoIsMeekMill?\u0026amp;kidcudi says:\nJust another java/android developer feeling threatened that his market is disappearing. Nothing to see here folks.\nbertbeck — August 13, 2016 at 3:54 pm (permalink) bertbeck says:\nHow much overhead (in app size) does Codename One add to a typical app (over native size) ? Any idea what is typical for React Native? I’m an IOS and Android developer – have worked with Xamarin – know all too well the pain of added and complex runtimes (and bugs created by the runtime by new releases). I’m looking for the best environment to co-develop IOS/Android and if possible Web and Native PC/OSX/Linux\nShai Almog — August 14, 2016 at 4:19 am (permalink) Shai Almog says:\nCodename One Android apps are roughly 1mb and iOS apps between 3-5mb for hello world.\nSo the overhead is relatively low. There are fluctuations in the implementations which is why we have versioned build which allows pro users to build against a stable release.\nyedidyak — August 21, 2016 at 8:47 am (permalink) yedidyak says:\nYou can simplify the JS asynchronous code by using async await, which is supported in React Native. The examle above would become:\nasync function fetchData() {\nconst responseData = await fetch(REQUEST_URL).json();\nthis.setState({\ndataSource: this.state.dataSource.cloneWithRows(responseData.movies),\nloaded: true,\n});\n}\nFar simpler.\nShai Almog — August 22, 2016 at 3:25 am (permalink) Shai Almog says:\nThat does change the syntax and we use it quite a bit in our JavaScript port. But it doesn’t really change the language semantics. Native API’s rely on threads and the ability to control them, this is true both for Android and iOS. JavaScript relies on hiding the complexity of threads.\nThere is a conceptual disconnect.\nShailesh — September 17, 2016 at 1:25 am (permalink) Shailesh says:\nSuch a misleading title. Comparing Java and javascript is totally different than comparing react-native with codename. The reason react-native is way superior is because of react component model. Building complex UIs is such a breeze in react. It is a lot lot simpler to keep the UI in a consistent clean state in react compared to other frameworks where finding the view and updating it, keep it in sync is such a pain.\nShai Almog — September 17, 2016 at 4:11 am (permalink) Shai Almog says:\nCodename One is Java based and shows what can be done with Java for mobile. It’s not as known as Java so I chose to use Java in the title since a lot of the arguments (specifically terseness) relate to improvements in the Java language.\nCleanliness is up to the programmer more than anything.\nWhat you are talking about is separation of concerns which sounds great. Until you try to use it in real life and need access to this thing from that place which you didn’t expect and you end up crossing the language barrier of the separation with constant zigzags. This makes grepping your code for issues and sources a huge pain.\nConcerns can be separated by convention as well all good programmers do that anyway and they don’t need a separate UI representation to perform that in Java. The big advantage in doing everything in Java is that I can place a breakpoint anywhere and inspect Java based UI state right in the debugger, I can mutate/animate the UI with the same code/syntax I use to construct it which makes refactoring much easier.\nIsMyBlueYourBlue — October 11, 2016 at 5:58 am (permalink) IsMyBlueYourBlue says:\nHmmm weird I don’t know why you say Java is simpler. For me the Javascript version is A LOT easier to read. I only have 7 years professional programming, is that a problem…?\nHristo Vrigazov — October 23, 2016 at 2:28 pm (permalink) Hristo Vrigazov says:\nI think my opinion would be pretty interesting… I started with Ionic and created a few apps, (have not written in React), and I like a lot of concepts in both JS and Java. To me, Codename One gives you more control, although more verbose. It is extremely easy to reuse code in Codename One due to the fact that you have the full OOP power with all its patterns etc. What is also cool is that you just use the IDE you know (IntelliJ in my case), and you can just send iOS, Android and Windows builds in the cloud and this way not to worry about configurations. Codename One also has amazing support. Javascript frameworks on the other side are very convinient with things like parsing JSON, callbacks, promises, which to me simplify the web, but these things can be used in Codename One also, if one wants, although slightly verbose. JS frameworks also have a lot of third-party frameworks that simplify things a lot (Codename One also has CN1 libs, but there are not as much out there). In my opinion, one should go the way that he likes best. For example, in my current app, I am actually integrating Codename One with Node.js backend, since the Loopback framework makes it so easy to quicky create REST APIs. No need to choose guys, learn the best of both worlds, don’t be close-minded.\nShai Almog — November 1, 2016 at 1:11 am (permalink) Shai Almog says:\nI used the react tools and Microsofts C# tools and xcode and Codename One… Obviously I’m biased but I am informed.\nUsing Visual Studio is like traveling back thru time for a person using a modern Java IDE, it’s like using Eclipse after you used NetBeans or IntelliJ. It constantly fails on basic things, doesn’t provide valuable hints and its debugger is just plain painful (inspecting variables etc.). So while I see the theoretical logic of comparing it to Java I can tell you that in practice Java is far more refined.\nAtom is surprisingly good as an editor, in fact I use it a lot for asciidoc editing. But it’s no IDE. Most JavaScript tooling isn’t nearly in the same level. When I talk to JavaScript devs they argue about the \u0026ldquo;need\u0026rdquo; for tooling. As a guy who started Java during the beta of 1.0 I can totally sympathize, I used a text editor and command line rather than use C++ and preferred it over visual studio of the day (was it visual studio 92 back then?). Anyway, I was right at the time but when tooling came to Java they brought productivity to a completely different level and they might eventually do the same for JavaScript. JavaScript needs tooling more than Java because the code hides far more meaning than the Java code.\nThat’s what you missed about the code problems in JavaScript. The problem is that the Java code is very clear in its intention you point at X in the IDE and the IDE will tell you it’s an integer. In JavaScript you don’t even know what \u0026ldquo;this\u0026rdquo; is.\nReact native itself has a slew of other issues, it has one nice thing with is the live preview/update. That is something we have in the simulator with \u0026ldquo;apply code changes\u0026rdquo; but it’s still pretty cool to have it \u0026ldquo;on-device\u0026rdquo;.\nI’m not sure if our tooling will be simpler for you since obviously there is a \u0026ldquo;filter\u0026rdquo; when picking up any technology and getting your brain used to it’s \u0026ldquo;oddities\u0026rdquo; and if you are not a Java guy to begin with the habits might be too deep. But our tools are WAY simpler and that’s obvious even during the installation phase not to mention in final projects where the IDE can literally show you the where \u0026amp; what of everything.\nJustin L Mills — November 9, 2016 at 4:42 pm (permalink) Justin L Mills says:\nCan I code Haxe Java for Codename, Haxe can allow you to access most jars via -java-lib. Obviously you feel there are some advantages of your system over React Native but I could also use Haxe JS with React-Native, so what’s left beyond IDE’s when you consider some of the cross target Haxe libraries like Kha, OpenFL, Flambe, SnowKit etc… do you still feel that Codename One – a paid product offers something extra that Haxe developers might want to tap into for mobile development? It’s not a retorical question I am curious as I am aware that Haxe ecosytem does lack component support in many areas but at sametime is maybe nicer than Java or Javascript as a language 🙂 . Perhaps you could take a proper look and write another post around use of haxe with Codename One against maybe other options like Haxe c++ and Haxe JS wrapped.\nShai Almog — November 10, 2016 at 5:03 am (permalink) Shai Almog says:\nIn the past there was a guy in the forum who ported Haxe to Codename One but hasn’t followed up. Codename One is an open source product with a commercial SaaS on top. I would argue that’s better than a completely free product as it guarantees professional continuity and support.\nI’m not familiar enough with Haxe and I’m not really sure why one would pick it. But lets do it the other way… You try Codename One and write a guest post from a Haxe developers perspective?\nJustin L Mills — November 10, 2016 at 11:33 am (permalink) Justin L Mills says:\nIt seems I need to install lots of tools and it’s not really clear how I might use Codename One using just Textmate and Terminal, since fancy tools are great but would get in the way of a proof of concept of mixing Haxe with Codename One.\nAn old tutorial of mine on using Slick and lwjgl jars with Haxe.\nhttp://old.haxe.org/doc/jav…\nSo is there a Jar file for the Codename One components, that I could hook up to the Haxe and then a way to wrap the haxe jar up and send to your conversion servers?\nIn terms of React there are native externs support for Haxe and some addons, Haxe probably has better strict typing than Java, being a bit more functional inspired so the js typing issues disappear.\nhttps://github.com/tokomlab…\nhttps://github.com/kevinres…\nAt moment where I work I am not excited by the android solutions looking inside put me off learning Android java, so expect Codename One approach might do better, my collegue is creating React/Reflux touchscreen app, and feels it’s simpler than the AIR approach we have used for Kiosks in the past. So I would really be interested to know if Codename One could be easily hooked up to Haxe Java and I could prototype a similar Kiosk app with it, but I have no interest in coding in Java or really Javascript 🙂 And the docs online do not really give me the information I would need to set up a project that used Haxe Java for application code.\nHaving learnt code through flash, I am not convinced by the closed source support arguments you use, since I saw Adobe largely desert as3 developers. But I know at work they love the C# backend supported approach, so there are swings and roundabouts, often closed provides better tooling, but you can’t branch the project if you don’t like where it’s going.\nBut don’t expect you have time to setup a codename one haxe java demo but I would be very curious if you did.\nShai Almog — November 11, 2016 at 7:22 am (permalink) Shai Almog says:\nThere is actually very little to install for Codename One but using it without the tooling goes a bit against the grain of what we are trying to accomplish. Codename One has far fewer dependencies than any other tool out there and is really just an ant project with no external dependencies other than a couple of jars.\nI’m not sure I can help you with Haxe as it’s not a point of interest/focus for us. If you don’t like Java then Codename One might not be the best solution for you at this time.\nThe Adobe argument doesn’t fit since Adobe didn’t open source flash. Codename One is open source (including the VM, ports etc.)… It’s more like Android in that sense.\nJason Nathan — December 18, 2016 at 12:41 am (permalink) Jason Nathan says:\nMy sentiments exactly. I think a deep dive into JS is needed to make a proper comparison. The Promise and \u0026ldquo;then\u0026rdquo;-problems described are really the woes of someone newly discovering JS, for example.\nShai Almog — December 18, 2016 at 4:45 am (permalink) Shai Almog says:\nWe use futures in our JavaScript port. Nope.\nie5x — January 11, 2017 at 10:29 am (permalink) ie5x says:\nI am not sure why you are comparing a language with a tool? Shouldn’t you either be comparing codenameone with React Native,\nor Java with JavaScript?\nAnyways, using async/await syntax which is completely supported in React-Native –\nfetchData: async function() {\ntry {\nlet response = await fetch(REQUEST_URL),\nresponseData = response.json();\nthis.setState({\ndataSource: this.state.dataSource.cloneWithRows(responseData.movies),\nloaded: true,\n});\n}\ncatch (err){\nthis.setState({\nerror:err,\nloaded:false\n});\n}\n},\nDone!\nShai Almog — January 12, 2017 at 5:08 am (permalink) Shai Almog says:\nI did compare with Codename One. Java has better name recognition so I used it for syndication purposes.\nThe async/await approach was mentioned in other comments. It’s not exactly a thread alternative more like futures which is fine but not the same.\nNitin Bansal — February 4, 2017 at 7:39 pm (permalink) Nitin Bansal says:\nIf JavaScript was/is so great, then why has it started to seem more and more like Java after ES6? And so goes for Java too, where it has started to seem more like Python after Java8. The fact is none of the languages were perfect. But, as time lapsed, and so the programmers’ experience in using these languages, and also the fact that current projects require exposure to more than one language, people have started adding more and more best features from other languages. Hence, java introduced lambdas and functional interfaces, while javascript introduced classes, which it hated at one time so much. Newer languages such as Go and Rust and Swift already come with balanced set of these features. As time goes by, we’ll see more of unite among the way languages handle their syntax, getting more and more diversed on where they fit best.\nShai Almog — February 5, 2017 at 8:17 am (permalink) Shai Almog says:\nI agree there is a lot of convergence, it’s an artifact of taking a language designed for one purpose and re-purposing it after the fact.\nThe languages are still very different especially when it comes to types, encapsulation etc.\nStan — February 8, 2017 at 5:41 pm (permalink) Stan says:\nand I’m willing to bet that Facebook has got a whole bunch of lower level code to suplement the javascript. I’ve been a software engineer for over 2 decades and have coded in many languages (C/C++, Ada, Fortran, Pascal, assembler, etc) and I’ve been coding Java since 1998 and by far, it’s still me language of choice hence which is why I’m starting to use Codename One. Not knocking Javscriipt because I like that as bwell and have been using it since t6he early 2000s but not much comparison to java as a heavyweight language.\nStan — February 8, 2017 at 5:44 pm (permalink) Stan says:\nTotally agree and has anybody heard of this new phenomena called \u0026ldquo;Javascript Fatigue\u0026rdquo;? It’s dizzying the number of frameworks, libraries, packagers and add ons that one must know…\nanonymyst — February 17, 2017 at 11:51 pm (permalink) anonymyst says:\nYa well Java doesn’t hold a candle to Swift. Besides, your claim may be true in some ways, but in the way that’s most glaring and important to most, is speed… I’ve got junior dev react native programmers that can code outcomes much faster than your senior dev java developers. Another way in which it fails, is in it’s inability to deliver a consistent user experience across 2 platforms… react native gives my clients a single codebase, which makes better business sense, so in that sense, it’s a major fail for both Java and Swift. So I’d hold back in speaking in such extremes as \u0026ldquo;superior in every way,\u0026rdquo; because it makes you sound biased and ignorant.\nShai Almog — February 18, 2017 at 5:59 am (permalink) Shai Almog says:\nTo each his own. I don’t like Swift personally and even if you are a big fan of the language it needs years to reach the maturity level of Java in tooling, 3rd party support, resources etc.\nI agree that a lot of Java programmers tend to \u0026ldquo;overthink\u0026rdquo; problems especially when it comes to the monstrosity that is Java EE. There is a cultural problem there. In JavaScript react you have the exact opposite of patchwork and unawareness of production/security problems that might occur. I’m sure that you are comparing react programmers to native Android programming which is horribly broken.\nI am biased (notice the site you are on) but I’m quite well informed.\ncarlos — March 21, 2017 at 7:41 pm (permalink) carlos says:\nHi Shai,\nA quick peak at your CodenameOne looks great. In the past I’ve done a lot of Java client side development but I think you should know that React Native is way better than using Java because it provides an evolved way of developing GUI client software. I mean your method looks and feels like the 90’s when Swing was the state of the art on GUI development. Techniques have evolved to include a combination of imperative and declarative techniques as well as auto binding data. There are several Javascript frameworks that use these techniques (Angular, Aurelia, Ember, etc) but React is by far the simpler and most powerful of the bunch and hence why it is so popular.\nUse React Native to develop a full blown app and experience what is great about it and hopefully you can incorporate that into your CodenameOne system.\nBest of luck.\nCarlos.\ncarlos — March 21, 2017 at 7:48 pm (permalink) carlos says:\nYes, and Webstorm is a fantastic Javascript IDE\nShai Almog — March 22, 2017 at 4:57 am (permalink) Shai Almog says:\nHi,\nyou are comparing Swing an old and outdated implementation of the idea with new implementations of JS frameworks so naturally the former will feel old and the latter will feel new.\nThe imperative nature of these frameworks isn’t there in the name of progress, it’s in place to workaround the oddities and pains of the DOM/JavaScript combo. Imperative frameworks are problematic as they are harder to learn and debug due to the underlying \u0026ldquo;magic\u0026rdquo;.\nWhere do these imperative frameworks provide any real world concrete advantage?\nThey aren’t more terse (as I demonstrated more than once).\nThey aren’t easier to debug or understand since their flow isn’t linear. So where is the progress?\ncarlos — March 22, 2017 at 6:29 pm (permalink) carlos says:\nShai,\nYour system, CodenameOne, is new so it should feel new but instead it looks like old technology using old techniques. You could had done something like JavaFX or better yet React Native but you are doing things like Swing !!! Your choice.\nYou got imperative and declarative mixed up. Markup is declarative, Java is imperative, React combines amazingly imperative and declarative techniques.\nThe imperative nature of these frameworks isn’t there in the name of progress, it’s in place to workaround the oddities and pains of the DOM/JavaScript combo.\nWrong. Their declarative nature has nothing to do with pains of DOM/Javascript. React Native has no DOM. Adobe Flex uses declarative techniques without DOM, so does JavaFX, etc.\nImperative frameworks are problematic as they are harder to learn and debug due to the underlying \u0026ldquo;magic\u0026rdquo;.\nWrong. Some of these frameworks are harder to learn and debug but React is super simple and easy to debug, reason, read, etc. Do you think that it would take off like this if it was hard?\nWhere do these imperative frameworks provide any real world concrete advantage?\nCode is simpler (and faster) to read, write, maintain, debug, better architecture, re-use, scale, etc\nThey aren’t more terse (as I demonstrated more than once).\nYour ‘demonstration’ is a joke. Do a full app, with UI building code and event handling, etc. Do something like this: https://github.com/junedomi…\nThey aren’t easier to debug or understand since their flow isn’t linear. So where is the progress?\nWrong. You really need to actually learn something new and appreciate why it is better than what was before. You sound like a proud horse carriage owner praising its advantages over the car. Pride is preventing you from reaching your full potential.\nCarlos.\nShai Almog — March 23, 2017 at 6:23 am (permalink) Shai Almog says:\nCodename One is based on work we did at Sun Microsystems during the time JavaFXScript was developed. So it predated JavaFX and React by several years. JavaFX’s failure and counter-innovation is something I just don’t want to go into as it’s a long and deep argument.\nThere are quite a few things I’d like to correct here but I’m pretty busy with the bootcamp to write something extensive. Our system mixes some concepts from UI and model like Swing used to. Some developers might think that’s old… The fact that iOS/Android take that approach natively (because they are old?) is probably important.\nReact is simpler than doing barebones AJAX but it’s not simpler than just coding the UI directly. Not every idea that comes later and fits into a new structure is better e.g. Linus came back with monolithic kernels years after the debate for microkernels \u0026ldquo;won\u0026rdquo;. The reason for Reacts success relates to the problems of the system it is layered on top.\nWe took an age old solution to a common problem and provide a lot of advantages/capabilities you just can’t do with React Native (and yes I based this code on the react tutorial demo so I’m very aware of what’s there).\nRick — April 8, 2017 at 10:08 pm (permalink) Rick says:\nBut aren’t you missing the whole point? I hardly believe anyone will claim that non native code is better than the real deal.\nBut React is a response to a time when we have a highly fragmented UI market (thanks Apple Store, Google Play, etc).\nThe idea is to leverage device homogeneity and at the same time minimize the performance impact as much as possible. Here React is just very good. You can quickly code an average mobile app in a short time that will run with minimal changes, if at all, on various devices. Try keeping a solid dev team with frequent releases using native only.\nAnd either you like it or not, functional style programming is very important now, more than ever actually. Functional style programming leverages the computing power of multi-core systems and aides with concurrency issues to render them almost trivial. Even the event driven paradigm helps with linear code design by dropping the need for stateful concurrency marshaling entirely. The code you say is hard to read is not when you learn how to go about these paradigms.\nAnd how about the top-down data flow model in react? This means no event/data cross binding hell.\nI have 19 years experience in this field, so I’m almost as old as you in this regard. And I repeat, I acknowledge you do have very good points, but your blog doesn’t make sense to me. It’s like comparing cars to planes A Ferrari is definitely an immensely better machine at its job than a Cessna, and although both address the same common need, transportation, they both respond to different circumstances and socio-historical driving forces. The Cessna is able to solve the much more sophisticated need for fast travel vs convenience vs cost debacle, and that is the point.\nShai Almog — April 9, 2017 at 4:02 am (permalink) Shai Almog says:\nCodename One is more native than React Native. On iOS code is translated to native code and compiled using XCode not run thru JavaScript JIT. On Android Java is running directly on the Android VM. We allow embedding native widgets (e.g. Google Maps etc.) so in most aspects Codename One is more native.\nHowever, let me attack the \u0026ldquo;native is best\u0026rdquo; dogma that has undertaken our industry. That dogma didn’t exist 10 years ago. It came to be because iOS UI’s were so radically different there was no other way, the same was true for Android. Over the years both Android and iOS converged a lot. The cross platform tools have also made great strides and are now rivaling native.\nThe fact that you can take a design, caching system and features quickly everywhere is huge in terms of delivering fast functionality and update to your user base. Update speed for applications is probably more important than anything in mobile.\nI’m not a fan of functional programming for real applications. It’s great for math but without encapsulation or imperative style it becomes a maintenance problem down the road. The idea that multi-core will be leveraged by this style is one that the JS crowd has been pushing for years, it \u0026ldquo;might\u0026rdquo; be valid for NodeJS but it’s not for react native where the UI is single threaded and any bit of \u0026ldquo;adventure\u0026rdquo; off the main UI thread will demolish you. Our GC \u0026amp; networking run in their own threads and make use of multi-core and since our EDT is separate from the main OS thread we leverage multi-core better while increasing portability.\nlambdatoast — May 18, 2017 at 10:42 pm (permalink) lambdatoast says:\nYou don’t have to have your codebase in JavaScript when using React Native (e.g. I’m using React Native and the code I write is in a language whose static type system is light years ahead of what Java will ever reach).\nSo this blog just post amounts to you showing that that bit of Java code that’s more familiar to you (and which has type checking, although caveman era-type checking that doesn’t track side-effects in the types, and is therefore doomed to become a pain to reason about as it grows…. sorry, that’s the Haskeller in me, ranting), reads better to you than that dynamic language garbage they used in the React Native example.\nBTW not only are we able to use something other than JavaScript with React Native, but we can even use plain old JavaScript, and for the parts we choose, add type annotations in the comments, and have FB’s Flow type check it statically, aaaand Flow’s type system is already more advanced than Java (as in stronger type guarantees. e.g. isn’t it pathetic how Java can’t type-track uses of NULL at compile time. Ugh).\nBTW, to all peoples interested in static typing: Please check out something like PureScript + React (or React Native, or both), in order to understand why languages like Java remain in the dark ages of static typing. Do NOT get your idea of what types can do for you based on OOP languages like Java, which ruin all typing guarantees with their out-of-control side-effects.\nShai Almog — August 14, 2017 at 7:07 am (permalink) Shai Almog says:\nNo. It’s the exact same number of lines and works perfectly on iOS. Clearly you haven’t read what I said.\nThe logic can be shared just as well in Java or even better… Great you can share 80% of the styles in CSS (I call bullshit but fine) in Codename One you can share 100% of the styles.\nAlbert Gao — October 9, 2017 at 4:15 am (permalink) Albert Gao says:\nReact native could share codes across web and native, even for the UI (Production ready for a long time and already some big names did that in production like MS and Airbnb). And it has an unique pattern to encapsulate the related UI and logic into a component. These are something CodeNameOne just can’t compete with.\nBut I do see the use cases for CodeNameOne, as our company, we have a web site which is not based on react stack, and we adopted kotlin in part of our back-end. It makes CodeNameOne perfect sense for us when considering a solution for delivering mobile app. And as I can see from the doc, CN1’s app life cycle is pretty straightforward and easy to understand for a mobile developer.\nI just wish you guys could:\n1. Make the import of kotlin lib (coroutine and reflection) viable, so we could use CN1 to write an app while still use our existing kotlin libs.\n2. Wish the new UI designer could work with kotlin soon, come from a python cross-platform framework named Kivy, any time you start to code the UI via code (not only python, for java, kotlin, javascript…). It makes you such a pain when the UI becomes complex. I can see the UI designer will generate a XML which is a good sign.\n3. Add some 2-way binding or at least 1-way binding mechanism to lessen the code to write.\nThere are always good thing to take from new tech or ideas. Use that to strengthen CodeNameOne would be better.\nShai Almog — October 9, 2017 at 7:59 am (permalink) Shai Almog says:\nI think a better place for this is in the kotlin post as it relates more closely to that. We can compile codename one apps directly to JavaScript with no code changes so I’d say we are way ahead if what you are trying to do is build an app and not a website.\nI think partial code sharing is problematic, you end up having to constantly test any change to shared code lowering the value of the reward. A lot of the abstractions and patterns of react are there since there to abstract issues in the underlying platform. Abstraction is less valuable when you have one common abstraction for everything, when that exists you can just work directly and get more platforms as a result.\n1. I’m not sure about the complexities of those. I think some of that should be portable.\n2. That’s doable. The main obstacle for doing this is people/resources.\n3. We have a properties binding framework, it’s oriented at Java but might work well for kotlin see: https://www.codenameone.com…\nAlbert Gao — October 9, 2017 at 8:08 am (permalink) Albert Gao says:\nThanks for the reply. If I understand you right, it’s more like a web-first or app-first approach difference now 🙂 And CN1 is the latter, makes sense now 🙂 Will surely look into that properties binding framework, as far as I can see, my simple example works really well with Kotlin.\nAnd thanks for the reply. You are very responsive for my questions which split over places 😀 (And you are even more responsive than some big name open source project) Your attitude to the product will SURELY help my evaluation! Appreciate!\nnathan32 — October 13, 2017 at 7:54 am (permalink) nathan32 says:\nI think the biggest disadvantage of codename one is the \u0026ldquo;Environment\u0026rdquo;. React Native is truly opensource. As for mac version we can buy a mac mini and set it up like a server for the whole office and it costs me just $499, that equals just 6 months of professional subscription we pay for codename one. If we’re uncomfortable or prohibited by client contract from uploading the content to a 3rd party server we shell out $399 each month, honestly we can equip my whole office with macs in what we would pay CN1.\nAs for horrible Android emulator, React Native provides an easy way to build app using Expo and even preview it on ios/android mobile using the Expo client (https://expo.io/)), So just scan the code and it shows a preview on the device. Any code changes is reflected instantly on the device. That one feature has made our lives a lot easier. Easy DOM manipulation is good for business apps interacting frequently with a backend.\nExcept for that I find both toolkits similar, the standard gui principles are used. It boils down to the language of your preference (both JS and Java fall on the disliked side of things for me).\nWe went with React Native for just those reasons, If you could provide a truly opensource toolkit we’d have been on the side of Codename One. A simple VBox image of a pre-configured server would make CN1 more popular, to test this just release one vbox image and see for yourself. Just the response to a linux based server for android builds might surprise you.\nShai Almog — October 13, 2017 at 8:20 am (permalink) Shai Almog says:\nYour response reads like one of someone who has made up his mind and is trying to justify it. Just in case it isn’t here’s the way I see it:\n– We are 100% open source just like react native. No less. React native doesn’t have build servers and sharing a Mac doesn’t really give you anything remotely close to that experience. Saying that this piece which doesn’t exist in the open source project is the reason we aren’t as open is like me saying that React Native’s VM isn’t open source like our VM’s are.\n– You can get a basic subscription for your office for less than a cost of a Mac if all you care about is the build server functionality. Having said that the pro subscription includes FAR more features than that and full support. That’s something you can’t buy fro any amount of money in react. You can’t pay Facebook (not a 3rd party) to give you professional support.\nWith the enterprise subscription you buy a lot of things that go well beyond offline build, specifically you buy partial control over the direction of the project and a direct line to us. There are many other features besides offline build etc. Its meant for enterprises not startups so if price is an issue don’t buy it. The fact that there are paid options is an advantage for us, not a disadvantage.\n– We support Kotlin not just Java although Java is the main target. We could support any language supported by the JVM from Ruby to Jython to Scala etc. There is even a nifty guide Steve wrote explaining the steps he took in porting Kotlin (FYI he also added unofficial support for Mirah a few years back): https://www.codenameone.com…\n– There used to be a 3rd party offline build project, we hired its maintainer (not to stop the project, he’s just a really great hacker). When that project ran very few people used it, it might still work but most people don’t really care about that stuff so the last paragraph should be reversed. \u0026ldquo;You would be surprised\u0026rdquo;.\nnathan32 — October 13, 2017 at 8:52 am (permalink) nathan32 says:\nNo its not, until you are using custom native modules refer https://facebook.github.io/… You can simply use expo client (https://expo.io/)). The opposite however is a point of concern. I can do a native build in case of React Native while Codename One native builds though not impossible are costly as hell $400/mo. I can dedicate a machine for doing builds for that amount. So effectively for one month of Codename One Build server I can get a react one for lifetime.\nShai Almog — October 13, 2017 at 10:00 am (permalink) Shai Almog says:\nNative builds in Codename One are between free (with quota limits) to 19USD per month with no limits. I have no idea why you decided the $399 enterprise version is needed when about 1% of our users actually pick that option. From that 1% very few use the offline builds which even our promotional material recommends against see: https://www.codenameone.com…\nAgain you totally ignore the fact that you can use our source code for free and that it delivers pretty much everything. You also ignored all the other points I made.\nAbout expo, that is indeed a nice feature. We have a proof of concept that will allow something similar in Codename One (on-device-debugging) without the build cycle. Unfortunately this would require some work to bring to production.\nShai Almog — November 7, 2017 at 11:01 am (permalink) Shai Almog says:\nJohn. We make our money through the SaaS product which is our chief source of income. That guarantees sustainability unlike a company like Facebook or Google both of whom proved they have no problem throwing away a product used by millions because it didn’t gather revenue… We only support push notification in the pro level but if you look in the parse plugin for Codename One you will find that this isn’t a requirement there. It’s not something we advertise as we can’t guarantee it but it works fine.\nThere are also people and projects by third parties who use our source code to build their apps, if you look in our discussion group just the other day a user posted about a free plugin for building apps. Naturally that isn’t a sustainable model and you can’t expect us to support it.\nLegally we can’t publish \u0026ldquo;vbox images\u0026rdquo; as we can’t re-distribute Mac OS or Windows. Your assumption that our backend application is something a human being can reasonably setup with a guide off the internet is incorrect. Our architecture is ridiculously complex.\nAbout open source being free of charge. That’s just wrong. Free software != free beer.\nThe fact that we charge is a huge advantage. If something breaks or needs fixing in a \u0026ldquo;free\u0026rdquo; product you are stuck. There is no one there. You can pay a consultant but that’s a coin toss. Here you have a guarantee by the authors of the product that we provide support. With Facebook even if you are a huge company you can’t buy that guarantee because react isn’t a product that makes money for Facebook.\nFurthermore, if you appreciate your craft you pay for good tools. There are 3 great Java IDE’s and the most popular among them isn’t completely free (IntelliJ). It’s still open source and it’s still a great IDE that is worth the money. We pay a large salary to our developers it makes sense to spend a little on their tools so they work more effectively.\nAbout expo it didn’t exist when I wrote the article. Regardless it’s nothing like Codename One which is a WORA solution something that React Native is not (based on Facebooks explicit definition). Build servers are possible with a WORA lightweight architecture but with a heavyweight architecture (one that relies on native peers for everything) this is problematic as you need a far larger set of testing devices to verify anything. Cloud build becomes a hindrance rather than an advantage in that case.\nNick — February 26, 2018 at 4:48 am (permalink) Nick says:\nA little late but I found it amusing you speak very highly of \u0026ldquo;separation of responsibilities\u0026rdquo; but you have view rendering logic coupled tightly with your data fetching logic, which a framework like React encourages to actually separate (don’t know about Codename one).\nShai Almog — March 3, 2018 at 12:12 pm (permalink) Shai Almog says:\nSure, it’s demo code so that’s how I treated this. I don’t think a framework should \u0026ldquo;force\u0026rdquo; separation.\nIt sounds good on paper but when you need to cross the separation bounds to do some back and forth logic things start getting \u0026ldquo;hazy\u0026rdquo; and you end up having a lot of clutter all over the place just to pass through that artificial bridge.\nReact native didn’t do that because it’s good engineering. That separation exists because the platform is in a different language and difference system. We let you access everything if you need to. Yes, power allows you to shoot yourself in the foot (i.e. threads) but it’s still more powerful to have the choice and languages that support encapsulation.\nFYI this article is really old and actually pulls a lot of punches from React Native. I should seriously revisit it since things are pretty different by now.\nJames Line — June 14, 2018 at 1:38 am (permalink) James Line says:\nTo be fair the Android emulator has gotten a fair bit faster since you wrote the article.\nIftee Khar Ul Islam — June 20, 2019 at 2:27 pm (permalink) Iftee Khar Ul Islam says:\nI like everything about CodenameOne, but I think there should be a comparison with Flutter, Google’s new framework cross-platform lover dudes may know it very well, I loved it but only thing that brought me here is that CodenameOne doesn’t increase App size as flutter, there’s other pros and cons but you should go with the one you like, I like both hence I will use both (there are migration tutorials for flutter, i.e. Flutter for Android devs, iOS devs, which enabled me to learn and use both)\nIftee Khar Ul Islam — June 20, 2019 at 2:31 pm (permalink) Iftee Khar Ul Islam says:\nA basic ‘Hello World’ app in flutter produces a 7.5mb file, where CodenameOne uses 1.7mb only, so for Small or relatively small apps using CodenameOne is a choice you won’t regret (Flutter may increase app size due to everything in Flutter is a Widget! and it also includes a C++ , Skia engine for performance which makes it’s size relatavely larger) …\nMichael — September 16, 2019 at 11:18 pm (permalink) Michael says:\nThere are an awful lot of comma splices in this article.\nMerkle Groot — February 7, 2020 at 11:51 pm (permalink) Merkle Groot says:\nReact Native lets me use one code base for Android, IoS, Web, UWP, and cross-platform Desktop.\nWHERE IS YOUR JAVA NOW?????\nShai Almog — February 8, 2020 at 4:43 am (permalink) Shai Almog says:\nAhem. Did you look at the website you’re in???\nWe target all these platforms and unlike react native we’re even more portable in terms of the code base, it’s truly one code.\nCrab Synth — May 22, 2020 at 1:56 am (permalink) Crab Synth says:\nFantastic Post… especially the comments… keep coming back to it, many times over the years… and i must commend you Shai… you had an appropriate answer for everything…. and even though conventions, preferrences and styles will continue to segragate users, causing them to pick a side… i believe by reading the comments and your replies i have a much better understanding of how to separate the hype from the features of React and how Java can achieve everything asked of it.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/java-is-superior-to-react-native-in-practically-every-way/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/java-is-superior-to-react-native-in-practically-every-way/react-demo.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI got into a discussion with a colleague on the Java vs. JavaScript subject, which is a problematic subject to\u003cbr\u003e\nbegin with. He then mentioned how great React Native is, I decided I have to look into it and maybe grab\u003cbr\u003e\nsome ideas for Codename One.\u003c/p\u003e\n\u003cp\u003eThere are some nice ideas there, but none of them is revolutionary or exceptional and most of them are pretty\u003cbr\u003e\nold news for Codename One developers running in Java 8.\u003c/p\u003e","title":"Java is Superior To React Native In Practically Every Way"},{"content":"Codename One 3.2 Release Notes Home 3.2 Release Notes Summary Version 3.2 sets the pace for many upcoming features \u0026amp; migration processes such as the new cloud infrastructure for push servers, modernized GUI builder etc.\nHighlights - Click For Details New GUI Builder (technology preview)\nThe new GUI builder is a big departure from our existing designer tool. This tool is now in \u0026ldquo;technology preview\u0026rdquo; status meaning that its not quite ready for prime time but we want feedback on its direction and issues.\nRead more about this work in this blog post.\nLocal Notifications on iOS and Android\nLocal notifications are similar to push notifications, except that they are initiated locally by the app, rather than remotely. They are useful for communicating information to the user while the app is running in the background, since they manifest themselves as pop-up notifications on supported devices.\nRead more about this work in this blog post.\nIntroduced New Push Server Architecture\nWe completely overhauled the way Codename One handles push services and added several long time RFE\u0026rsquo;s to the mix.\nRead more about this work in this blog post.\nAdded Ability for cn1libs To Include Build Hints\ncn1libs now include the ability to include build hints thus integrate more seamlessly without complex integration instructions.\nRead more about this work in this blog post.\nImproved iOS/Android Rendering Speed\nThanks to a community contribution we took a deep look at the rendering code and are using faster code for tiling/string rendering.\nRead more about this work in this github pull request.\nAdded A Permanent Side Menu Option\nThe Toolbar API has really picked up, in order to make it more useful for Tablets we added the ability to keep the SideMenuBar that\u0026rsquo;s builtin to it always on.\nRead more about this work in this blog post.\nGet All Styles - Simplified Handcoding Theme Elements\ngetAllStyles() allows writing code that is more concise to perform an operation on multiple style objects at once.\nRead more about this work in this blog post.\nAdded Support For Facebooks \u0026ldquo;Invite A Friend\u0026rdquo;\nNew integration for Facebooks \u0026ldquo;invite a friend\u0026rdquo; feature that simplifies viral marketing for your app.\nRead more about this work in this blog post.\nTerse Syntax For Building UI\u0026rsquo;s\nA shorter syntax for adding components and labels into the UI resulting in less code for the same functionality.\nRead more about this work in this blog post.\nJava 8 Language Features are now on by default\nWe fixed many things in this implementation over the past three months and feel confident enough to switch this into the default.\nRead more about this work in this blog post.\nDetails Added helper methods to RadioButton to create toggle buttons in a more concise way\nTuned SpanLabel to avoid unnecessary line breaks\nFixed an issue with URLImage \u0026amp; ImageViewer that caused the images not to download in some cases\nFixed BigDecimal and BigInteger to behave more like their java.lang counterparts\nFixed alpha handling in fillShape() on iOS as part of issue #1594\nImproved multiline support in ContainerList which seems to have regressed\nFixed stack overflow with SocketConnection on iOS issue #1581\nAdded ability to customize the completion list of the AutoCompleteTextField via code\nFixed language id\u0026rsquo;s for iOS 9 which started adding variants into language codes\nFixed race condition in the AppArg property on iOS\nFixed an issue with reloading a resource file using a different DPI\nAdded ability to customize the long press interval\nAdded ability to create a Container that encapsulates a component or group of components with one line of code\nAdded ability to specify a SimpleDateFormat for a picker to allow a more custom look\nEnhancements for issue #1572 that log dangling cursors in the SQL API into the console\nFixed issues with the TimerAPI on iOS\nFixed issue with SCALE_TO_FILL in URLImage, when rounding causes IllegalArgumentException\nAdded constructor to border layout for simpler/shorter code\nAdded validateToken to the Login framework\nFixed null pointer on String.valueOf(Object) in the iOS VM\nAdded helper methods to UIManager to reduce the boilerplate when initializing projects\nFixed vertical position in toolbar apps with morph transition\nNew utility methods to simplify sleep/wait calls\nAdded ability to mask images fetched thru URL image.\nAdded many new shortcut methods such as add methods to containers and text field getter for integer, new constructors for text fields.\nFixed upload to provide progress indication on iOS\nAdded ability for dialogs to dynamically adapt their size\nAdded command support to SpanButton\n","permalink":"https://www.codenameone.com/codename-one-3-2-release-notes/","summary":"\u003ch1 id=\"codename-one-32-release-notes\"\u003eCodename One 3.2 Release Notes\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e3.2 Release Notes\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"summary\"\u003eSummary\u003c/h3\u003e\n\u003cp\u003eVersion 3.2 sets the pace for many upcoming features \u0026amp; migration processes such as the new cloud infrastructure for push servers, modernized GUI builder etc.\u003c/p\u003e\n\u003ch3 id=\"highlights---click-for-details\"\u003eHighlights - Click For Details\u003c/h3\u003e\n\u003cp\u003eNew GUI Builder (technology preview)\u003c/p\u003e\n\u003cp\u003eThe new GUI builder is a big departure from our existing designer tool. This tool is now in \u0026ldquo;technology preview\u0026rdquo; status meaning that its not quite ready for prime time but we want feedback on its direction and issues.\u003cbr\u003e\nRead more about this work in \u003ca href=\"/blog/new-gui-builder.html\"\u003ethis blog post\u003c/a\u003e.\u003c/p\u003e","title":"Codename One 3.2 Release Notes"},{"content":"\nWe are thrilled to announce the immediate availability of Codename One 3.2!\nVersion 3.2 sets the pace for many upcoming features \u0026amp; migration processes such as the\nnew cloud infrastructure for push servers, modernized GUI builder etc.\nCodename One 3.3 is currently scheduled for January 27th 2016 and should continue the trend of iterative changes\nthat form a larger platform evolution arch.\nHighlights Of The Release – Click For Details ____New GUI Builder (technology preview)\nThe new GUI builder is a big departure from our existing\ndesigner tool. This tool is now in \u0026ldquo;technology preview\u0026rdquo; status meaning that its not quite ready for\nprime time but we want feedback on its direction and issues.\nRead more about this work in this blog post.\n____Local Notifications on iOS and Android\nLocal notifications are similar to push notifications, except that they are initiated locally by the app,\nrather than remotely. They are useful for communicating information to the user while the app is running in the background, since they\nmanifest themselves as pop-up notifications on supported devices.\nRead more about this work in this blog post.\n____Introduced New Push Server Architecture\nWe completely overhauled the way Codename One handles push services\nand added several long time RFE’s to the mix.\nRead more about this work in this blog post.\n____Added Ability for cn1libs To Include Build Hints\ncn1libs now include the ability to include build hints thus\nintegrate more seamlessly without complex integration instructions.\nRead more about this work in this blog post.\n____Improved iOS/Android Rendering Speed\nThanks to a community contribution we took a deep look at the rendering\ncode and are using faster code for tiling/string rendering.\nRead more about this work in this github pull request.\n____Added A Permanent Side Menu Option\nThe Toolbar API has really picked up, in order to make it more useful for Tablets\nwe added the ability to keep the SideMenuBar that’s builtin to it always on.\nRead more about this work in this blog post.\n____Get All Styles – Simplified Handcoding Theme Elements\ngetAllStyles() allows writing code that is more concise to perform an operation on multiple\nstyle objects at once.\nRead more about this work in this blog post.\n____Added Support For Facebooks \u0026ldquo;Invite A Friend\u0026rdquo;\nNew integration for Facebooks \u0026ldquo;invite a friend\u0026rdquo; feature that simplifies\nviral marketing for your app.\nRead more about this work in this blog post.\n____Terse Syntax For Building UI’s\nA shorter syntax for adding components and labels into the UI resulting in less code for the same functionality.\nRead more about this work in this blog post.\n____Java 8 Language Features are now on by default\nWe fixed many things in this implementation over the past\nthree months and feel confident enough to switch this into the default.\nRead more about this work in this blog post.\nYou can also read the far more detailed list of release notes here. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDiamond — October 27, 2015 at 11:52 am (permalink) Diamond says:\nThank you guys for the hardwork,\nMy build always fail whenever I send a build using 1.8, I got a message that codenameone supports up to 1.7 java version… Does the build server support 1.8 now?\nAnd may I ask if \u0026ldquo;background process while app is not running\u0026rdquo; would be implemented anytime soon?\nShai Almog — October 28, 2015 at 3:35 am (permalink) Shai Almog says:\nYou need to explicitly use the Java 8 support either by migrating your project to a Java 8 project type or creating a new project. Our server code converts Java 8 bytecode down to Java 5 making this seamless to our servers.\nBackground processes is something we slated and discussed for 3.2 and worked on a lot. The end result was just background notifications which IMO is the least important of the bunch. Hopefully this will land sooner rather than later.\nDiamond — October 28, 2015 at 4:17 am (permalink) Diamond says:\nHi,\nHow do I add MultiImages or create UIIDs in the new GUI Builder.\nCan we have a double click function on components to open their properties please.\nDragging components crashes the Gui Builder sometimes.\nWhen I delete component, it doesn’t disappear from the tree and if I try to delete it again, the Gui Builder crashes.\nWhen I select a Container that has one component inside, I got properties of the component and not the container itself.\nMost of this stuff happens randomly.\nShai Almog — October 28, 2015 at 9:47 am (permalink) Shai Almog says:\nHi,\nare you sure you are building with the right account? It should be logged to the console.\nGerben — October 28, 2015 at 9:49 am (permalink) Gerben says:\nTurned out we had paypal issues and our account was terminated or something like that at the exact moment I installed 3.2. But is was unrelated.\nShai Almog — October 28, 2015 at 9:55 am (permalink) Shai Almog says:\nHi,\nadding multi-images is part of the theme which is a separate feature altogether. You need to still do that with the old designer and it will be accessible then. The same is true for creating/manipulating UIID’s. We’ll replace the theme generating functionality in the old designer using a different tool, it was a mistake mixing everything into a single tool.\nSingle clicking a component in the UI opens its properties on the left side. If you pick it from the tree then it will be selected as you change the tabs. Notice that properties are now split into \u0026ldquo;Basic\u0026rdquo;, \u0026ldquo;Advanced\u0026rdquo; \u0026amp; \u0026ldquo;Events\u0026rdquo; (at the bottom of the tab). There is also a separate tab to control layout.\nIf you get crashes or errors a log would be nice, we will add some better crash logging for the next update and hopefully start fixing these bugs quickly.\nTom Arn — October 30, 2015 at 10:03 am (permalink) Tom Arn says:\nIs the source code of the new gui builder already available for download?\nBest regards\nTom\nahmed — October 31, 2015 at 3:52 am (permalink) ahmed says:\nThe latest version i get in intellij is 3.1\nShai Almog — October 31, 2015 at 4:16 am (permalink) Shai Almog says:\nOur plugins aren’t open source and we are looking at the new GUI builder as a part of the plugin so at this time we don’t plan to open source it.\nShai Almog — October 31, 2015 at 4:17 am (permalink) Shai Almog says:\nWe are working on a partial rewrite of the IntelliJ plugin, this is taking some time.\nMost features of 3.2 are available on IntelliJ via a library update.\nYaakov Gesher — November 10, 2015 at 10:07 pm (permalink) Yaakov Gesher says:\nAfter upgrading to 3.2, using the old GUI Builder, every time I make a change in a form I get a little popup saying \u0026ldquo;GUI Builder error – undoing\u0026rdquo;, but it doesn’t actually undo the changes made.\nShai Almog — November 11, 2015 at 4:53 am (permalink) Shai Almog says:\nCan you run the GUI builder from command line and get the logged output when you get that error?\nYaakov Gesher — November 11, 2015 at 7:51 pm (permalink) Yaakov Gesher says:\nWhat’s the command I use for that?\nShai Almog — November 12, 2015 at 3:09 am (permalink) Shai Almog says:\njava -jar ~/.codenameone/designer_1.jar\n~ is the home directory if you are doing this in Windows and you would naturally need to reverse the slashes.\nYaakov Gesher — November 14, 2015 at 9:16 pm (permalink) Yaakov Gesher says:\nI’ll email you the stack trace.\nShai Almog — November 15, 2015 at 4:08 am (permalink) Shai Almog says:\nI see the issue but I don’t think its a regression since this is pretty old code. Did you change something with the TableLayout in that hierarchy?\nCan you change the column count to be larger or is this inaccessible in the GUI?\nYaakov Gesher — November 21, 2015 at 8:48 pm (permalink) Yaakov Gesher says:\nYeah, I realized later that I was adding components beyond the TableLayout’s defined row count. But shouldn’t there be a more user-friendly error message?\nShai Almog — November 22, 2015 at 4:37 am (permalink) Shai Almog says:\nIt auto increments the row. This is a bug that we fixed.\nThat’s just a workaround until we provide a new version of the designer.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-3-2-now-live/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-3-2-now-live/CodenameOne-Horizontal.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are thrilled to announce the immediate availability of Codename One 3.2!\u003cbr\u003e\nVersion 3.2 sets the pace for many upcoming features \u0026amp; migration processes such as the\u003cbr\u003e\nnew cloud infrastructure for push servers, modernized GUI builder etc.\u003cbr\u003e\nCodename One 3.3 is currently scheduled for January 27th 2016 and should continue the trend of iterative changes\u003cbr\u003e\nthat form a larger platform evolution arch.\u003c/p\u003e\n\u003ch3 id=\"highlights-of-the-release--click-for-details\"\u003eHighlights Of The Release – Click For Details\u003c/h3\u003e\n\u003cp\u003e____New GUI Builder (technology preview)\u003c/p\u003e","title":"Codename One 3.2 Now Live"},{"content":"\nIn this last minute before 3.2 finally comes out we have a batch of new features \u0026amp; updates. Some of\nthe last minute features that went into Codename One include: shorter more terse syntax for creating forms,\nmigration wizard for the new GUI builder \u0026amp; dialog adaptive sizing.\nBetter Syntax For Populating Containers and Toogle Buttons Codename One is slightly verbose. In part its due to Java’s tradition of verbosity but some of that comes from\nthe fact that we never considered terse to be a virtue. Obviously a lot of developers disagree with that notion\nand would like shorter syntax, which does have a point…\nOne such small modification of the \u0026ldquo;why didn’t we do this sooner\u0026rdquo; variety is new methods we added to container\nthat are shorter (add instead of addComponent) but also return the Container\ninstance thus allowing chaining. E.g. this is taken directly from the KitchenSink’s input demo:\nContainer input = new Container(new BoxLayout(BoxLayout.Y_AXIS)); input.addComponent(new Label(\u0026quot;Text Field\u0026quot;)); input.addComponent(new TextField(\u0026quot;Hi World\u0026quot;)); input.addComponent(new Label(\u0026quot;Text Field With Hint\u0026quot;)); TextField hint = new TextField(); hint.setHint(\u0026quot;Hint\u0026quot;); input.addComponent(hint); With the newer syntax we can cut down the verbosity significantly. Notice we can just add(\u0026quot;String\u0026quot;)\nwhich is equivalent to addComponent(new Label(\u0026quot;String\u0026quot;)):\nTextField hint = new TextField(); hint.setHint(\u0026quot;Hint\u0026quot;); Container input = new Container(new BoxLayout(BoxLayout.Y_AXIS)). add(\u0026quot;Text Field\u0026quot;).add(new TextField(\u0026quot;Hi World\u0026quot;)). add(\u0026quot;Text Field With Hint\u0026quot;).add(hint); The thing I really like about the code above is that its short enough to place the label and component side\nby side to each other without side scrolling in the IDE window.\nAnother feature we added in the same vain is a simple factory method for RadioButton/\nToggleButton creation. Up until now if we wanted to create a toggle button we would do something like:\nContainer toggles = new Container(new BoxLayout(BoxLayout.Y_AXIS)); ButtonGroup bg = new ButtonGroup(); RadioButton a = new RadioButton(\u0026quot;a\u0026quot;); a.setToggleButton(true); bg.add(a); toggles.addComponent(a); RadioButton b = new RadioButton(\u0026quot;b\u0026quot;); b.setToggleButton(true); bg.add(b); toggles.addComponent(b); That’s pretty verbose and ridden with boilerplate code. So we shortened this slightly using the\ncreateToggle factory method that combines 3 lines above into one e.g:\nContainer toggles = new Container(new BoxLayout(BoxLayout.Y_AXIS)); ButtonGroup bg = new ButtonGroup(); RadioButton a = RadioButton.createToggle(\u0026quot;a\u0026quot;, null, bg); RadioButton b = RadioButton.createToggle(\u0026quot;b\u0026quot;, null, bg);; toggles.add(a).add(b); Dialog Adaptive Sizing Dialogs in Codename One are forms that show the previous form as a background. This causes some confusion\nsince developers often think of them as standard OS \u0026ldquo;windows\u0026rdquo; which isn’t the case at all…\nWe position the dialog by padding the dialog body from the sides to move it into the right place and for most\nstandard dialogs we \u0026ldquo;auto calculate\u0026rdquo; this margin based on the preferred size of the dialogs content. This is\nall great until we want to change something with the content of the dialog….\nWe normally try to discourage people from building complex UI’s into a dialogs body but sometimes this is\nnecessitated by the UI/UX and can’t be avoided. Up until now our workaround to grow the dialog was to dispose\nthe current dialog and show a new dialog (without the transitions). However, with the new update we now have\na new method: growOrShrink() which will implicitly resize a dialog to its new preferred size.\nGUI Builder Updates The new GUI builder and its integration with Codename One has been going on very well, we were even able\nto add a preliminary migration wizard for existing resource files just before the 3.2 release. This wizard and\nthe rest of the GUI builder are HIGHLY experimental so caution is advised, copy your project to the side and\nexperiment on that!\nThe migration wizard will appear for GUI builder projects and effectively should convert them to manual projects\nwith the new GUI builder in place. It will replace the StateMachineBase class with a hardcoded\nclass that does a lot of the work for partial compatibility. Its quite possible your code will work after the migration\nas is (although we would assume some work would be required).\nThe following things might have an issue with the new GUI builder and the migration wizard, please use the comments\nsection below with other things you notice and file issues in the\ngithub issue tracker:\nRenderers – at this time renderers aren’t supported in the new GUI builder. State machine navigation is MUCH simpler and keeps an instance of the previous form so before/exit behaviors\nmight vary a lot. The new GUI builder always uses the Toolbar class, code that relies on different command\nsemantics might not work properly Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChibuike Mba — January 29, 2016 at 10:32 pm (permalink) Chibuike Mba says:\nHi Shai,\nthe conversion tool while converting ui List Instantiates:\nprivate com.codename1.ui.list.List gui_listContact = new com.codename1.ui.list.List();\ninstead of:\nprivate com.codename1.ui.List gui_listContact = new com.codename1.ui.List();\nAm using CodenameOne 3.3\nShai Almog — January 30, 2016 at 5:35 am (permalink) Shai Almog says:\nDamn. Fixing it now.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/terse-syntax-migration-wizard-more/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/terse-syntax-migration-wizard-more/gui-builder-migration-wizard.png\"\u003e\u003c/p\u003e\n\u003cp\u003eIn this last minute before 3.2 finally comes out we have a batch of new features \u0026amp; updates. Some of\u003cbr\u003e\nthe last minute features that went into Codename One include: shorter more terse syntax for creating forms,\u003cbr\u003e\nmigration wizard for the new GUI builder \u0026amp; dialog adaptive sizing.\u003c/p\u003e\n\u003ch4 id=\"better-syntax-for-populating-containers-and-toogle-buttons\"\u003eBetter Syntax For Populating Containers and Toogle Buttons\u003c/h4\u003e\n\u003cp\u003eCodename One is slightly verbose. In part its due to Java’s tradition of verbosity but some of that comes from\u003cbr\u003e\nthe fact that we never considered terse to be a virtue. Obviously a lot of developers disagree with that notion\u003cbr\u003e\nand would like shorter syntax, which does have a point…\u003cbr\u003e\nOne such small modification of the \u0026ldquo;why didn’t we do this sooner\u0026rdquo; variety is new methods we added to container\u003cbr\u003e\nthat are shorter (\u003ccode\u003eadd\u003c/code\u003e instead of \u003ccode\u003eaddComponent\u003c/code\u003e) but also return the \u003ccode\u003eContainer\u003c/code\u003e\u003cbr\u003e\ninstance thus allowing chaining. E.g. this is taken directly from the KitchenSink’s input demo:\u003c/p\u003e","title":"Terse Syntax, Migration Wizard \u0026 more"},{"content":"\nThis morning I was awoken by myself – or rather the 1985 version of myself. He (I’ll refer to the 1985 version of myself in the 3rd person here forward) was in a panic and was yammering about something to do with changing history. He asked why my pants were inside out, and I wondered why he was wearing a life preserver. According to him, he had driven a time machine from 1985 to this day (October 21, 2015) in the future to stop me from making a terrible mistake. I asked him: \u0026ldquo;What mistake?\u0026rdquo;, to which he produced a 3.5 inch floppy disk.\n\u0026ldquo;On this disk, you’ll find a scan of a single page from a Grays Sports Almanac, that displays the score to the 2015 world series\u0026rdquo;. He implored me to look at the image and use it to change the team that I had planned to bet on. No sooner did I take the disk from him, than he made like a tree and got out of there.\nThe first hurdle to viewing this image was in loading it off of that floppy disk in this post floppy disk world. I wasn’t going to let that stop me, though. If you put your mind to it, you can accomplish anything.\nAfter some struggles, I managed to copy the image from the floppy disk onto my cell phone so I could view it. Unfortunately, the image was too small to make anything out. The image itself, he had said was 1 inch by 1 inch. But on my phone, it only rendered at a measly 8th of an inch. It basically looked like a speck on my screen.\nWhat the??! He said it was 1 inch squared. How will I ever see what is on this image? I soon realized that the problem was that I wasn’t thinking 4th dimensionally: the fourth dimension being density. My 1985 self was using a Macintosh of the time that had a pixel density of approximately 57 pixels per inch. My cell phone, on the other hand was a new iPhone 6+, with a pixel density of about 480 pixels per inch. So his 57×57 pixel image looked fine on his old screen, but was only an eighth of an inch on mine. Heavy! Device displays in the future are too dense to display this image at a reasonable size.\nWhat I needed to do was convert this image to a multi-image so that it would display at the proper size on my device, and all devices. So I imported the image into my Codename One resource file, specifying a source density of \u0026ldquo;Very Low\u0026rdquo;. Then created a simple app using the Codename One GUI builder, that displays a single label. The source to display the multi-image roughly as follows (Please excuse the crudity of this model. I didn’t have time to build it to scale or paint it):\nSystem.out.println(\u0026quot;I'm your density: \u0026quot;+ Display.getInstance().getDeviceDensity()); Label image = new Label(theme.getImage(\u0026quot;AlmanacClipping.png\u0026quot;)); theForm.addComponent(image); Since the image is a multi-image, the app should display it at the correct \u0026ldquo;real\u0026rdquo; size of 1 inch by 1 inch.\nAfter loading the app onto my phone, I can finally see the message: \u0026ldquo;Chicago Cubs win the World Series!\u0026rdquo;.\nHmm. Good thing I didn’t bet on the Blue Jays, as I had planned to do. On the bright side, my app works. It displays the image in the correct size on all devices. I finally invent something that works! Perhaps I should submit this to the iTunes store and Google Play.\nBut what if I send in the app in and they don’t like it? What if they say I’m no good? What if they say, \u0026ldquo;Get out of here kid. You’ve got no future\u0026rdquo;? I mean, I just don’t think I can take that kind of rejection.\nBehind the Scenes: The Making of this Post The iPhone 3gs has a 3.5″ display with a resolution of 320×480, which works out to approximately 163 pixels per inch across both the horizontal and vertical axes.\nThe iPhone 4 also has a 3.5″ display, but the resolution is double: 640×960, which works out to approximately 326 pixels per inch across the horizontal and vertical axes.\nTherefore, if you render a 163×163 pixel image on an iPhone 3Gs the result will be approximately 1 inch squared in the real world. The same image rendered on an iPhone 4 would be approximately 0.5 inches squared – or half the size. Similarly font sizes, border thickness, padding, margins, and positions specified in pixels will produce different results on an iPhone 3Gs than on an iPhone 4.\nThis is just a small sample from a vast sea of different device densities that are available on the market. I use this example to demonstrate one of the inherent challenges in writing cross-platform user interfaces. Luckily, Codename One provides you with the tools you need to work in a multi-device world.\nDevice Densities At runtime, you can always find the host device’s approximate pixel density using the Display.getDeviceDensity() method. This will return one of:\nConstant Density Example Device Display.DENSITY_VERY_LOW ~ 88 ppi Display.DENSITY_LOW ~ 120 ppi Android ldpi devices Display.DENSITY_MEDIUM ~ 160 ppi iPhone 3GS, iPad, Android mdpi devices Display.DENSITY_HIGH ~ 240 ppi Android hdpi devices Display.DENSITY_VERY_HIGH ~ 320 ppi iPhone 4, iPad Air 2, Android xhdpi devices Display.DENSITY_HD ~ 540 ppi iPhone 6+, Android xxhdpi devices Display.DENSITY_560 ~ 750 ppi Android xxxhdpi devices Density.DENSITY_2HD ~ 1000 ppi Density.DENSITY_4K ~ 1250ppi Multi-Images In 99% of cases, you’ll want images to render at the same \u0026ldquo;real\u0026rdquo; size on all devices, rather than their pixel size. Codename One has you covered here with its multi-image support. You can import an image into the resource file, specifying its source density, and it will be embedded at all of the densities that you specify. Then you can obtain a reference to the image using the Resources.getImage() method at runtime, it will give the correct version of the image for the device’s density so that the \u0026ldquo;real\u0026rdquo; size of the image will be preserved across all devices.\nUse Millimetres, Not Pixels for Dimensions When configuring your styles, you should almost never use \u0026ldquo;Pixels\u0026rdquo; as the unit for padding, margins, font size, and border thickness because the results will be inconsistent on different densities. Instead, you should use millimetres for all non-zero units of measurements.\nFractions of Millimetres Sometimes millimetres don’t give you enough precision for what you want to do. Currently the resource editor only allows you to specify integer values for most units. However, you can achieve more precise results when working directly in Java. The Display.convertToPixels() method will allow you to convert millimetres (or dips) to pixels. It also only takes an integer input, but you can use it to obtain a multiplier that you can then use to convert any millimeter value you want into pixels.\nE.g.\ndouble pixelsPerMM = ((double)Display.getInstance().convertToPixels(10, true)) / 10.0; And now you can set the padding on an element to 1.5mm. E.g.\nmyButton.getAllStyles().setPaddingUnit(Style.UNIT_TYPE_PIXELS); int pixels = (int)(1.5 * pixelsPerMM); myButton.getAllStyles().setPadding(pixels, pixels, pixels, pixels); Font Sizes If you’re using system fonts (the default), then you’re limited to only three font sizes: Small, Medium, and Large. These will be converted to an appropriate \u0026ldquo;real\u0026rdquo; size on the device. If you need more precision, you can embed a TTF font with your app, then you can specify font size in millimetres (or DIPS). And if you require more precision on the font size than millimetres, you can use the same trick above to obtain a fractional millimetres to pixels conversion, and use the Font.deriveFont() method to generate a font in the exact \u0026ldquo;real\u0026rdquo; size that you desire.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/i-am-your-density/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/i-am-your-density/density-heading.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis morning I was awoken by myself – or rather the 1985 version of myself. He (I’ll refer to the 1985 version of myself in the 3rd person here forward) was in a panic and was yammering about something to do with changing history. He asked why my pants were inside out, and I wondered why he was wearing a life preserver. According to him, he had driven a time machine from 1985 to this day (October 21, 2015) in the future to stop me from making a terrible mistake. I asked him: \u0026ldquo;What mistake?\u0026rdquo;, to which he produced a 3.5 inch floppy disk.\u003c/p\u003e","title":"I Am Your Density"},{"content":"\nCodename One provides you with the tools to craft a visually stunning and unique user interface via its pluggable look and feel. For simple use cases, you can define styles entirely by setting style properties either in code or the resource editor. However, to achieve best results (for anything more complicated than a solid background color with a rectangular border), you will often want to use image borders and backgrounds. The usual process for styling elements in Codename One is:\nFind or create an image that encapsulates the background and border of the element.\nImport the image into your theme as a multi-image.\nSlice the image into a 9-piece border if you want the element to be able to adapt to different sizes.\nThis process is described in great detail in this blog post.\nThis process is extremely flexible, since you can use it to convert pretty much any design into an app. However, for many common use cases such as rounded borders, I would prefer to be able to automatically generate these image borders and backgrounds without having to create an image, import it, and slice it.\nThe new Codename One CSS library allows you to do just that. The library enables you to create entire themes using only CSS, but in this post, I’m going to focus on its ability to automatically generate image backgrounds and borders for your apps.\nRounded Corners The following a CSS definition for a minimal rounded button.\nRound1 { width: 40pt; height: 40pt; border-radius: 20pt; border: 1pt solid black; text-align: center; } The result will be a button that looks like this:\nHow it works:\nAt compile-time, the CSS library compiles the CSS file into a codename one resource file. Each element selector (in the example above this is \u0026ldquo;Round1\u0026rdquo;) is converted into a UIID/Style that can be referenced from your codename one application. If the CSS styles specified can be expressed completely by Codename One style properties (e.g. padding, margin, font, simple borders, etc…​), then the resulting UIID will be more or less a direct conversion of the CSS properties. If, however, the CSS styles mandate a background or border that Codename One cannot express using its regular styles (e.g. rounded corners, shadows, gradients), then an appropriate image border or background will be generated and saved in the resource file as a multi-image.\nIn the above example, we specify that the \u0026ldquo;Round1\u0026rdquo; UIID should include rounded corners with a radius of 20pt. Since Codename One doesn’t support rounded corners natively, the CSS module will (at compile time) generate a an image with the appropriate rounded border and use this in an image border for the \u0026ldquo;Round1\u0026rdquo; UIID.\nInner Shadows Let’s spice up our button a bit more by adding shadows into the mix. Add this CSS snippet:\nRound1InnerShadow { cn1-derive: Round1; box-shadow: inset 0px 0px 21pt 10pt rgba(61,59,61,0.48); border: 1pt solid transparent; } This defines a new UIID named \u0026ldquo;Round1InnerShadow\u0026rdquo; that derives from the \u0026ldquo;Round1\u0026rdquo; UIID (i.e. inherits all of its properties), but changes to a transparent border, and adds an inner shadow.\nAnd the result is\nOuter Shadows Let’s shift gears a bit and make a button that is a little less round, but has a subtle drop-shadow.\nRound1OuterShadow { cn1-derive: Round1; box-shadow: 5pt 5pt 10pt 0px rgba(61,59,61,0.48); border-radius: 5pt; border: 1pt solid #ccc; padding-bottom: 2mm; padding-top: 1mm; } In this case we reduce the border radius to 5 dips, and we have removed the inset marker from the box-shadow property so that the shadow will be outside the button. After some experimentation I also found that a little bit of padding helps for the look of the button in this case.\nThe result:\nGradients I could go on and on with different cool CSS effects that you can generate, but I’ll stop at this one last one: Gradients.\nCodename One has been capable of generating gradient backgrounds at runtime for quite some time, but we are told not to use them because they are \u0026ldquo;slow\u0026rdquo;. Instead we are instructed to create an image with the gradient that we want, and then use it as a background image.\nUsing CSS and the linear-gradient or radial-gradient property, you can have your cake and eat it too since it will generate the gradients as images at compile-time, then use them as image backgrounds (or image borders) in your theme.\nRound1Gradient { cn1-derive: Round1OuterShadow; background: linear-gradient(to bottom, rgba(242,246,248,1) 0%, rgba(216,225,231,1) 50%, rgba(181,198,208,1) 51%, rgba(224,239,249,1) 100% ); } The result:\nGenerating the CSS For those of you who don’t speak CSS fluently yet, you will be happy to learn that the ‘net is filled with online tools for generating CSS borders, shadows, and gradients for you. One such tool is this CSSMatic tool. You just enter the values that you want for color, border-radius, etc.., and it spits out some shiny CSS for you to just paste into your stylesheet.\nHowever You will probably want to modify the CSS that it generates just a little bit:\nChange all px units to pt. This will cause the coordinate to be scaled appropriate for the device density.\nOnly include the standard CSS properties, not the browser-specific ones. Browser specific property names will be prefixed by one of -moz-, -webkit, or some other prefix beginning with \u0026ldquo;-\u0026rdquo;. E.g. The tool output the following CSS for a rounded border:\nborder-radius: 10px 10px 10px 10px; -moz-border-radius: 10px 10px 10px 10px; -webkit-border-radius: 10px 10px 10px 10px; border: 0px solid #000000; We would change this to\nborder-radius: 10pt 10pt 10pt 10pt; border: 0px solid #000000; Where Do I Put My CSS File? \u0026ldquo;This CSS looks really nice, but where to I put it, and how to I set up the CSS module?\u0026rdquo;, you say. I’m glad you asked. The CSS compiler will look for .css files inside your project’s \u0026ldquo;css\u0026rdquo; directory (which you’ll need to create). It will compiles these CSS files into corresponding .res files which will be placed into your project’s src directory. You can then load this theme in your app just as you would load any other theme file.\nE.g.\nSuppose you add a CSS file into your project css/theme.css. When you compile your project, it will generate the file src/theme.css.res. Then you can load this file in your app as follows:\nResources css = Resources.openLayered(\u0026quot;/theme.css\u0026quot;); UIManager.getInstance().addThemeProps(css.getTheme(css.getThemeResourceNames()[0])); You can download the Codename One CSS library and read the installation instructions in the CN1-CSS Repository on GitHub. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — October 19, 2015 at 3:54 pm (permalink) Looks like really cool stuff; hope to try this out some time. Thanks!!!\nFranck Marchand — February 13, 2016 at 10:51 pm (permalink) Hi, is it possible to do a cercle ? I try with border-radius:50% but I have a border around image, not a circle.\nShai Almog — February 14, 2016 at 3:36 am (permalink) Hi,\nthat won’t work. You round is inherently a special case since it can’t grow very well.\nThe closest you can get is use something a MultiImage of a circle as a background image and marking it as SCALE_TO_FIT.\nFranck Marchand — February 14, 2016 at 10:21 am (permalink) Have you an example ?\nThe closest I do is not really fun :).\nFranck Marchand — February 14, 2016 at 7:41 pm (permalink) Ok, I find: http://www.javacodegeeks.co…\nAnd I am inspired me :\nEncodedImage img = EncodedImage.createFromImage(_parent.getTheme().getImage(\u0026ldquo;teams_female.png\u0026rdquo;), false);\nImage mask = _parent.getTheme().getImage(\u0026ldquo;teams_rounded-mask.png\u0026rdquo;);\nEncodedImage roundPlaceholder = EncodedImage.createFromImage(img.scaled(mask.getWidth(), mask.getHeight()).applyMask(mask.createMask()), false);\nLabel photo = new Label(roundPlaceholder);\nphoto.setUIID(\u0026ldquo;UserImage\u0026rdquo;);\nRegards\nShai Almog — February 15, 2016 at 3:28 am (permalink) Shai Almog says:\nI was thinking more about this: https://www.codenameone.com…\nNotice that the article you linked appeared here first: http://www.codenameone.com/…\nMo — June 2, 2016 at 4:09 pm (permalink) Mo says:\nHi Steve, love the CSS lib, thank you, so far so good, just ran into a few issues when it comes to controlling the position and styling for the Container (Center) when setting direction ( RTL/LTR) with SpanLabel and SpanButton components(Label and Text), which do not inherits the UIID in addition to the Round1OuterShadow above, where I failed to Center, keeping inmind that, my user can switch from Arabic(RTL) to English, do I have to maintain to 2 CSS files??, any thought to the above would be much appreciated.\nShai Almog — June 3, 2016 at 4:05 am (permalink) Shai Almog says:\nCSS isn’t really related to LTR. Things will flip automatically when you turn on RTL\nAkinniranye James — September 9, 2016 at 8:55 pm (permalink) Akinniranye James says:\nCss to res ,along with the the New GUI Builder (i could substitute this https://github.com/shannah/…), gave me the superpower to create my best looking cross mobile app with codenameone.\nHristo Vrigazov — September 11, 2016 at 11:32 am (permalink) Hristo Vrigazov says:\nThere are instructions for Netbeans and Eclipse. Is IntelliJ supported? I tried the steps for Netbeans but it did not work\nEDIT: It actually works in InteliJ following Netbeans instructions. But I think that we should load the theme by:\nUIManager.getInstance().addThemeProps(css.getTheme(css.getThemeResourceNames()[0]));\ninstead of:\nUIManager.getInstance().addThemeProps(css.getThemeResourceNames()[0]);\nshannah78 — September 12, 2016 at 3:34 pm (permalink) shannah78 says:\nThanks. I’ve fixed the post… it will be updated on site shortly.\nHristo Vrigazov — October 23, 2016 at 6:25 pm (permalink) Hristo Vrigazov says:\nI notice that sometimes, in very rare cases, the rounded UIID appears broken in a dialog, it is like the part above it appears under it. I cannot a find a case that does this reliably, but it is somewhat annoying. Any idea what could have caused the problem?\nShai Almog — October 24, 2016 at 2:17 am (permalink) Shai Almog says:\nIs this specific to CSS?\nWhat’s the generated style you have in the resource file?\nCan you provide screenshots?\nHristo Vrigazov — October 27, 2016 at 1:22 pm (permalink) Hristo Vrigazov says:\nI finally managed to get it on\nhttps://uploads.disquscdn.c… the simulator.\nI have seen this only on CSS and not always.\nShai Almog — October 28, 2016 at 3:44 am (permalink) Shai Almog says:\nThat looks like a problematic cut of a 9-piece border\nHristo Vrigazov — November 2, 2016 at 10:15 pm (permalink) Hristo Vrigazov says:\nThanks for the guide! Is there a way to avoid this only using css, without modifiying the resulting theme.css.res file?\nshannah78 — November 3, 2016 at 12:31 am (permalink) shannah78 says:\nCan you share the CSS that you used to create this border?\nHristo Vrigazov — November 3, 2016 at 5:31 am (permalink) Hristo Vrigazov says:\nRound1 {\nwidth: 40pt;\nheight: 40pt;\nborder-radius: 20pt;\nborder: 1pt solid black;\ntext-align: center;\nbackground-color: white;\n}\nRound1InnerShadow {\ncn1-derive: Round1;\nbox-shadow: inset 0px 0px 21pt 10pt rgba(61,59,61,0.48);\nborder: 1pt solid transparent;\nbackground-color: white;\n}\nThe UIID is Round1InnerShadow\nshannah78 — November 3, 2016 at 5:41 pm (permalink) shannah78 says:\nHmm.. That looks fine. Do you get the same behaviour with the Round1 UIID?\nHristo Vrigazov — November 3, 2016 at 7:49 pm (permalink) Hristo Vrigazov says:\nYes, for example see this: https://uploads.disquscdn.c….\nI managed to pinpoint exact scenario that breaks it everytime like this. It is when I have a bigger and after it I show smaller. Not sure if this helps.\nshannah78 — November 4, 2016 at 6:48 pm (permalink) shannah78 says:\nCan you file an issue in the cn1-css issue tracker, and include a minimal test case (both the java and css)? I can’t seem to reproduce this problem using your CSS and a test case that I put together.\nHristo Vrigazov — November 9, 2016 at 5:30 pm (permalink) Hristo Vrigazov says:\nSorry, I can only reproduce it in my app for now, I can’t find a simple example that creates it. I will try to find one later\nArtur Hefczyc — May 4, 2020 at 6:50 pm (permalink) Artur Hefczyc says:\nHi,\nI tried linear-gradient examples but they seem to be not working. They give css compiler errors:\nbackground: linear-gradient(to bottom, rgba(242,246,248,1) 0%, rgba(216,225,231,1) 50%, rgba(181,198,208,1) 51%, rgba(224,239,249,1) 100% ); This results in the following CSS error:\nCSS\u0026gt; Expecting color for param 3 of linear-gradient CSS\u0026gt; Gradient not valid: null Then I simplify it to (removed the stop parameter):\nbackground: linear-gradient(to bottom, rgba(242,246,248,0.5), rgba(216,225,231,0.7), rgba(181,198,208,0.9), rgba(224,239,249,1) ); And I get another error:\nCSS\u0026gt; Gradient not valid: alphas of start and end colors don’t match So it looks like the linear-gradient does not support ‘stop’ parameter and it does not support custom alpha for each color. This is a shame as creating a linear gradient for a single color with different alpha for each stop gives really nice effects.\nOr maybe I am doing something wrong?\nShai Almog — May 5, 2020 at 5:34 am (permalink) Shai Almog says:\nAt this time we don’t support alphas on the gradient. It’s something we might be able to improve but it’s a bit rough to optimize since we sometimes generate image textures and customizing the alpha there is slightly harder.\nIf it’s important to you then this is something we can improve potentially.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/rounded-corners-shadows-and-gradients-with-css/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/rounded-corners-shadows-and-gradients-with-css/css-header.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One provides you with the tools to craft a visually stunning and unique user interface via its pluggable look and feel. For simple use cases, you can define styles entirely by setting style properties either in code or the resource editor. However, to achieve best results (for anything more complicated than a solid background color with a rectangular border), you will often want to use image borders and backgrounds. The usual process for styling elements in Codename One is:\u003c/p\u003e","title":"Rounded Corners, Gradients, and Shadows with CSS"},{"content":"\nSince we announced the new GUI builder work we got quite a few questions in the discussion forum and offline\nso I prepared a quick video showing how the new GUI builder will look when released (more or less). Notice that\na lot of things will change with the GUI builder but some things are pretty much fixed such as the basic architecture\nwith the XML to Java process. This is unlikely to change much.\nSome developers asked for samples of the XML and Java code the new GUI builder generates.\nFor your convenience this is the code for the demo above specifically the XML gui file is:\n\u0026lt;?xml version=\u0026quot;1.0\u0026quot; encoding=\u0026quot;UTF-8\u0026quot;?\u0026gt; \u0026lt;component type=\u0026quot;Form\u0026quot; layout=\u0026quot;BoxLayout\u0026quot; boxLayoutAxis=\u0026quot;Y\u0026quot; title=\u0026quot;TestForm\u0026quot; name=\u0026quot;TestForm\u0026quot;\u0026gt; \u0026lt;component type=\u0026quot;TextField\u0026quot; text=\u0026quot;TextField\u0026quot; name=\u0026quot;Text_Field_1\u0026quot;\u0026gt; \u0026lt;/component\u0026gt; \u0026lt;component type=\u0026quot;Label\u0026quot; text=\u0026quot;Label\u0026quot; name=\u0026quot;Label_1\u0026quot;\u0026gt; \u0026lt;/component\u0026gt; \u0026lt;component type=\u0026quot;Container\u0026quot; layout=\u0026quot;FlowLayout\u0026quot; flowLayoutFillRows=\u0026quot;false\u0026quot; flowLayoutAlign=\u0026quot;1\u0026quot; flowLayoutValign=\u0026quot;0\u0026quot; name=\u0026quot;Container_1\u0026quot;\u0026gt; \u0026lt;component type=\u0026quot;Button\u0026quot; text=\u0026quot;This Button\u0026quot; name=\u0026quot;Button_2\u0026quot;\u0026gt; \u0026lt;/component\u0026gt; \u0026lt;/component\u0026gt; \u0026lt;component type=\u0026quot;Button\u0026quot; text=\u0026quot;Hi World\u0026quot; name=\u0026quot;Button_1\u0026quot; actionEvent=\u0026quot;true\u0026quot;\u0026gt; \u0026lt;/component\u0026gt; \u0026lt;/component\u0026gt; The Java code to match that is:\npublic class TestForm extends com.codename1.ui.Form { public TestForm() { this(com.codename1.ui.util.Resources.getGlobalResources()); } public TestForm(com.codename1.ui.util.Resources resourceObjectInstance) { initGuiBuilderComponents(resourceObjectInstance); } //-- DON'T EDIT BELOW THIS LINE!!! private com.codename1.ui.TextField gui_Text_Field_1 = new com.codename1.ui.TextField(); private com.codename1.ui.Label gui_Label_1 = new com.codename1.ui.Label(); private com.codename1.ui.Container gui_Container_1 = new com.codename1.ui.Container(new com.codename1.ui.layouts.FlowLayout()); private com.codename1.ui.Button gui_Button_2 = new com.codename1.ui.Button(); private com.codename1.ui.Button gui_Button_1 = new com.codename1.ui.Button(); // \u0026lt;editor-fold defaultstate=\u0026quot;collapsed\u0026quot; desc=\u0026quot;Generated Code\u0026quot;\u0026gt; private void guiBuilderBindComponentListeners() { EventCallbackClass callback = new EventCallbackClass(); gui_Button_1.addActionListener(callback); } class EventCallbackClass implements com.codename1.ui.events.ActionListener, com.codename1.ui.events.DataChangedListener { private com.codename1.ui.Component cmp; public EventCallbackClass(com.codename1.ui.Component cmp) { this.cmp = cmp; } public EventCallbackClass() { } public void actionPerformed(com.codename1.ui.events.ActionEvent ev) { if(ev.getSource() == gui_Button_1) { onButton_1ActionEvent(ev); } } public void dataChanged(int type, int index) { } } private void initGuiBuilderComponents(com.codename1.ui.util.Resources resourceObjectInstance) { guiBuilderBindComponentListeners(); setLayout(new com.codename1.ui.layouts.BoxLayout(com.codename1.ui.layouts.BoxLayout.Y_AXIS)); setTitle(\u0026quot;TestForm\u0026quot;); setName(\u0026quot;TestForm\u0026quot;); addComponent(gui_Text_Field_1); addComponent(gui_Label_1); addComponent(gui_Container_1); gui_Container_1.setName(\u0026quot;Container_1\u0026quot;); gui_Container_1.addComponent(gui_Button_2); gui_Button_2.setText(\u0026quot;This Button\u0026quot;); gui_Button_2.setName(\u0026quot;Button_2\u0026quot;); addComponent(gui_Button_1); gui_Text_Field_1.setText(\u0026quot;TextField\u0026quot;); gui_Text_Field_1.setName(\u0026quot;Text_Field_1\u0026quot;); gui_Label_1.setText(\u0026quot;Label\u0026quot;); gui_Label_1.setName(\u0026quot;Label_1\u0026quot;); gui_Container_1.setName(\u0026quot;Container_1\u0026quot;); gui_Button_1.setText(\u0026quot;Hi World\u0026quot;); gui_Button_1.setName(\u0026quot;Button_1\u0026quot;); }// \u0026lt;/editor-fold\u0026gt; //-- DON'T EDIT ABOVE THIS LINE!!! public void onButton_1ActionEvent(com.codename1.ui.events.ActionEvent ev) { Dialog.show(\u0026quot;Hi\u0026quot;, \u0026quot;Hi world: \u0026quot; + gui_Text_Field_1.getText(), \u0026quot;OK\u0026quot;, null); } } Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nClement Levallois — October 15, 2015 at 6:07 am (permalink) Clement Levallois says:\nhello,\ngreat stuff as usual. May I suggest that the workflow allows for a \u0026ldquo;all without coding\u0026rdquo; route? Your demo showed that 2 lines of code had to be added when a new \u0026ldquo;GUi form\u0026rdquo; was created, in order to make it displayed. A tick box in the wizard at the moment of Form creation could do it.\nEssentially, it is key to allow beginners to use the designer much before they have to write even one line of code, as is the case now.\nShai Almog — October 15, 2015 at 6:39 am (permalink) Shai Almog says:\nGood point. We should have some better project templates, ideally with ready made projects that already include some forms.\nWe did that with the old designer (e.g. with the Tabs based application) but it wasn’t used much so we need to get more refined use cases for this.\nRight now I’d like to stabilize the designer so we can start building on top of it both tutorials and things such as this. At the moment this is somewhat of a regression for a \u0026ldquo;no coding\u0026rdquo; approach since some things like navigating from one form to the next aren’t supported in the new GUI builder. Naturally, we want to fix that.\nmtran — October 16, 2015 at 2:49 pm (permalink) mtran says:\nWhere can I download the Gui Buider ?\nShai Almog — October 17, 2015 at 4:31 am (permalink) Shai Almog says:\nIt will be a part of the next plugin update early next week.\nJeremy — October 18, 2015 at 2:38 pm (permalink) Jeremy says:\nGood job, but I think it would even be better if the Gui builder is designed such that it is possible to switch between the drag and drop style and the XML layout.\nShai Almog — October 19, 2015 at 2:17 am (permalink) Shai Almog says:\nThanks for the feedback.\nAs you can see above the XML syntax wasn’t designed for human consumption as much as it was designed for accuracy. So editing this will be less intuitive.\nYou can edit this XML thru NetBeans and also use it to find out what happened if something went wrong. I think its a better approach since NetBeans already has great XML editing capabilities.\nChidiebere Okwudire — October 29, 2015 at 3:48 pm (permalink) Chidiebere Okwudire says:\nHi Shai,\nI like what I see in the video. One thing that’s still unclear to me is what will eventually happen to the navigation logic that is present in the current GUI builder. Can you say something about that? Basically, how is navigation envisaged to work in the new GUI builder especially for scenarios where some forms are completely handcoded whereas others are created using the GUI builder?\nShai Almog — October 30, 2015 at 5:04 am (permalink) Shai Almog says:\nHi,\nin the new GUI builder each form/container lives in isolation which is similar to the way traditional Java GUI builders have always worked.\nThe migration wizard we just introduced generates a fake state machine that just moves you between form instances.\nBecause of that the new GUI builder is more like a handcoded app than a GUI builder app.\nbledi — October 31, 2015 at 4:52 pm (permalink) bledi says:\nHello,\ni just downloaded the last version of the netbenas plugin and there seems not te be a new gui builder. When are you planning to relase the new one, as ti seems very promissing. Thank you\nShai Almog — November 1, 2015 at 4:27 am (permalink) Shai Almog says:\nHi,\nWhere did you download it from and what’s the version. 3.2.2 is the latest version of the NetBeans plugin.\nbledi — November 1, 2015 at 11:01 am (permalink) bledi says:\nI installed again from the netbeans plugins and now i have 3.2.2. On all newly created project i cannot add events to buttons etc. On already existing projects it works as before. There is a thread in the google group for this also.\nDan — November 5, 2015 at 3:16 am (permalink) Dan says:\nThanks for this overview, Shai – and thanks for including it in the latest CodenameOne release. Downloaded it today and have started playing with it. Thanks for the tip about the XML file – for some reason, dragging and dropping a textfield (for me at least) kept it as type \u0026ldquo;Label\u0026rdquo;. so if i go into the XML and change the type to \u0026ldquo;TextField\u0026rdquo; it seems to come out ok. Keep up the good work! – dan\nShai Almog — November 6, 2015 at 4:26 am (permalink) Shai Almog says:\nHi,\nthanks for the feedback. We are making heavy changes to the tool as we speak to get it to alpha level. Our focus in the technology preview was on the concept and the XML process with back and forth communication to the IDE.\nYaakov Gesher — November 8, 2015 at 7:28 am (permalink) Yaakov Gesher says:\nHi, I just converted an existing project using the migration wizard, and in all the generated files the NetBeans shows me compilation errors: Cannot find symbol ‘setGlobalResources’ in class ‘Resources’. After refreshing project libraries, the errors all went away. Just in case anyone else runs into the same issue!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/gui-builder-walkthru/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/gui-builder-walkthru/new-gui-builder-preview.png\"\u003e\u003c/p\u003e\n\u003cp\u003eSince we announced the new GUI builder work we got quite a few questions in the discussion forum and offline\u003cbr\u003e\nso I prepared a quick video showing how the new GUI builder will look when released (more or less). Notice that\u003cbr\u003e\na lot of things will change with the GUI builder but some things are pretty much fixed such as the basic architecture\u003cbr\u003e\nwith the XML to Java process. This is unlikely to change much.\u003c/p\u003e","title":"GUI Builder Walkthru"},{"content":"\nThis is the third and final instalment in a series on integrating 3rd party native SDKs in your Codename One application. If you missed the first two chapters, I recommend you begin with part one before reading this tutorial, as it provides much needed context for the procedures described here.\nPart 2: Implementing the iOS Native Code Part 1 of this tutorial focused on the Android native integration. Now we’ll shift our focus to the iOS implementation.\nAfter selecting \u0026ldquo;Generate Native Interfaces\u0026rdquo; for our \u0026ldquo;MobihelpNative\u0026rdquo; class, you’ll find a native/ios directory in your project with the following files:\ncom_codename1_freshdesk_MobihelpNativeImpl.h\ncom_codename1_freshdesk_MobihelpNativeImpl.m\nThese files contain stub implementations corresponding to our MobihelpNative class.\nWe make use of the API docs to see how the native SDK needs to be wrapped. The method names aren’t the same. E.g. instead of a method showFeedback(), it has a message -presentFeedback:\nWe more-or-less just follow the iOS integration guide for wrapping the API. Some key points include:\nRemember to import the Mobihelp.h file in your header file:\n#import \u0026quot;Mobihelp.h\u0026quot; Similar to our use of runOnUiThread() in Android, we will wrap all of our API calls in either dispatch_async() or dispatch_sync() calls to ensure that we are interacting with the Mobihelp API on the app’s main thread rather than the Codename One EDT.\nSome methods/messages in the Mobihelp SDK require us to pass a UIViewController as a parameter. In Codename One, the entire application uses a single UIViewController: CodenameOne_GLViewController. You can obtain a reference to this using the [CodenameOne_GLViewController instance] message. We need to import its header file:\n#import \u0026quot;CodenameOne_GLViewController.h\u0026quot; As an example, let’s look at the showFeedback() method:\n-(void)showFeedback{ dispatch_async(dispatch_get_main_queue(), ^{ [[Mobihelp sharedInstance] presentFeedback:[CodenameOne_GLViewController instance]]; }); } Using the MobihelpNativeCallback We described earlier how we created a static method on the MobihelpNativeCallback class so that native code could easily fire a callback method. Now let’s take a look at how this looks from the iOS side of the fence. Here is the implementation of getUnreadCountAsync():\n-(void)getUnreadCountAsync:(int)param{ dispatch_async(dispatch_get_main_queue(), ^{ [[Mobihelp sharedInstance] unreadCountWithCompletion:^(NSInteger count){ com_codename1_freshdesk_MobihelpNativeCallback_fireUnreadUpdatesCallback___int_int_int(CN1_THREAD_GET_STATE_PASS_ARG param, 3 /*SUCCESS*/, count); }]; }); } In our case the iOS SDK version of this method is +unreadCountWithCompletion: which takes a block (which is like an anonymous function) as a parameter.\nThe callback to our Codename One function occurs on this line:\ncom_codename1_freshdesk_MobihelpNativeCallback_fireUnreadUpdatesCallback___int_int_int(CN1_THREAD_GET_STATE_PASS_ARG param, 3 /*SUCCESS*/, count); Some things worth mentioning here:\nThe method name is the result of taking the FQN (com.codename1.freshdesk.MobihelpNativeCallback.fireUpdateUnreadUpdatesCallback(int, int, int)) and replacing all . characters with underscores, suffixing two underscores after the end of the method name, then appending _int once for each of the int arguments.\nWe also need to import the header file for this class:\n#import \u0026quot;com_codename1_freshdesk_MobihelpNativeCallback.h\u0026quot; Bundling Native iOS SDK Now that we have implemented our iOS native interface, we need to bundle the Mobihelp iOS SDK into our project. There are a few different scenarios you may face when looking to include a native SDK:\nThe SDK includes .bundle resource files. In this case, just copy the .bundle file(s) into your native/ios directory.\nThe SDK includes .h header files. In this case, just copy the .h file(s) into your native/ios directory.\nThe SDK includes .a files. In this case, just copy the .a file(s) into your native/ios directory.\nThe SDK includes .framework files. This is a bit tricker as Codename One doesn’t support simply copying the .framework files inside your project. In this case you need to perform the following:\nRight click on the .framework file (if you are using OS X) and select \u0026ldquo;Show Package Contents\u0026rdquo;.\nFind the \u0026ldquo;binary\u0026rdquo; file within the framework, and copy it into your native/ios directory – but rename it libXXX.a (where XXX is the name of the binary).\nCopy all .h files from the framework into your native/ios directory.\nUpdate all #import statements in the headers from #import \u0026lt;FrameworkName/FileName.h\u0026gt; format to simply #import \u0026quot;FileName.h\u0026quot;\nThe FreshDesk SDK doesn’t include any .framework files, so we don’t need to worry about that last scenario. We simply download the iOS SDK, copy the libFDMobihelpSDK.a, Mobihelp.h. MHModel.bundle, MHResources.bundle, and MHLocalization/en.proj/MHLocalizable.strings into native/ios.\nTroubleshooting iOS If you run into problems with the build, you can select \u0026ldquo;Include Sources\u0026rdquo; in the build server to download the resulting Xcode Project. You can then debug the Xcode project locally, make changes to your iOS native implementation files, and copy them back into your project once it is building properly.\nAdding Required Core Libraries and Frameworks The iOS integration guide for the FreshDesk SDK lists the following core frameworks as dependencies:\nWe can add these dependencies to our project using the ios.add_libs build hint. E.g.\nI.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 \u0026ldquo;include sources\u0026rdquo; checked, then looked at the frameworks that were included).\nPart 3 : Packaging as a .cn1lib During the initial development, I generally find it easier to use a regular Codename One project so that I can run and test as I go. But once it is stabilized, and I want to distribute the library to other developers, I will transfer it over to a Codename One library project. This general process involves:\nCreate a Codename One Library project.\nCopy the .java files from my original project into the library project.\nCopy the native directory from the original project into the library project.\nCopy the relevant build hints from the original project’s codenameone_settings.properties file into the library project’s codenameone_library_appended.properties file.\nIn the case of the FreshDesk .cn1lib, I modified the original project’s build script to generate and build a libary project automatically. But that is beyond the scope of this tutorial.\nSummary After walking through this tutorial, you should have all the required knowledge to wrap native SDKs into your own codename one libraries. Wrapping native SDKs is a really easy way to extend the capabilities of the Codename One platform. If you plan to create such a library, I encourage you to blog about it and post your experiences to the Codename One google group. We’re always interested in hearing how the community is using Codename One, and we’re especially interested in hearing about the creative ways that you are extending it.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/integrating-3rd-party-native-sdks-part-3/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/integrating-3rd-party-native-sdks-part-3/native-sdks-header.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is the third and final instalment in a series on integrating 3rd party native SDKs in your Codename One application. If you missed the first two chapters, I recommend you begin with part one before reading this tutorial, as it provides much needed context for the procedures described here.\u003c/p\u003e\n\u003ch2 id=\"part-2-implementing-the-ios-native-code\"\u003ePart 2: Implementing the iOS Native Code\u003c/h2\u003e\n\u003cp\u003ePart 1 of this tutorial focused on the Android native integration. Now we’ll shift our focus to the iOS implementation.\u003c/p\u003e","title":"Integrating 3rd Party Native SDKs Part III"},{"content":"\nCodename One 3.2 is scheduled for Tuesday the 27th of October. In keeping with our successful 3.1 release we’ll\nuse a very short one week code freeze on the 20th of October at which point we will only commit crucial fixes\nwith code review. I hope we can land quite a few new features for the release, the GUI builder is getting\nvery close although its still a very rough product and will only be featured as a \u0026ldquo;technology preview\u0026rdquo; showing\nthe direction we are heading rather than a final product.\nNew Approach To Demos Up until now we always thought about demos as developers often do: \u0026ldquo;As a tool to show how to program using\na set of features in the tool\u0026rdquo;.\nRecently, after working on my spouses Yoga Studio management app I came to the epiphany that this isn’t\nthe best way for mobile app demos. The main problem is that we can’t upload these demos to app stores\nand show them running on a device. So with that in mind we are rethinking some future demos starting with\na quick and dirty Solitaire Klondike demo that we made within a weekend\nand submitted to the store.\nCheck out the demo page where you can see the full code of what is now a production app that you can download\nvia itunes and google play.\nWe have a couple of additional apps that we need to cleanup and submit including the Yoga Studio app\nthat demonstrates a very common use case of a database driven app. We’ll try to clean that up and prepare\nit for mass consumption/store submission.\nIn Other News The performance enhancement for image tiling from Fabricio that we discussed last week finally landed after\na lot of hard work debugging it by Fabricio and Steve. You should notice 9-piece images performing better\non both iOS \u0026amp; Android.\nWe are moving to make Java 8 builds into the default build mode, we are pretty thrilled by the Java 8 support\nso far and want more newbies to be exposed to it. You would still have the checkbox for Java 8 mode when creating\na new project (if you are running on JDK 8 or newer!) but now it will be checked by default.\nWe also added get/setGlobalResources methods to the Resources class.\nThis really simplifies working with the new GUI builder since new GUI builder files will no longer be a part of\na resource file you would need to pass them a resources object somehow. Initially we thought about passing\nit in the constructor but this seems tedious, with the global resources this should be much simpler. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nRoss Taylor — October 27, 2015 at 11:12 am (permalink) Ross Taylor says:\nHey I tried your solitaire app. However I have some critiques and wonder if its anything related to codenameone. The first is the card images are grainy (medium – low quality). I suppose you did this to save app size? The second is there is a line separation in the menu command after the \u0026ldquo;About\u0026rdquo;, where I think it shouldn’t be since it makes the menu command separation look untidy (looks like something broke off suddenly). The third is the background blurs (or refreshes?) when the menu command and the About dialog is disposed. The last is that when the button of the dialog is pressed in the pressed state, the highlighted area of the button way exceeds the area of the actual button. Other than these UI blips, the app seems to be pretty fast.\nShai Almog — October 28, 2015 at 3:29 am (permalink) Shai Almog says:\nHi. Its mostly related to my lazyness when building the app. I also neglected to customize the overflow menu icon properly and its sizing/color differ from the color of the other icons.\nSpecifically the overflow feature of the toolbar needs some refinement in the default theme, both its in/out transition and look need some work in the default theme. Menus are remarkably customizable in Codename One and this type of menu is pretty new so we didn’t get much feedback for it, I’ve passed your comments to the guy who did it and he agrees we should fix that by default.\nThe larger button than the dialog is something I just noticed for the first time, it seems that just the edges of the button exceed. Haven’t noticed it because I normally press and release. This is a property of the Android theme and isn’t indicative of anything inherent. We do need to improve that behavior though.\nJoe — November 2, 2015 at 1:06 pm (permalink) Joe says:\nI cloned the demo on my local. Looks like the project files are for NetBean Do you have the instruction of how to import the projects into Eclipse?\nShai Almog — November 3, 2015 at 4:29 am (permalink) Shai Almog says:\nGenerally for every imported NetBeans project just create a new project in eclipse using the same main class and package.\nCopy the src dir and libs dir on top of their Eclipse counterparts.\nCopy the codenameone_settings.proper… on top of the existing one and the icon.png.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/release-plan-for-3-2-new-approach-to-demos/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/release-plan-for-3-2-new-approach-to-demos/solitaire.png\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One 3.2 is scheduled for Tuesday the 27th of October. In keeping with our successful 3.1 release we’ll\u003cbr\u003e\nuse a very short one week code freeze on the 20th of October at which point we will only commit crucial fixes\u003cbr\u003e\nwith code review. I hope we can land quite a few new features for the release, the GUI builder is getting\u003cbr\u003e\nvery close although its still a very rough product and will only be featured as a \u0026ldquo;technology preview\u0026rdquo; showing\u003cbr\u003e\nthe direction we are heading rather than a final product.\u003c/p\u003e","title":"Release Plan For 3.2 \u0026 New Approach To Demos"},{"content":"\nThis blog post is part two in a three-part series on integrating 3rd party native SDKs into Codename One application. I recommend you start with part one in this series as it will give you much-needed context to understand the procedures described in part two and three.\nIn part one, we described the design and development of the public API and native interfaces of the Codename One FreshDesk library. In this installment we’ll move onto the development of the Android side of the native interface.\nStep 5: Implementing the Native Interface in Android Now that we have set up our public API and our native interface, it is time to work on the native side of things. You can generate stubs for all platforms in your IDE (Netbeans in my case), by right clicking on the MobihelpNative class in the project explorer and selecting \u0026ldquo;Generate Native Access\u0026rdquo;.\nThis will generate a separate directory for each platform inside your project’s native directory:\nInside the android directory, this generates a com/codename1/freshdesk/MobihelpNativeImpl class with stubs for each method.\nOur implementation will be a thin wrapper around the native Android SDK. See the source here.\nSome highlights:\nContext : The native API requires us to pass a context object as a parameter on many methods. This should be the context for the current activity. It will allow the FreshDesk API to know where to return to after it has done its thing. Codename One provides a class called AndroidNativeUtil that allows us to retrieve the app’s Activity (which includes the Context). We’ll wrap this with a convenience method in our class as follows:\nprivate static Context context() { return com.codename1.impl.android.AndroidNativeUtil.getActivity().getApplicationContext(); } This will enable us to easily wrap the freshdesk native API. E.g.:\npublic void clearUserData() { com.freshdesk.mobihelp.Mobihelp.clearUserData(context()); } runOnUiThread() – Many of the calls to the FreshDesk API may have been made from the Codename One EDT. However, Android has its own event dispatch thread that should be used for interacting with native Android UI. Therefore, any API calls that look like they initiate some sort of native Android UI process should be wrapped inside Android’s runOnUiThread() method which is similar to Codename One’s Display.callSerially() method. E.g. see the showSolutions() method:\npublic void showSolutions() { activity().runOnUiThread(new Runnable() { public void run() { com.freshdesk.mobihelp.Mobihelp.showSolutions(context()); } }); } (Note here that the activity() method is another convenience method to retrieve the app’s current Activity from the AndroidNativeUtil class).\nCallbacks. We discussed, in detail, the mechanisms we put in place to enable our native code to perform callbacks into Codename One. You can see the native side of this by viewing the getUnreadCountAsync() method implementation:\npublic void getUnreadCountAsync(final int callbackId) { activity().runOnUiThread(new Runnable() { public void run() { com.freshdesk.mobihelp.Mobihelp.getUnreadCountAsync(context(), new com.freshdesk.mobihelp.UnreadUpdatesCallback() { public void onResult(com.freshdesk.mobihelp.MobihelpCallbackStatus status, Integer count) { MobihelpNativeCallback.fireUnreadUpdatesCallback(callbackId, status.ordinal(), count); } }); } }); } Step 6: Bundling the Native SDKs The last step (at least on the Android side) is to bundle the FreshDesk SDK. For Android, there are a few different scenarios you’ll run into for embedding SDKs:\nThe SDK includes only Java classes – NO XML UI files, assets, or resources that aren’t included inside a simple .jar file. In this case, you can just place the .jar file inside your project’s native/android directory.\nThe SDK includes some XML UI files, resources, and assets. In this case, the SDK is generally distributed as an Android project folder that can be imported into an Eclipse or Android studio workspace. In general, in this case, you would need to zip the entire directory and change the extension of the resulting .zip file to \u0026ldquo;.andlib\u0026rdquo;, and place this in your project’s native/android directory.\nThe SDK is distributed as an.aar file – In this case you can just copy the .aar file into your native/android directory.\nThe FreshDesk SDK The FreshDesk (aka Mobihelp) SDK is distributed as a project folder (i.e. scenario 2 from the above list). Therefore, our procedure is to download the SDK (download link), and rename it from mobihelp_sdk_android.zip to mobihelp_sdk_android.andlib, and copy it into our native/android directory.\nDependencies Unfortunately, in this case there’s a catch. The Mobihelp SDK includes a dependency:\nMobihelp SDK depends on AppCompat-v7 (Revision 19.0+) Library. You will need to update project.properties to point to the Appcompat library.\nIf we look inside the project.properties file (inside the Mobihelp SDK directory— i.e. you’d need to extract it from the zip to view its contents), you’ll see the dependency listed:\nandroid.library.reference.1=../appcompat_v7 I.e. it is expecting to find the appcompat_v7 library located in the same parent directory as the Mobihelp SDK project. After a little bit of research (if you’re not yet familiar with the Android AppCompat support library), we find that the AppCompat_v7 library is part of the Android Support library, which can can installed into your local Android SDK using Android SDK Manager. Installation processed specified here.\nAfter installing the support library, you need to retrieve it from your Android SDK. You can find that .aar file inside the ANDROID_HOME/sdk/extras/android/m2repository/com/android/support/appcompat-v7/19.1.0/ directory (for version 19.1.0). The contents of that directory on my system are:\nappcompat-v7-19.1.0.aar\tappcompat-v7-19.1.0.pom appcompat-v7-19.1.0.aar.md5\tappcompat-v7-19.1.0.pom.md5 appcompat-v7-19.1.0.aar.sha1\tappcompat-v7-19.1.0.pom.sha1 There are two files of interest here:\nappcompat-v7-19.1.0.aar – This is the actual library that we need to include in our project to satisfy the Mobisdk dependency.\nappcompat-v7-19.1.0.pom – This is the Maven XML file for the library. It will show us any dependencies that the appcompat library has. We will also need to include these dependencies:\n\u0026lt;dependencies\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;com.android.support\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;support-v4\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;19.1.0\u0026lt;/version\u0026gt; \u0026lt;scope\u0026gt;compile\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;/dependencies\u0026gt; i.e. We need to include the support-v4 library version 19.1.0 in our project. This is also part of the Android Support library. If we back up a couple of directories to: ANDROID_HOME/sdk/extras/android/m2repository/com/android/support, we’ll see it listed there:\nappcompat-v7\tpalette-v7 cardview-v7\trecyclerview-v7 gridlayout-v7\tsupport-annotations leanback-v17\tsupport-v13 mediarouter-v7\tsupport-v4 multidex\ttest multidex-instrumentation + And if we look inside the appropriate version directory of support-v4 (in ANDROID_HOME/sdk/extras/android/m2repository/com/android/support/support-v4/19.1.0), we see:\nsupport-v4-19.1.0-javadoc.jar\tsupport-v4-19.1.0.jar support-v4-19.1.0-javadoc.jar.md5\tsupport-v4-19.1.0.jar.md5 support-v4-19.1.0-javadoc.jar.sha1\tsupport-v4-19.1.0.jar.sha1 support-v4-19.1.0-sources.jar\tsupport-v4-19.1.0.pom support-v4-19.1.0-sources.jar.md5\tsupport-v4-19.1.0.pom.md5 support-v4-19.1.0-sources.jar.sha1\tsupport-v4-19.1.0.pom.sha1 Looks like this library is pure Java classes, so we only need to include the support-v4-19.1.0.jar file into our project. Checking the .pom file we see that there are no additional dependencies we need to add.\nSo, to summarize our findings, we need to include the following files in our native/android directory:\nappcompat-v7-19.1.0.aar\nsupport-v4-19.1.0.jar\nAnd since our Mobihelp SDK lists the appcompat_v7 dependency path as \u0026ldquo;../appcompat_v7\u0026rdquo; in its project.properties file, we are going to rename appcompat-v7-19.1.0.aar to appcompat_v7.aar.\nWhen all is said and done, our native/android directory should contain the following:\nappcompat_v7.aar\tmobihelp.andlib com\tsupport-v4-19.1.0.jar Step 7 : Injecting Android Manifest and Proguard Config The final step on the Android side is to inject necessary permissions and services into the project’s AndroidManifest.xml file.\nWe can find the manifest file injections required by opening the AndroidManifest.xml file from the MobiHelp SDK project. Its contents are as follows:\n\u0026lt;?xml version=\u0026quot;1.0\u0026quot; encoding=\u0026quot;utf-8\u0026quot;?\u0026gt; \u0026lt;manifest xmlns_android=\u0026quot;http://schemas.android.com/apk/res/android\u0026quot; package=\u0026quot;com.freshdesk.mobihelp\u0026quot; android_versionCode=\u0026quot;1\u0026quot; android_versionName=\u0026quot;1.0\u0026quot; \u0026gt; \u0026lt;uses-sdk android_minSdkVersion=\u0026quot;10\u0026quot; /\u0026gt; \u0026lt;uses-permission android_name=\u0026quot;android.permission.INTERNET\u0026quot; /\u0026gt; \u0026lt;uses-permission android_name=\u0026quot;android.permission.READ_LOGS\u0026quot; /\u0026gt; \u0026lt;uses-permission android_name=\u0026quot;android.permission.ACCESS_NETWORK_STATE\u0026quot; /\u0026gt; \u0026lt;uses-permission android_name=\u0026quot;android.permission.WRITE_EXTERNAL_STORAGE\u0026quot; /\u0026gt; \u0026lt;application\u0026gt; \u0026lt;activity android_name=\u0026quot;com.freshdesk.mobihelp.activity.SolutionArticleListActivity\u0026quot; android_configChanges=\u0026quot;orientation|screenSize\u0026quot; android_theme=\u0026quot;@style/Theme.Mobihelp\u0026quot; android_windowSoftInputMode=\u0026quot;adjustPan\u0026quot; \u0026gt; \u0026lt;/activity\u0026gt; \u0026lt;activity android_name=\u0026quot;com.freshdesk.mobihelp.activity.FeedbackActivity\u0026quot; android_configChanges=\u0026quot;keyboardHidden|orientation|screenSize\u0026quot; android_theme=\u0026quot;@style/Theme.Mobihelp\u0026quot; android_windowSoftInputMode=\u0026quot;adjustResize|stateVisible\u0026quot; \u0026gt; \u0026lt;/activity\u0026gt; \u0026lt;activity android_name=\u0026quot;com.freshdesk.mobihelp.activity.InterstitialActivity\u0026quot; android_configChanges=\u0026quot;orientation|screenSize\u0026quot; android_theme=\u0026quot;@style/Theme.AppCompat\u0026quot;\u0026gt; \u0026lt;/activity\u0026gt; \u0026lt;activity android_name=\u0026quot;com.freshdesk.mobihelp.activity.TicketListActivity\u0026quot; android_parentActivityName=\u0026quot;com.freshdesk.mobihelp.activity.SolutionArticleListActivity\u0026quot; android_theme=\u0026quot;@style/Theme.Mobihelp\u0026quot; \u0026gt; \u0026lt;!-- Parent activity meta-data to support 4.0 and lower --\u0026gt; \u0026lt;meta-data android_name=\u0026quot;android.support.PARENT_ACTIVITY\u0026quot; android_value=\u0026quot;com.freshdesk.mobihelp.activity.SolutionArticleListActivity\u0026quot; /\u0026gt; \u0026lt;/activity\u0026gt; \u0026lt;activity android_name=\u0026quot;com.freshdesk.mobihelp.activity.SolutionArticleActivity\u0026quot; android_parentActivityName=\u0026quot;com.freshdesk.mobihelp.activity.SolutionArticleListActivity\u0026quot; android_theme=\u0026quot;@style/Theme.Mobihelp\u0026quot; android_configChanges=\u0026quot;orientation|screenSize|keyboard|keyboardHidden\u0026quot; \u0026gt; \u0026lt;!-- Parent activity meta-data to support 4.0 and lower --\u0026gt; \u0026lt;meta-data android_name=\u0026quot;android.support.PARENT_ACTIVITY\u0026quot; android_value=\u0026quot;com.freshdesk.mobihelp.activity.SolutionArticleListActivity\u0026quot; /\u0026gt; \u0026lt;/activity\u0026gt; \u0026lt;activity android_name=\u0026quot;com.freshdesk.mobihelp.activity.ConversationActivity\u0026quot; android_parentActivityName=\u0026quot;com.freshdesk.mobihelp.activity.SolutionArticleListActivity\u0026quot; android_theme=\u0026quot;@style/Theme.Mobihelp\u0026quot; android_windowSoftInputMode=\u0026quot;adjustResize|stateHidden\u0026quot; \u0026gt; \u0026lt;!-- Parent activity meta-data to support 4.0 and lower --\u0026gt; \u0026lt;meta-data android_name=\u0026quot;android.support.PARENT_ACTIVITY\u0026quot; android_value=\u0026quot;com.freshdesk.mobihelp.activity.SolutionArticleListActivity\u0026quot; /\u0026gt; \u0026lt;/activity\u0026gt; \u0026lt;activity android_name=\u0026quot;com.freshdesk.mobihelp.activity.AttachmentHandlerActivity\u0026quot; android_configChanges=\u0026quot;keyboardHidden|orientation|screenSize\u0026quot; android_parentActivityName=\u0026quot;com.freshdesk.mobihelp.activity.SolutionArticleListActivity\u0026quot; android_theme=\u0026quot;@style/Theme.Mobihelp\u0026quot; \u0026gt; \u0026lt;!-- Parent activity meta-data to support 4.0 and lower --\u0026gt; \u0026lt;meta-data android_name=\u0026quot;android.support.PARENT_ACTIVITY\u0026quot; android_value=\u0026quot;com.freshdesk.mobihelp.activity.SolutionArticleListActivity\u0026quot; /\u0026gt; \u0026lt;/activity\u0026gt; \u0026lt;service android_name=\u0026quot;com.freshdesk.mobihelp.service.MobihelpService\u0026quot; /\u0026gt; \u0026lt;receiver android_name=\u0026quot;com.freshdesk.mobihelp.receiver.ConnectivityReceiver\u0026quot; \u0026gt; \u0026lt;intent-filter\u0026gt; \u0026lt;action android_name=\u0026quot;android.net.conn.CONNECTIVITY_CHANGE\u0026quot; /\u0026gt; \u0026lt;/intent-filter\u0026gt; \u0026lt;/receiver\u0026gt; \u0026lt;/application\u0026gt; \u0026lt;/manifest\u0026gt; We’ll need to add the \u0026lt;uses-permission\u0026gt; tags and all of the contents of the \u0026lt;application\u0026gt; tag to our manifest file. Codename One provides the following build hints for these:\nandroid.xpermissions – For your \u0026lt;uses-permission\u0026gt; directives. Add a build hint with name android.xpermissions, and for the value, paste the actual \u0026lt;uses-permission\u0026gt; XML tag.\nandroid.xapplication – For the contents of your \u0026lt;application\u0026gt; tag.\nProguard Config For the release build, we’ll also need to inject some proguard configuration so that important classes don’t get stripped out at build time. The FreshDesk SDK instructions state:\nIf you use Proguard, please make sure you have the following included in your project’s proguard-project.txt\n-keep class android.support.v4.** { *; } -keep class android.support.v7.** { *; } In addition, if you look at the proguard-project.txt file inside the Mobihelp SDK, you’ll see the rules:\n-keep public class * extends android.app.Service -keep public class * extends android.content.BroadcastReceiver -keep public class * extends android.app.Activity -keep public class * extends android.preference.Preference -keep public class com.freshdesk.mobihelp.exception.MobihelpComponentNotFoundException -keepclassmembers class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; } We’ll want to merge this and then paste them into the build hint android.proguardKeep of our project.\nTroubleshooting Android Stuff If, after doing all this, your project fails to build, you can enable the \u0026ldquo;Include Source\u0026rdquo; option of the build server, then download the source project, open it in Eclipse or Android Studio, and debug from there.\nIn Our Next Instalment…​ In the third and final part of this blog series, we will shift our focus to the iOS side of the library.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/integrating-3rd-party-native-sdks-part-2/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/integrating-3rd-party-native-sdks-part-2/native-sdks-header.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis blog post is part two in a three-part series on integrating 3rd party native SDKs into Codename One application. I recommend you start with part one in this series as it will give you much-needed context to understand the procedures described in part two and three.\u003c/p\u003e\n\u003cp\u003eIn \u003ca href=\"http://www.codenameone.com/blog/integrating-3rd-party-native-sdks-part-1.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003epart one\u003c/a\u003e, we described the design and development of the public API and native interfaces of the Codename One FreshDesk library. In this installment we’ll move onto the development of the Android side of the native interface.\u003c/p\u003e","title":"Integrating 3rd Party Native SDKs Part II"},{"content":"\nWe are happy to announce support for local notifications on iOS and Android. Local notifications are similar to push notifications, except that they are initiated locally by the app, rather than remotely. They are useful for communicating information to the user while the app is running in the background, since they manifest themselves as pop-up notifications on supported devices.\nSending Notifications The process for sending a notification is:\nCreate a LocalNotification object with the information you want to send in the notification.\nPass the object to Display.scheduleLocalNotification().\nNotifications can either be set up as one-time only or as repeating.\nExample Sending Notification LocalNotification n = new LocalNotification(); n.setId(\u0026quot;demo-notification\u0026quot;); n.setAlertBody(\u0026quot;It's time to take a break and look at me\u0026quot;); n.setAlertTitle(\u0026quot;Break Time!\u0026quot;); n.setAlertSound(\u0026quot;/notification_sound_beep-01a.mp3\u0026quot;); // alert sound file name must begin with notification_sound Display.getInstance().scheduleLocalNotification( n, System.currentTimeMillis() + 10 * 1000, // fire date/time LocalNotification.REPEAT_MINUTE // Whether to repeat and what frequency ); The resulting notification will look like\nThe above screenshot was taken on the iOS simulator.\nReceiving Notifications The API for receiving/handling local notifications is also similar to push. Your application’s main lifecycle class needs to implement the com.codename1.notifications.LocalNotificationCallback interface which includes a single method:\npublic void localNotificationReceived(String notificationId) The notificationId parameter will match the id value of the notification as set using LocalNotification.setId().\nExample Receiving Notification public class BackgroundLocationDemo implements LocalNotificationCallback { //... public void init(Object context) { //... } public void start() { //... } public void stop() { //... } public void destroy() { //... } public void localNotificationReceived(String notificationId) { System.out.println(\u0026quot;Received local notification \u0026quot;+notificationId); } } __ localNotificationReceived() is only called when the user responds to the notification by tapping on the alert. If the user doesn’t opt to click on the notification, then this event handler will never be fired. Cancelling Notifications Repeating notifications will continue until they are canceled by the app. You can cancel a single notification by calling:\nDisplay.getInstance().cancelLocalNotification(notificationId); Where notificationId is the string id that was set for the notification using LocalNotification.setId().\nSample App You can see a full sample that uses the new local notifications API here. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nCarlos — October 1, 2015 at 10:32 am (permalink) Cool.\nIs it possible to reset an scheduled notification? I’m thinking on something like \u0026ldquo;Hey, it’s been a while since you last visited us\u0026rdquo;. So if the user opens the app before the notification is triggered, the scheduled time gets back to zero. I haven’t checked the api so I don’t know if something like this is possible.\nshannah78 — October 1, 2015 at 3:18 pm (permalink) shannah78 says:\nYes. You can cancel the existing notification, then schedule a new one. One strategy might be to cancel the notification in your start() method, the schedule it in your stop() method. Might be a good idea to additionally schedule the notification before the stop method (e.g. in the start method) so that the user will be triggered to allow notifications when the app opens.\nThe key is that nothing bad happens if you cancel a notification id that doesn’t exist.\nNick Koirala — October 5, 2015 at 9:20 pm (permalink) Nick Koirala says:\nWhat sort of limit is there for how far in advance a notification can be set? can it be days or months away?\nahmed — November 1, 2015 at 9:17 pm (permalink) ahmed says:\nhi. I am using intelliJ and updated the codename libs and found that the new notification folder is now part of the jar. However when implementing using the sample code and the sample application I do not get any notifications. I tried this on the simulator and also sent the build to the physical phone but same result, no notifications.\nShai Almog — November 2, 2015 at 3:27 am (permalink) Shai Almog says:\nThis will only work on devices. On which device type did you try?\nahmed — November 2, 2015 at 4:30 am (permalink) ahmed says:\niPhone 6 running iOS 9.\nshannah78 — November 5, 2015 at 3:54 pm (permalink) shannah78 says:\nI’m not aware of any limitation as to how far in advance the notification can be. On iOS you are limited to 64 notifications at a time. (recurring notifications are treated as a single notification).\nshannah78 — November 5, 2015 at 3:56 pm (permalink) shannah78 says:\nNotifications will only be shown when the app is not running, or in the background. If the app is in the foreground, the notification will not appear.\nahmed — November 5, 2015 at 4:27 pm (permalink) ahmed says:\nYes of course. The app was in the background at the time the scheduled notification would have fired.\nshannah78 — November 5, 2015 at 5:26 pm (permalink) shannah78 says:\nWow. Just looked at the source and it seems that the entire local notifications section had been commented out. This was caused by a sort of git race condition. I implemented it -\u0026gt; Shai commented it out because of a build error-\u0026gt; I fixed it and uncommented it -\u0026gt; tried to push but needed to first merge from origin master… so merged from master which re-added the comment outs .\nI have now uncommented it so it should be working next time Shai updates the server.\nhttps://github.com/codename…\nahmed — November 6, 2015 at 7:04 pm (permalink) ahmed says:\nThank you for the info and update. I assume the IntelliJ lib will also get updated with the next build. Will keep an eye open.\nKeshav Rai — April 11, 2016 at 4:22 pm (permalink) Keshav Rai says:\nHey! Fellas 🙂 #iOs\nCan we set CUSTOM SOUNDS on Local Notifications? !?!\nPls. Help …\nChen Fishbein — April 22, 2016 at 8:46 pm (permalink) Chen Fishbein says:\nFrom the code above :\nn.setAlertSound(\u0026ldquo;beep-01a.mp3\u0026rdquo;);\nLukman Javalove Idealist Jaji — June 21, 2016 at 10:19 pm (permalink) Lukman Javalove Idealist Jaji says:\nOne question…can we place a container with components in the notification…similar to what Uber and other apps have? I will like o have a few buttons in that area\nShai Almog — June 22, 2016 at 3:42 am (permalink) Shai Almog says:\nThose aren’t containers as you can’t add arbitrary data there. Currently that isn’t supported as the behavior here differs too much between platforms but if there is demand for it we might address it thru common use cases.\nmadhu thestudent — July 20, 2016 at 11:44 am (permalink) madhu thestudent says:\ncan we see the local notifications in simulator and how?\nmadhu thestudent — July 20, 2016 at 11:44 am (permalink) madhu thestudent says:\ndoes the codename one support notification builders and how?\nDaniel Le Cardinal — April 13, 2017 at 3:04 pm (permalink) Daniel Le Cardinal says:\nhi guys,\ncan someone tell me if local notification can allow to trigger some part of my app when it is in background ? For instance, i want to count the number of push notification received which are in a pending state (even if i restart my phone)?\nShai Almog — April 14, 2017 at 4:39 am (permalink) Shai Almog says:\nHi,\nyou can schedule a local notification to the background but it’s not exactly a background task. It’s more of a visual use case.\nApps don’t really run in the background in iOS, they perform background use cases which is a pretty limited scope. I’m assuming you want to do background processing similar to Androids services which is something iOS just doesn’t allow.\nShai Almog — April 14, 2017 at 4:40 am (permalink) Shai Almog says:\nSorry I didn’t see that comment.\nWe support local notifications which provide similar functionality see the discussion on this in the developer guide.\nChibuike Mba — May 10, 2017 at 7:22 am (permalink) Chibuike Mba says:\nHow can I reschedule my LocalNotification on device reboot?\nAndroid has this user permission which invokes a BroadcastReceiver but I can’t figure out how to use it with my LocalNotification.\nShai Almog — May 11, 2017 at 9:25 am (permalink) Shai Almog says:\nI replied here http://stackoverflow.com/qu…\nChibuike Mba — May 11, 2017 at 10:43 am (permalink) Chibuike Mba says:\nOK, will be expecting your reply.\nCh Hjelm — May 5, 2020 at 10:11 am (permalink) Ch Hjelm says:\nI use localNotificationReceived for setting reminders and it works as expected when the app is active in the background.\nHowever, when the app is not running (eg killed manually), tapping the ios notification starts up the app and calls init() and start() as expected, but it doesn’t seem to get around to calling localNotificationReceived after that. How can I ensure the call to localNotificationReceived happens so the app takes the action the user expects?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/local-notifications/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/local-notifications/local-notifications-header.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are happy to announce support for local notifications on iOS and Android. Local notifications are similar to push notifications, except that they are initiated locally by the app, rather than remotely. They are useful for communicating information to the user while the app is running in the background, since they manifest themselves as pop-up notifications on supported devices.\u003c/p\u003e\n\u003ch2 id=\"sending-notifications\"\u003eSending Notifications\u003c/h2\u003e\n\u003cp\u003eThe process for sending a notification is:\u003c/p\u003e","title":"Local Notifications on iOS and Android"},{"content":"\nThis past Thursday, we held our fourth webinar, and the topic was how to incorporate 3rd party native libraries into a Codename One app. I used the recently released FreshDesk cn1lib as a case study for this webinar. As the topic is a little involved, I decided to break it up into two webinars. In part one, we focused on the public API and architecture involved in developing a wrapper for a native SDK, and walked through the native implementation for Android.\nView a Recording of the Part I webinar\nIn part 2, scheduled for Thursday October 8th, we’ll show how to implement the iOS side of the library.\nSign up for Enhancing your App with 3rd Party Native Libraries Part 2\nThe Companion Tutorial For those of you who prefer written tutorials, I will be publishing a parallel 3-part series on this topic in the blog. The first part of the tutorial is contained in the remainder of this blog post.\nThe following is a description of the procedure that was used to create the Codename One FreshDesk library. This process can be easily adapted to wrap any native SDK on Android and iOS.\nStep 1 : Review the FreshDesk SDKs Before we begin, we’ll need to review the Android and iOS SDKs.\nFreshDesk Android SDK : Integration Guide | API Docs\nFreshDesk iOS SDK : Integration Guide | API Docs\nIn reviewing the SDKs, I’m looking to answer two questions:\nWhat should my Codename One FreshDesk API look like?\nWhat will be involved in integrating the native SDK in my app or lib?\nStep 2: Designing the Codename One Public API When designing the Codename One API, I often begin by looking at the Javadocs for the native Android SDK. If the class hierarchy doesn’t look too elaborate, I may decide model my Codename One public API fairly closely on the Android API. On the other hand, if I only need a small part of the SDK’s functionality, I may choose to create my abstractions around just the functionality that I need.\nIn the case of the FreshDesk SDK, it looks like most of the functionality is handled by one central class Mobihelp, with a few other POJO classes for passing data to and from the service. This is a good candidate for a comprehensive Codename One API.\nBefore proceeding, we also need to look at the iOS API to see if there are any features that aren’t included. While naming conventions in the iOS API are a little different than those in the Android API, it looks like they are functionally the same.\nTherefore, I choose to create a class hierarchy and API that closely mirrors the Android SDK.\nStep 3: The Architecture and Internal APIs A Codename One library that wraps a native SDK, will generally consist of the following:\nPublic Java API , consisting of pure Java classes that are intended to be used by the outside world.\nNative Interface(s). The Native Interface(s) act as a conduit for the public Java API to communicate to the native SDK. Parameters in native interface methods are limited to primitive types, arrays of primitive types, and Strings, as are return values.\nNative code. Each platform must include an implementation of the Native Interface(s). These implementations are written in the native language of the platform (e.g. Java for Android, and Objective-C for iOS).\nNative dependencies. Any 3rd party libraries required for the native code to work, need to be included for each platform. On android, this may mean bundling .jar files, .aar files, or .andlib files. On iOS, this may mean bundling .h files, .a files, and .bundle files.\nBuild hints. Some libraries will require you to add some extra build hints to your project. E.g. On Android you may need to add permissions to the manifest, or define services in the \u0026lt;Application\u0026gt; section of the manifest. On iOS, this may mean specifying additional core frameworks for inclusion, or adding build flags for compilation.\nThe following diagram shows the dependencies in a native library:\nIn the specific case of our FreshDesk API, the public API and classes will look like:\nThings to Notice The public API consists of the main class (Mobihelp), and a few supporting classes (FeedbackRequest, FeedbackType, MobihelpConfig, MobihelpCallbackStatus), which were copied almost directly from the Android SDK.\nThe only way for the public API to communicate with the native SDK is via the MobihelpNative interface.\nWe introduced the MobihelpNativeCallback class to facilitate native code calling back into the public API. This was necessary for a few methods that used asynchronous callbacks.\nStep 4: Implement the Public API and Native Interface We have already looked at the final product of the public API in the previous step, but let’s back up and walk through the process step-by-step.\nI wanted to model my API closely around the Android API, and the central class that includes all of the functionality of the SDK is the com.freshdesk.mobihelp.Mobihelp class, so we begin there.\nWe’ll start by creating our own package (com.codename1.freshdesk) and our own Mobihelp class inside it.\nAdapting Method Signatures The Context parameter In a first glance at the com.freshdesk.mobihelp.Mobihelp API we see that many of the methods take a parameter of type android.content.Context. This class is part of the core Android SDK, and will not be accessible to any pure Codename One APIs. Therefore, our public API cannot include any such references. Luckily, we’ll be able to access a suitable context in the native layer, so we’ll just omit this parameter from our public API, and inject them in our native implementation.\nHence, the method signature public static final void setUserFullName (Context context, String name) will simply become public static final void setUserFullName (String name) in our public API.\nNon-Primitive Parameters Although our public API isn’t constrained by the same rules as our Native Interfaces with respect to parameter and return types, we need to be cognizant of the fact that parameters we pass to our public API will ultimately be funnelled through our native interface. Therefore, we should pay attention to any parameters or return types that can’t be passed directly to a native interface, and start forming a strategy for them. E.g. consider the following method signature from the Android Mobihelp class:\npublic static final void showSolutions (Context activityContext, ArrayList\u0026lt;String\u0026gt; tags) We’ve already decided to just omit the Context parameter in our API, so that’s a non-issue. But what about the ArrayList\u0026lt;String\u0026gt; tags parameter? Passing this to our public API is no problem, but when we implement the public API, how will we pass this ArrayList to our native interface, since native interfaces don’t allow us to arrays of strings as parameters?\nI generally use one of three strategies in such cases:\nEncode the parameter as either a single String (e.g. using JSON or some other easily parseable format) or a byte[] array (in some known format that can easily be parsed in native code).\nStore the parameter on the Codename One side and pass some ID or token that can be used on the native side to retrieve the value.\nIf the data structure can be expressed as a finite number of primitive values, then simply design the native interface method to take the individual values as parameters instead of a single object. E.g. If there is a User class with properties name and phoneNumber, the native interface can just have name and phoneNumber parameters rather than a single user` parameter.\nIn this case, because an array of strings is such a simple data structure, I decided to use a variation on strategy number 1: Merge the array into a single string with a delimiter.\nIn any case, we don’t have to come up with the specifics right now, as we are still on the public API, but it will pay dividends later if we think this through ahead of time.\nCallbacks It is quite often the case that native code needs to call back into Codename One code when an event occurs. This may be connected directly to an API method call (e.g. as the result of an asynchronous method invocation), or due to something initiated by the operating system or the native SDK on its own (e.g. a push notification, a location event, etc..).\nNative code will have access to both the Codename One API and any native APIs in your app, but on some platforms, accessing the Codename One API may be a little tricky. E.g. on iOS you’ll be calling from Objective-C back into Java which requires knowledge of Codename One’s java-to-objective C conversion process. In general, I have found that the easiest way to facilitate callbacks is to provide abstractions that involve static java methods (in Codename One space) that accept and return primitive types.\nIn the case of our Mobihelp class, the following method hints at the need to have a \u0026ldquo;callback plan\u0026rdquo;:\npublic static final void getUnreadCountAsync (Context context, UnreadUpdatesCallback callback) The interface definition for UnreadUpdatesCallback is:\npublic interface UnreadUpdatesCallback { //This method is called once the unread updates count is available. void onResult(MobihelpCallbackStatus status, Integer count); } I.e. If we were to implement this method (which I plan to do), we need to have a way for the native code to call the callback.onResult() method of the passed parameter.\nSo we have two issues that will need to be solved here:\nHow to pass the callback object through the native interface.\nHow to call the callback.onResult() method from native code at the right time.\nFor the first issue, we’ll use strategy #2 that we mentioned previously: (Store the parameter on the Codename One side and pass some ID or token that can be used on the native side to retrieve the value).\nFor the second issue, we’ll create a static method that can take the token generated to solve the first issue, and call the stored callback object’s onResult() method. We abstract both sides of this process using the MobihelpNativeCallback class.\npublic class MobihelpNativeCallback { private static int nextId = 0; private static Map\u0026lt;Integer,UnreadUpdatesCallback\u0026gt; callbacks = new HashMap\u0026lt;Integer,UnreadUpdatesCallback\u0026gt;(); static int registerUnreadUpdatesCallback(UnreadUpdatesCallback callback) { callbacks.put(nextId, callback); return nextId++; } public static void fireUnreadUpdatesCallback(int callbackId, final int status, final int count) { final UnreadUpdatesCallback cb = callbacks.get(callbackId); if (cb != null) { callbacks.remove(callbackId); Display.getInstance().callSerially(new Runnable() { public void run() { MobihelpCallbackStatus status2 = MobihelpCallbackStatus.values()[status]; cb.onResult(status2, count); } }); } } } Things to notice here:\nThis class uses a static Map\u0026lt;Integer,UnreadUpdatesCallback\u0026gt; member to keep track of all callbacks, mapping a unique integer ID to each callback.\nThe registerUnreadUpdatesCallback() method takes an UnreadUpdatesCallback object, places it in the callbacks map, and returns the integer token that can be used to fire the callback later. This method would be called by the public API inside the getUnreadCountAsync() method implementation to convert the callback into an integer, which can then be passed to the native API.\nThe fireUnreadUpdatesCallback() method would be called later from native code. Its first parameter is the token for the callback to call.\nWe wrap the onResult() call inside a Display.callSerially() invocation to ensure that the callback is called on the EDT. This is a general convention that is used throughout Codename One, and you’d be well-advised to follow it. Event handlers should be run on the EDT unless there is a good reason not to – and in that case your documentation and naming conventions should make this clear to avoid accidentally stepping into multithreading hell!\nInitialization Most Native SDKs include some sort of initialization method where you pass your developer and application credentials to the API. When I filled in FreshDesk’s web-based form to create a new application, it generated an application ID, an app \u0026ldquo;secret\u0026rdquo;, and a \u0026ldquo;domain\u0026rdquo;. The SDK requires me to pass all three of these values to its init() method via the MobihelpConfig class.\nNote, however, that FreshDesk (and most other service provides that have native SDKs) requires me to create different Apps for each platform. This means that my App ID and App secret will be different on iOS than they will be on Android.\nTherefore our public API needs to enable us to provide multiple credentials in the same app, and our API needs to know to use the correct credentials depending on the device that the app is running on.\nThere are many solutions to this problem, but the one I chose was to provide two different init() methods:\npublic final static void initIOS(MobihelpConfig config) and\npublic final static void initAndroid(MobihelpConfig config) Then I can set up the API with code like:\nMobihelpConfig config = new MobihelpConfig(); config.setAppSecret(\u0026quot;xxxxxxx\u0026quot;); config.setAppId(\u0026quot;freshdeskdemo-2-xxxxxx\u0026quot;); config.setDomain(\u0026quot;codenameonetest1.freshdesk.com\u0026quot;); Mobihelp.initIOS(config); config = new MobihelpConfig(); config.setAppSecret(\u0026quot;yyyyyyyy\u0026quot;); config.setAppId(\u0026quot;freshdeskdemo-1-yyyyyyyy\u0026quot;); config.setDomain(\u0026quot;https://codenameonetest1.freshdesk.com\u0026quot;); Mobihelp.initAndroid(config); The Resulting Public API public class Mobihelp { private static char[] separators = new char[]{',','|','/','@','#','%','!','^','\u0026amp;','*','=','+','*','\u0026lt;'}; private static MobihelpNative peer; public static boolean isSupported() { .... } public static void setPeer(MobihelpNative peer) { .... } //Attach the given custom data (key-value pair) to the conversations/tickets. public final static void\taddCustomData(String key, String value) { ... } //Attach the given custom data (key-value pair) to the conversations/tickets with the ability to flag sensitive data. public final static void\taddCustomData(String key, String value, boolean isSensitive) { ... } //Clear all breadcrumb data. public final static void\tclearBreadCrumbs() { ... } //Clear all custom data. public final static void\tclearCustomData() { ... } //Clears User information. public final static void\tclearUserData() { ... } //Retrieve the number of unread items across all the conversations for the user synchronously i.e. public final static int\tgetUnreadCount() { ... } //Retrieve the number of unread items across all the conversations for the user asynchronously, count is delivered to the supplied UnreadUpdatesCallback instance Note : This may return 0 or stale value when there is no network connectivity etc public final static void\tgetUnreadCountAsync(UnreadUpdatesCallback callback) { ... } //Initialize the Mobihelp support section with necessary app configuration. public final static void\tinitAndroid(MobihelpConfig config) { ... } public final static void initIOS(MobihelpConfig config) { ... } //Attaches the given text as a breadcrumb to the conversations/tickets. public final static void\tleaveBreadCrumb(String crumbText) { ... } //Set the email of the user to be reported on the Freshdesk Portal public final static void\tsetUserEmail(String email) { ... } //Set the name of the user to be reported on the Freshdesk Portal. public final static void\tsetUserFullName(String name) { ... } //Display the App Rating dialog with option to Rate, Leave feedback etc public static void\tshowAppRateDialog() { ... } //Directly launch Conversation list screen from anywhere within the application public final static void\tshowConversations() { ... } //Directly launch Feedback Screen from anywhere within the application. public final static void\tshowFeedback(FeedbackRequest feedbackRequest) { ... } //Directly launch Feedback Screen from anywhere within the application. public final static void\tshowFeedback() { ... } //Displays the Support landing page (Solution Article List Activity) where only solutions tagged with the given tags are displayed. public final static void\tshowSolutions(ArrayList\u0026lt;String\u0026gt; tags) { ... } private static String findUnusedSeparator(ArrayList\u0026lt;String\u0026gt; tags) { ... } //Displays the Support landing page (Solution Article List Activity) from where users can do the following //View solutions, //Search solutions, public final static void\tshowSolutions() { ... } //Displays the Integrated Support landing page where only solutions tagged with the given tags are displayed. public final static void\tshowSupport(ArrayList\u0026lt;String\u0026gt; tags) { ... } //Displays the Integrated Support landing page (Solution Article List Activity) from where users can do the following //View solutions, //Search solutions, // Start a new conversation, //View existing conversations update/ unread count etc public final static void\tshowSupport() { ... } } The Native Interface The final native interface is nearly identical to our public API, except in cases where the public API included non-primitive parameters.\npublic interface MobihelpNative extends NativeInterface { /** * @return the appId */ public String config_getAppId(); /** * @param appId the appId to set */ public void config_setAppId(String appId); /** * @return the appSecret */ public String config_getAppSecret(); /** * @param appSecret the appSecret to set */ public void config_setAppSecret(String appSecret); /** * @return the domain */ public String config_getDomain(); /** * @param domain the domain to set */ public void config_setDomain(String domain) ; /** * @return the feedbackType */ public int config_getFeedbackType() ; /** * @param feedbackType the feedbackType to set */ public void config_setFeedbackType(int feedbackType); /** * @return the launchCountForReviewPrompt */ public int config_getLaunchCountForReviewPrompt() ; /** * @param launchCountForReviewPrompt the launchCountForReviewPrompt to set */ public void config_setLaunchCountForReviewPrompt(int launchCountForReviewPrompt); /** * @return the prefetchSolutions */ public boolean config_isPrefetchSolutions(); /** * @param prefetchSolutions the prefetchOptions to set */ public void config_setPrefetchSolutions(boolean prefetchSolutions); /** * @return the autoReplyEnabled */ public boolean config_isAutoReplyEnabled(); /** * @param autoReplyEnabled the autoReplyEnabled to set */ public void config_setAutoReplyEnabled(boolean autoReplyEnabled) ; /** * @return the enhancedPrivacyModeEnabled */ public boolean config_isEnhancedPrivacyModeEnabled() ; /** * @param enhancedPrivacyModeEnabled the enhancedPrivacyModeEnabled to set */ public void config_setEnhancedPrivacyModeEnabled(boolean enhancedPrivacyModeEnabled) ; //Attach the given custom data (key-value pair) to the conversations/tickets. public void\taddCustomData(String key, String value); //Attach the given custom data (key-value pair) to the conversations/tickets with the ability to flag sensitive data. public void addCustomDataWithSensitivity(String key, String value, boolean isSensitive); //Clear all breadcrumb data. public void\tclearBreadCrumbs() ; //Clear all custom data. public void\tclearCustomData(); //Clears User information. public void\tclearUserData(); //Retrieve the number of unread items across all the conversations for the user synchronously i.e. public int getUnreadCount(); //Retrieve the number of unread items across all the conversations for the user asynchronously, count is delivered to the supplied UnreadUpdatesCallback instance Note : This may return 0 or stale value when there is no network connectivity etc public void\tgetUnreadCountAsync(int callbackId); public void initNative(); //Attaches the given text as a breadcrumb to the conversations/tickets. public void leaveBreadCrumb(String crumbText); //Set the email of the user to be reported on the Freshdesk Portal public void setUserEmail(String email); //Set the name of the user to be reported on the Freshdesk Portal. public void setUserFullName(String name); //Display the App Rating dialog with option to Rate, Leave feedback etc public void\tshowAppRateDialog(); //Directly launch Conversation list screen from anywhere within the application public void showConversations(); //Directly launch Feedback Screen from anywhere within the application. public void\tshowFeedbackWithArgs(String subject, String description); //Directly launch Feedback Screen from anywhere within the application. public void\tshowFeedback(); //Displays the Support landing page (Solution Article List Activity) where only solutions tagged with the given tags are displayed. public void\tshowSolutionsWithTags(String tags, String separator); //Displays the Support landing page (Solution Article List Activity) from where users can do the following //View solutions, //Search solutions, public void\tshowSolutions(); //Displays the Integrated Support landing page where only solutions tagged with the given tags are displayed. public void\tshowSupportWithTags(String tags, String separator); //Displays the Integrated Support landing page (Solution Article List Activity) from where users can do the following //View solutions, //Search solutions, // Start a new conversation, //View existing conversations update/ unread count etc public void\tshowSupport(); } Notice also, that the native interface includes a set of methods with names prefixed with config__. This is just a naming conventions I used to identify methods that map to the MobihelpConfig class. I could have used a separate native interface for these, but decided to keep all the native stuff in one class for simplicity and maintainability.\nConnecting the Public API to the Native Interface So we have a public API, and we have a native interface. The idea is that the public API should be a thin wrapper around the native interface to smooth out rough edges that are likely to exist due to the strict set of rules involved in native interfaces. We’ll, therefore, use delegation inside the Mobihelp class to provide it a reference to an instance of MobihelpNative:\npublic class Mobihelp { private static MobihelpNative peer; We’ll initialize this peer inside the init() method of the Mobihelp class. Notice, though that init() is private since we have provided abstractions for the Android and iOS apps separately:\n//Initialize the Mobihelp support section with necessary app configuration. public final static void initAndroid(MobihelpConfig config) { if (\u0026quot;and\u0026quot;.equals(Display.getInstance().getPlatformName())) { init(config); } } public final static void initIOS(MobihelpConfig config) { if (\u0026quot;ios\u0026quot;.equals(Display.getInstance().getPlatformName())) { init(config); } } private static void init(MobihelpConfig config) { peer = (MobihelpNative)NativeLookup.create(MobihelpNative.class); peer.config_setAppId(config.getAppId()); peer.config_setAppSecret(config.getAppSecret()); peer.config_setAutoReplyEnabled(config.isAutoReplyEnabled()); peer.config_setDomain(config.getDomain()); peer.config_setEnhancedPrivacyModeEnabled(config.isEnhancedPrivacyModeEnabled()); if (config.getFeedbackType() != null) { peer.config_setFeedbackType(config.getFeedbackType().ordinal()); } peer.config_setLaunchCountForReviewPrompt(config.getLaunchCountForReviewPrompt()); peer.config_setPrefetchSolutions(config.isPrefetchSolutions()); peer.initNative(); } Things to Notice :\nThe initAndroid() and initIOS() methods include a check to see if they are running on the correct platform. Ultimately they both call init().\nThe init() method, uses the NativeLookup class to instantiate our native interface.\nImplementing the Glue Between Public API and Native Interface For most of the methods in the Mobihelp class, we can see that the public API will just be a thin wrapper around the native interface. E.g. the public API implementation of setUserFullName(String) is:\npublic final static void setUserFullName(String name) { peer.setUserFullName(name); } For some other methods, the public API needs to break apart the parameters into a form that the native interface can accept. E.g. the init() method, shown above, takes a MobihelpConfig object as a parameter, but it passed the properties of the config object individually into the native interface.\nAnother example, is the showSupport(ArrayList\u0026lt;String\u0026gt; tags) method. The corresponding native interface method that is wraps is showSupport(String tags, String separator) – i.e it needs to merge all tags into a single delimited string, and pass then to the native interface along with the delimiter used. The implementation is:\npublic final static void showSupport(ArrayList\u0026lt;String\u0026gt; tags) { String separator = findUnusedSeparator(tags); StringBuilder sb = new StringBuilder(); for (String tag : tags) { sb.append(tag).append(separator); } peer.showSupportWithTags(sb.toString().substring(0, sb.length()-separator.length()), separator); } The only other non-trivial wrapper is the getUnreadCountAsync() method that we discussed before:\npublic final static void getUnreadCountAsync(UnreadUpdatesCallback callback) { int callbackId = MobihelpNativeCallback.registerUnreadUpdatesCallback(callback); peer.getUnreadCountAsync(callbackId); } In the Next Instalment …​ In part 2 of this series I’ll cover the native Android implementation, and part 3 will cover the native iOS implementation. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nSteve Nganga — September 29, 2015 at 4:43 pm (permalink) just what i have been waiting for\nMoacir Schmidt — October 18, 2015 at 3:37 pm (permalink) Excellent!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/integrating-3rd-party-native-sdks-part-1/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/integrating-3rd-party-native-sdks-part-1/native-sdks-header.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis past Thursday, we held our fourth webinar, and the topic was how to incorporate 3rd party native libraries into a Codename One app. I used the recently released \u003ca href=\"http://shannah.github.io/cn1-freshdesk/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eFreshDesk cn1lib\u003c/a\u003e as a case study for this webinar. As the topic is a little involved, I decided to break it up into two webinars. In \u003ca href=\"https://codenameone.adobeconnect.com/p8tau90yr1d/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003epart one\u003c/a\u003e, we focused on the public API and architecture involved in developing a wrapper for a native SDK, and walked through the native implementation for Android.\u003c/p\u003e","title":"Integrating 3rd Party Native SDKs Part I"},{"content":"\nThe excellent Parse4cn1 library just announced version 1.1. The biggest new feature is batch operations but there are\na few others that could be helpful. Overall the library was pretty solid before the 1.1 version and this is a nice\nimprovement on top.\nFabricio Cabeca contributed an interesting\npull request\nthat has the potential to improve performance nicely on most platforms. Hopefully we’ll fix the issues in this\napproach and get it up again.\nSteve reimplemented our BigDecimal \u0026amp; BigInteger based on the TeaVM\nimplementation to make it more compliant to the Java SE version of these classes.\nExpanding A Tree A common request for the tree class is to open it when its already expanded. I recently had to do that myself for\nthe GUI builder and noticed that one of the pain points is the fact that the Tree always animates\nexpansion. So we added a new method that allows path expansion without animation specifically: expandPath(animated, path).\nThis tree class shows itself expanded by default and can be useful for your app:\npublic class MyTree extends Tree { public MyTree(TreeModel model) { super(model); } @Override protected void initComponent() { expand(); super.initComponent(); } public void expand() { Object current = null; Vector c = getModel().getChildren(current); if(c != null) { for(Object o : c) { recurseExpand(o); } } } private void recurseExpand(Object... path) { expandPath(false, path); if(getModel().isLeaf(path[path.length - 1])) { return; } Vector ch = getModel().getChildren(path[path.length - 1]); if(ch != null) { Object[] arr = new Object[path.length + 1]; for(int iter = 0 ; iter \u0026lt; path.length ; iter++) { arr[iter] = path[iter]; } for(Object o : ch) { arr[path.length] = o; recurseExpand(arr); } } } } Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/updated-parse-lib-tiling-performance-decimals-trees/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/updated-parse-lib-tiling-performance-decimals-trees/parse.com-post-header.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe excellent \u003ca href=\"https://github.com/sidiabale/parse4cn1/releases/tag/parse4cn1-1.1\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nParse4cn1 library just announced version 1.1.\u003c/a\u003e The biggest new feature is batch operations but there are\u003cbr\u003e\na few others that could be helpful. Overall the library was pretty solid before the 1.1 version and this is a nice\u003cbr\u003e\nimprovement on top.\u003c/p\u003e\n\u003cp\u003eFabricio Cabeca contributed an interesting\u003cbr\u003e\n\u003ca href=\"https://github.com/codenameone/CodenameOne/pull/1580\" target=\"_blank\" rel=\"noopener noreferrer\"\u003epull request\u003c/a\u003e\u003cbr\u003e\nthat has the potential to improve performance nicely on most platforms. Hopefully we’ll fix the issues in this\u003cbr\u003e\napproach and get it up again.\u003c/p\u003e","title":"Updated Parse Lib, Tiling Performance, Decimals \u0026 Trees"},{"content":"\nOur GUI builder is the result of many twists and turns in our product line mostly due to corporate bureaucracy\nhacks and last minute deadlines from our days at Sun. Its also written using Swing which is pretty much a dead\nend API that isn’t seeing any maintenence and since FX is even worse off there isn’t much hope for the\ntools future.\nThe GUI builder is also one of the most controversial parts of our UI. While it has its strengths and simplicities its\nUI could do with a facelift and its architecture was designed before tablets existed. It was designed when\nApple just barely surpassed Blackberry sales and had just announced the iPhone 4 (first with Retina display).\nWith that in mind we decided to rethink the GUI builder from the ground up with a complete from scratch\nrewrite. This allows us to keep the existing GUI builder for 100% compatibility for the forseeable future\nand add a decent migration path to developers who want to move to the new approach.\nWe did learn from the bad experience with FX where there is still no decent migration path for Swing apps to\nthis day so we intend to make the long term migration as easy as possible and intend to support the existing\ntool for a very long time!\nThe obvious question is how will the new GUI builder differ from our current GUI builder?\nBuilt Using Codename One With the new certificate wizard you saw the beginning of a trend that we hope to accelerate. Writing our\ntool using Codename One itself. This has numerous advantages to us but is also probably the best tool out\nthere with Swing/FX being effectively dead, SWT somewhat stagnated there is really no decent Java UI\nlibrary for us to use other than Codename One.\nWhen you add the JavaScript port of Codename One into the mix (not to mention the ability to run on devices)\nthe value proposition is even bigger!\nThe Resource File Format The resource file format is a binary format we originally invented for themes, images etc. This made features\nlike the GUI builder powerful yet somewhat awkward.\nAs we moved forward we added an auxiliary XML format that supports themes and allows teams to work\nmore effectively on the resource file. As part of that we added GUI builder XML file format support, this\nis the format that we will use for the GUI builder which will make the migration process very easy.\nThe Statemachine The original GUI builder was designed for simpler mobile apps that had far simpler UI. Most of the UI builders\nwork was navigating between forms and adding commands. The state machine was a common practice that\nmade a lot of sense for that point in time.\nToday we support, tablets, desktops and even web. With that in mind we decided to switch to a more traditional\napproach similar to standard desktop GUI builders where every Form/Container or Dialog in the GUI builder is\nrepresented by a single class and an XML file used to maintain the GUI builder state (see above).\nHowever, we intend to add a statemachine compatibility layer in the future to allow easier migration from the existing\nGUI builder to the new GUI builder with as little work as possible (although we can’t promise 100% seamlessness).\nCode Generation The new GUI builder will generate code directly into a class representing the UI. So if you have a form called\n\u0026ldquo;MyForm\u0026rdquo; then you will have a Java source file named \u0026ldquo;MyForm.java\u0026rdquo; under the \u0026ldquo;src\u0026rdquo; hierarchy and an XML file\ncalled \u0026ldquo;res/guibuilder/mypackage/MyForm.gui\u0026rdquo; under the \u0026ldquo;res\u0026rdquo; hierarchy. This \u0026ldquo;.gui\u0026rdquo; file will be used to store/load\nthe actual state from the GUI builder. The GUI builder ignores the source file almost completely except for the\nspecial case of event handling.\nThe code generation will happen thru a new ant task that we already introduced in the build XML. It runs during\nbuild and scans the res directory for \u0026ldquo;.gui\u0026rdquo; files which it then converts to Java source blocks. The \u0026ldquo;MyForm.java\u0026rdquo;\nwill have a special commented section that you aren’t allowed to touch, this is very similar to the NetBeans GUI\nbuilder architecture but we probably won’t physically lock these code blocks like NetBeans does.\nReleases \u0026amp; Limitations We’d like to have a technology preview out for 3.2 but will probably release something sooner than that maybe\nwithin the next month (which marks the 5 year anniversary of the launch of the previous GUI builder).\nWe don’t recommend the technology preview for production apps since the new tool might generate invalid\ncode and require that you manually edit the XML files to workaround issues. With the 3.3 release\nwe hope to graduate into beta level where we will start emphasizing this tool as \u0026ldquo;the gui builder\u0026rdquo;\nfor new projects.\nThe initial release won’t include standardized migration tools although we’ll try to add them as soon as possible\nas this is the best possible way for us to test the tool (by converting existing apps).\nThe following big ticket features from the designer won’t be available with the initial release:\nList renderers – currently the designer uses a separate container as a renderer. Since the new GUI builder\nworks in isolation this would be more tricky for us to expose. Commands \u0026amp; Navigation – similarly to renderers this requires something more than a simplistic view of a single form. Back Navigation, Embedded Container – These features won’t be available in the standard GUI builder since they\nrely on the statemachine architecture. We will add back navigation to the compatibility layer we plan to add and\nwill try to include embedded container there too Toolbar – the old GUI builder was very flexible in terms of command behavior which effectively made it\nvery limited since it assumed nothing about command behavior. This turned out to be very in-flexible and prevented\nbasic usability features such as \u0026ldquo;placing a button on the title\u0026rdquo;. The new designer assumes that the\nToolbar class is used and will allow greater control over command placement to facilitate that. Style manipulation/Localization – the existing GUI builder allowed customizing styles directly from the GUI builder UI. Since\nwe are now separating the tools styles \u0026amp; localization won’t be available. You’d still be able to make use of both\nbut not directly from the GUI builder UI. Feedback We are looking for feedback on the tooling and direction, we want to make the transition as seamless and painless\nas possible as we move forward. With that in mind I hope that once we launch this tool you’d give it a try\nand let us know what you think. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJaanus Hansen — September 21, 2015 at 3:00 pm (permalink) Jaanus Hansen says:\nThis is good news, that the long StateMachine will be split in the future 🙂\nbryan — September 21, 2015 at 8:39 pm (permalink) bryan says:\nSounds interesting. I wonder what you know about FX that the rest of us don’t – I can’t see Oracle trash canning it as I’m sure they have lots of desktop code they need some UI platform for.\nShai Almog — September 22, 2015 at 3:54 am (permalink) Shai Almog says:\nThe top guys running FX are no longer on the core platform but were re-assigned. For a while focus shifted to embedded/IoT but the guy who was running this (one of the smartest developers/people I know) got fired with his entire staff because of corporate bureaucracy… Corporate bureaucracy is disabled when dealing with a truly important platform. We tried to get him to come on-board but he decided to go to Google.\nNo one uses FX despite years of no alternative. The only \u0026ldquo;real app\u0026rdquo; usage is in Swing apps that need what is now basic features such as a decent web browser etc. I’ve talked with several top Java consultants and asked them about their FX work, they all concur that this observation is accurate. The few \u0026ldquo;pure FX\u0026rdquo; projects are small student works etc.\nThe world moved in a different direction, FX has many similarities to Flash. In some regards its better but in others its worse. Adobe with all its abilities was unable to get Flash into devices (it even sucked on Android) and on modern desktops its hated. Java currently doesn’t have a \u0026ldquo;working by default\u0026rdquo; deployment strategy. Webstart and Applet’s were riddled with bugs and security holes, javafxwrapper is immature and has basic functionality missing.\nI agree that Java needs a desktop solution but FX is still far off from that point and needs a lot of effort to get there. Currently Oracle products use web for most of their UI’s and server side Java. E.g. the architecture of MAF which has the architecture diagram that is the very definition of over engineering.\nUnlike Google that does Spring cleaning, Oracle/Sun never really kill off projects. They just sort of abandon them and don’t invest time in them but everyone knows they are dead. Sun effectively abandoned Swing because it \u0026ldquo;only\u0026rdquo; had 30% market share, FX is probably under 1%.\nI was joking with the NetBeans guys a while back saying that they should rewrite NetBeans in Codename One, I don’t think that’s a joke anymore…\nbryan — September 22, 2015 at 6:51 am (permalink) bryan says:\nI hope FX doesn’t disappear anytime soon as I’ve just spent the last 18 months on an FX app.\nWith your new stuff, will you be supporting it on the desktop on all of Windows, Max and Linux ?\nShai Almog — September 23, 2015 at 5:09 am (permalink) Shai Almog says:\nFX is already \u0026ldquo;gone\u0026rdquo;, but it won’t disappear just like Swing didn’t disappear. The problem with FX will be similar to the problems with Swing, huge gaping bugs that go unfixed for quite a while e.g. file dialog not working on Windows 7 for ages was plaguing us on Swing… Getting DPI to work correctly on Macs with Retina display is a HUGE issue still, we can do basic things like adapt images but other than that…\nWe support all OS’s with the new GUI builder as we always did.\nbryan — September 23, 2015 at 5:21 am (permalink) bryan says:\nThis is getting a bit off topic as regards actually using CN1, but I’m curious how you’re going to support all the platforms. I don’t imagine you’re going to have your own low level (Glib for example on Linux) graphics implementation – I assume you’re still going to use Swing or FX but have your own widget drawing primitives – essentially what CN1 does on Android etc now ?\nShai Almog — September 23, 2015 at 11:09 am (permalink) Shai Almog says:\nWe already have a desktop port which uses that architecture and a JavaScript port which is more complex: http://www.codenameone.com/…\nOne of our thoughts for the long term is to actually port directly to native since we already have native OpenGL code in the iOS port. Right now the benefit of doing that is very low. The core benefit is being a bit closer to the way things are on the device and being able to build a truly native app for desktop (e.g. 1mb desktop app instead of bundling the whole VM).\nChidiebere Okwudire — October 12, 2015 at 10:13 am (permalink) Chidiebere Okwudire says:\nNice to hear. Looking forward to it! I hope though that:\n1. The new GUI builder will make it easier to combine handcoded forms with GUI builder forms.\n2. It will be better documented (if for nothing else, to reduce the number of times you get asked the same questions on the forum about back navigation, skipping a form in the navigation stack, etc. :D). For even simple customizations to default behavior, I find myself having to dive into the source code either because the documentation is unclear or not quite available.\n3. Last but certainly not least, we’ll see more GUI builder-based demos because it’s hard to sell something that you guys yourselves don’t seem to be using that much 🙂\nCheers\nShai Almog — October 12, 2015 at 12:08 pm (permalink) Shai Almog says:\n1. Its designed to be a more traditional GUI builder so it should be pretty easy to mix GUI/handcoded styles. It would also be possible to use it in a library.\nYou would use it with a Manual type application and not with a GUI builder application.\n2/3. Our existing GUI builder quite a bit of documentation and tutorials, most older demos/tutorials were based on it e.g. http://udemy.com/build-mobi…\nSome things like the back behavior are really hard to teach/document since people don’t really know where to begin. Unlike coding where you have the javadoc and developer guide when you are in a GUI builder environment the terminology isn’t there as much… Since the new GUI builder won’t focus on navigation as much this sort of behavior won’t be as common.\nWe stopped using the GUI builder for newer demos because it made it harder for some developers to follow the process (as the result was binary and not source). We planned this rewrite for years so we intended to focus on the new GUI builder when it lands.\nChidiebere Okwudire — December 9, 2015 at 11:26 am (permalink) Chidiebere Okwudire says:\nHi,\nI’m curious about the status of the new GUI builder? Any ideas when the first stable version is due? Early next year I want to port an application to CN1 and the concepts in the new GUI builder are more suited for my use case. Of course, I know I can code the forms manually but let’s say, I’m more visually-oriented and/or lazy 🙂\nShai Almog — December 9, 2015 at 12:01 pm (permalink) Shai Almog says:\nHi,\nwe are aiming for beta quality with 3.3 which is due for January 27th if I remember correctly. Production grade probably won’t appear before 3.4.\nRight now the biggest problem is the lack of issues which partially relates to lack of tutorials (still pointing at the old GUI builder). We are reluctant to redo the tutorials pointing at a shifting/changing tool so this isn’t ideal.\nThe nice thing about the new GUI builder is that even if it completely breaks down you can still use the XML to recover so a disaster is less likely.\nChidiebere Okwudire — December 9, 2015 at 8:49 pm (permalink) Chidiebere Okwudire says:\nOk; thanks for the update. When I start the migration, I hope I can provide some useful feedback.\nAkinniranye James — September 10, 2016 at 5:52 pm (permalink) Akinniranye James says:\nThe builder is having issues with tabs. Anybody tried creating tabs?\nShai Almog — September 11, 2016 at 6:38 am (permalink) Shai Almog says:\nYes, it partially works.\nWe fixed several issues in tabs that will be included in the coming update.\nAkinniranye James — September 11, 2016 at 7:06 am (permalink) Akinniranye James says:\nDo you have any date in mind?\nShai Almog — September 12, 2016 at 4:16 am (permalink) Shai Almog says:\nWe hope to have it in this Friday release.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-gui-builder/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-gui-builder/new-gui-builder-preview.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOur GUI builder is the result of many twists and turns in our product line mostly due to corporate bureaucracy\u003cbr\u003e\nhacks and last minute deadlines from our days at Sun. Its also written using Swing which is pretty much a dead\u003cbr\u003e\nend API that isn’t seeing any maintenence and since FX is even worse off there isn’t much hope for the\u003cbr\u003e\ntools future.\u003cbr\u003e\nThe GUI builder is also one of the most controversial parts of our UI. While it has its strengths and simplicities its\u003cbr\u003e\nUI could do with a facelift and its architecture was designed before tablets existed. It was designed when\u003cbr\u003e\nApple just barely surpassed Blackberry sales and had just announced the iPhone 4 (first with Retina display).\u003c/p\u003e","title":"New GUI Builder"},{"content":"\nThis will be the last installment of this tutorial which was pretty complete in the previous section already. We might\nhave additional installments mostly for covering enhancements such as \u0026ldquo;invite a friend\u0026rdquo; and other similar capabilites\nbut this is probably as good a place as any to finish the app and let you try it live.\nNative Push Up until now we used PubNub to implement the push functionality which is excellent especially if you opt for the\npaid option which can also persist messages and offers quite a few additional perks for an app such as this.\nHowever, when the app isn’t running PubNub can’t push anything and in that case we need an OS native push to\nsend the message.\nThe obvious question would be \u0026ldquo;why not use OS native push for everything?\u0026rdquo;.\nIts possible to do so but OS native push isn’t as flexible, portable, fast or reliable as PubNub. Its painful to work with\nand the user can intentionally or inadvertently break it by disagreeing to an OS prompt etc…​ As you will see from the\nrest of the tutorial where we fallback to native OS push when PubNub can’t reach our target, its no panacea.\nThe PushCallback Interface We start by implementing the PushCallback interface in our main class, this must be the actual main class or\npush won’t work:\npublic class SocialChat implements PushCallback { Then we need to implement the following methods:\n@Override public void push(String value) { // its a JSON message, otherwise its a notice to the user if(value.startsWith(\u0026quot;{\u0026quot;) || value.startsWith(\u0026quot;[\u0026quot;)) { try { JSONObject obj = new JSONObject(value); // this is still early since we probably didn't login yet so add the messages to the list of pending messages java.util.List\u0026lt;Message\u0026gt; pendingMessages = (java.util.List\u0026lt;Message\u0026gt;)Storage.getInstance().readObject(\u0026quot;pendingMessages\u0026quot;); if(pendingMessages == null) { pendingMessages = new ArrayList\u0026lt;\u0026gt;(); } Message m = new Message(obj); pendingMessages.add(m); Storage.getInstance().writeObject(\u0026quot;pendingMessages\u0026quot;, pendingMessages); addMessage(m); } catch(JSONException err) { err.printStackTrace(); } } } @Override public void registeredForPush(String deviceId) { } @Override public void pushRegistrationError(String error, int errorCode) { } You will notice the following things here:\nWe don’t really need anything in the registeredForPush or pushRegistrationError. Since we use PubNub even\nif push fails the app will still work fine. registeredForPush is normally used to get the push key (which isn’t the argument\npassed to that method its the Push.getPushKey()) and send it to your servers so you can trigger a push to this device.\nSince here we don’t have a real server we have no use for that method.\nThe push method does the heavy lifting of handling push messages. It can be called anytime and accepts\nthe push callbacks. It receives both visible and hidden push messages and decides what to do with them based\non their content.\nWe don’t show the message during the push callback. It will be invoked before the user had time to login and\nso we want to just store the Message objects and have them processed later. We still add them to the general\nstore in case the user decides to kill the app before actually logging in\nNew Constants \u0026amp; Registration We need to add the following variables to the class to continue, I masked and changed the values. We’ll go over\nthem one by one:\nprivate static final String PUSH_TOKEN = \u0026quot;********-****-****-****-*************\u0026quot;; private static final String GCM_SENDER_ID = \u0026quot;99999999999999\u0026quot;; private static final String GCM_SERVER_API_KEY = \u0026quot;******************-********************\u0026quot;; private static final boolean ITUNES_PRODUCTION_PUSH = false; private static final String ITUNES_PRODUCTION_PUSH_CERT = \u0026quot;https://domain.com/linkToP12Prod.p12\u0026quot;; private static final String ITUNES_PRODUCTION_PUSH_CERT_PASSWORD = \u0026quot;ProdPassword\u0026quot;; private static final String ITUNES_DEVELOPMENT_PUSH_CERT = \u0026quot;https://domain.com/linkToP12Dev.p12\u0026quot;; private static final String ITUNES_DEVELOPMENT_PUSH_CERT_PASSWORD = \u0026quot;DevPassword\u0026quot;; PUSH_TOKEN is the easiest, just login to Codename One and select the account tab. It should appear just\nabove the Update Details button. If it isn’t there try logging out and logging back in.\nYou can get the GCM_SENDER_ID \u0026amp; GCM_SERVER_API_KEY from Google very easily. This assumes you\nfollowed our instructions to create a Google project in part 2 of the tutorial. If you skipped that (because you\ndidn’t need a G+ account login) just make sure to create a new project in the Google API console based on the\ninstructions in part 2.\nTo generate those just go to https://developers.google.com/mobile/add and click \u0026ldquo;pick a platform\u0026rdquo;:\nSelect \u0026ldquo;Android App\u0026rdquo;\nEnter the details for the app and the package\nClick the \u0026ldquo;Cloud Messaging\u0026rdquo; option then click the \u0026ldquo;Enable Google Cloud Messaging\u0026rdquo; button\nYou should now have the values for both GCM_SENDER_ID \u0026amp; GCM_SERVER_API_KEY as illustrated below\nThanks to our new certificate wizard generating the iOS portion of these flags is now a complete breeze!\nWe just go thru the certificate wizard and check the flag to enable push:\nOnce you finish that wizard and check the enable push flag make sure that the iOS section also has the \u0026ldquo;Include Push\u0026rdquo;\nflag checked. There is a bug in the current plugin where it isn’t enabled automatically.\nYou should receive instructions to include push by email which should include links that you can just paste into place\nand passwords. This should be pretty seamless.\nOther Code Changes When you push to a device you need to have the device key which is a unique identifier of the device to which you\nwant to send a push. Unfortunately since we don’t have a server in place we need somehow pass this key from the\nperson we are chatting with. The trick is to embed this key into the Message object and thus update it when we receive\na message, this means that we can only send a push message to a person who wrote to us in the past. Not a bad\nfeature all and all but still a limitation…​\nTo do that we need to do these two simple changes to the Message class:\npublic Message(JSONObject obj) { try { time = Long.parseLong(obj.getString(\u0026quot;time\u0026quot;)); senderId = obj.getString(\u0026quot;fromId\u0026quot;); recepientId = obj.getString(\u0026quot;toId\u0026quot;); message = obj.getString(\u0026quot;message\u0026quot;); name = obj.getString(\u0026quot;name\u0026quot;); picture = obj.getString(\u0026quot;pic\u0026quot;); // update the push id for the given user if(obj.has(\u0026quot;pushId\u0026quot;)) { String pushId = obj.getString(\u0026quot;pushId\u0026quot;); if(pushId != null) { Preferences.set(\u0026quot;pid-\u0026quot; + senderId, pushId); } } } catch (JSONException ex) { // will this ever happen? Log.e(ex); } } public JSONObject toJSON() { String pushId = Push.getPushKey(); if(pushId != null) { JSONObject obj = createJSONObject(\u0026quot;fromId\u0026quot;, senderId, \u0026quot;toId\u0026quot;, recepientId, \u0026quot;name\u0026quot;, name, \u0026quot;pic\u0026quot;, picture, \u0026quot;time\u0026quot;, Long.toString(System.currentTimeMillis()), \u0026quot;message\u0026quot;, message, \u0026quot;pushId\u0026quot;, pushId); return obj; } JSONObject obj = createJSONObject(\u0026quot;fromId\u0026quot;, senderId, \u0026quot;toId\u0026quot;, recepientId, \u0026quot;name\u0026quot;, name, \u0026quot;pic\u0026quot;, picture, \u0026quot;time\u0026quot;, Long.toString(System.currentTimeMillis()), \u0026quot;message\u0026quot;, message); return obj; } This effectively adds a push ID to every message we send if its available and updates a contacts push ID for usage\nlater.\nNow we need to register for push, in the end of the start() method in SocialChat.java we add:\n// let the login form show before we register the push so the permission screen doesn't appear on a white // background Display.getInstance().callSerially(() -\u0026gt; { // registering for push after the UI appears Hashtable args = new Hashtable(); args.put(com.codename1.push.Push.GOOGLE_PUSH_KEY, GCM_SENDER_ID); Display.getInstance().registerPush(args, true); }); We do it this way to let the UI appear first.\nPreviously in the showChatForm method we just sent a message thru PubNub, now we want there to be a fallback\nthat will send the message via push. To do that we need to know that the message wasn’t received by the other\nside. To discover that we now add a back message in PubNub called \u0026ldquo;ACK\u0026rdquo; which will acknowledge the receipt\nof a message, if an ACK isn’t received that means the message should be sent thru native push…​ To do that we add\nthe class field:\n/** * Includes messages that received ACK notices from the receiver */ private ArrayList\u0026lt;String\u0026gt; pendingAck = new ArrayList\u0026lt;\u0026gt;(); We remove ACK’s automatically in the listenToMessages method as such:\nprivate void listenToMessages() { try { pb = new Pubnub(\u0026quot;pub------------------------------\u0026quot;, \u0026quot;sub-------------------------------\u0026quot;); pb.subscribe(tokenPrefix + uniqueId, new Callback() { @Override public void successCallback(String channel, Object message, String timetoken) { if(message instanceof String) { pendingAck.remove(channel); return; } Message m = new Message((JSONObject)message); pb.publish(tokenPrefix + m.getSenderId(), \u0026quot;ACK\u0026quot;, new Callback() {}); Display.getInstance().callSerially(() -\u0026gt; { addMessage(m); respond(m); }); } }); } catch(PubnubException err) { Log.e(err); Dialog.show(\u0026quot;Error\u0026quot;, \u0026quot;There was a communication error: \u0026quot; + err, \u0026quot;OK\u0026quot;, null); } } In the showChatForm method we need to fallback to push, this is a bit of a large method so I’m only posting\nthe relevant section here:\nfinal Message messageObject = new Message(tokenPrefix + uniqueId, tokenPrefix + d.uniqueId, imageURL, fullName, text); JSONObject obj = messageObject.toJSON(); String pid = Preferences.get(\u0026quot;pid-\u0026quot; + tokenPrefix + d.uniqueId, null); if(pid != null) { // if we have a push address for the contact we can send them a push if they aren't reachable... UITimer timeout = new UITimer(() -\u0026gt; { if(pendingAck.contains(tokenPrefix + d.uniqueId)) { pendingAck.remove(tokenPrefix + d.uniqueId); // send two messages, one hidden with the data as JSON for parsing on the client // the other one visible with the text that should appear to the user who isn't running // the app, this will allow him to launch the app and then receive the hidden message immediately // within the app String cert = ITUNES_DEVELOPMENT_PUSH_CERT; String pass = ITUNES_DEVELOPMENT_PUSH_CERT_PASSWORD; if(ITUNES_PRODUCTION_PUSH) { cert = ITUNES_PRODUCTION_PUSH_CERT; pass = ITUNES_PRODUCTION_PUSH_CERT_PASSWORD; } if(Push.sendPushMessage(PUSH_TOKEN, text + \u0026quot;;\u0026quot; + obj.toString(), ITUNES_PRODUCTION_PUSH, GCM_SERVER_API_KEY, cert, pass, 3, pid)) { t.getUnselectedStyle().setOpacity(255); t.repaint(); addMessage(messageObject); } else { chatArea.removeComponent(t); chatArea.revalidate(); Dialog.show(\u0026quot;Error\u0026quot;, \u0026quot;We couldn't reach \u0026quot; + d.name + \u0026quot; thru push\u0026quot;, \u0026quot;OK\u0026quot;, null); } } }); timeout.schedule(10000, false, write.getComponentForm()); if(!pendingAck.contains(tokenPrefix + d.uniqueId)) { pendingAck.add(tokenPrefix + d.uniqueId); } } The way this works is rather simple:\nIf we have a push id then we create a 10 second timer\nWhen the timer elapses we check if the pendingAck is still pending, if so we need to fall back to push\nWe have the device push key from the Message class above so sending the push message is pretty easy\nrelatively\nWe send a type 3 push which includes both a visible and invisible payload separated by a colon (;).\nThe visible payload is just the text of the message whereas the invisible payload is the JSON string we want to add to the message database\nAnd that’s pretty much it for the chat app!\nFinal Word You can check out the final source code of this tutorial here.\nWhen I started off with this tutorial I wasn’t yet familiar with the Parse integration for Codename One.\nAfter playing with it quite a bit and being blown away by it I would have architected this whole app on\ntop of it and simplified quite a bit in the process. It would also allow me to track push ID’s keep messages\nin place and remove some of the issues with going back and forth between PubNub/native push.\nI’d still use PubNub without a doubt! Its amazing and very convenient for fast push networking. I think that combining\nit with Parse would have made this a much better app.\nLogin via Google/Facebook etc. was probably the most painful part of the app and I’m including push notification\nwithin the set of pains. While it is much simpler than it used to be and is simpler than the native/web versions I\nthink the main problem is in the networks opacity and desire to keep the developers close. The pain is less on\nour side and more on the tedium of creating apps and passing values to Facebook/Google. The APK hash key\nis just painful, there were things such as \u0026ldquo;invite a friend\u0026rdquo; which I just avoided because of the tedium.\nI might do a rewrite with those thoughts in mind but I’m more inclined to redo this as a cn1lib rather than an app.\nThe main motivation being end user support for apps, so developers can communicate with users over issues by integrating\na single cn1lib into our app. I’m not sure I’ll have time to dig into something like that but I think it should be\nrelatively easy since most of the big pieces (push, cloud storage etc.) are already handled by these great 3rd party\nservices.\nOther Posts In This Series This is a multi-part series of posts including the following parts:\nPart 1 – Initial UI\nPart 2 – Login With Google\nPart 3 – Login With Facebook\nPart 4 – The Contacts Form\nPart 5 – The Chat Form\nPart 6 – Native Push \u0026amp; Finishing Up\nYou can check out the final source code of this tutorial here. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — September 18, 2015 at 1:50 pm (permalink) Nice to see the concluding ‘edition’ of this series. I’ve scanned quickly through the post and I have a few questions:\n1. Can you please explain what you mean by visible and hidden push? I had a look at the Push Javadoc and didn’t seem to find any sendPushMessage() method meeting the signature you used.\n2. You say that the PushCallback must be implemented by the main class.\n(a) Why is that needed?\n(b) For a GUI builder application this would be the StateMachine class right?\nShai Almog — September 18, 2015 at 3:34 pm (permalink) 1. Both iOS and Android allow delivering a payload that is hidden so we can just update application state from the server.\nHidden push is just push type==2 and type 3 means we are sending two push entries in a single operation: http://www.codenameone.com/…\nThe javadocs should be updated this is related to the new push architecture: http://www.codenameone.com/…\n2. The main class represents the lifecycle (start, stop etc.) and that is effectively where push resides in the native platform. So we mapped it to there. A main class exists even in a GUI builder app, its not the statemachine class.\nChidiebere Okwudire — September 24, 2015 at 7:15 am (permalink) Clear. Thanks\nHristo Vrigazov — July 19, 2016 at 6:42 pm (permalink) Cloned the chat, and the following is shown just after I login with Google:\njava.lang.NullPointerException\nat com.codename1.ui.html.HTMLComponent.newLine(HTMLComponent.java:1872)\nat com.codename1.ui.html.HTMLComponent.processTag(HTMLComponent.java:3289)\nat com.codename1.ui.html.HTMLComponent.processTag(HTMLComponent.java:3273)\nat com.codename1.ui.html.HTMLComponent.processTag(HTMLComponent.java:3273)\nat com.codename1.ui.html.HTMLComponent.processTag(HTMLComponent.java:3273)\nat com.codename1.ui.html.HTMLComponent.rebuildPage(HTMLComponent.java:1757)\nat com.codename1.ui.html.HTMLComponent.documentReady(HTMLComponent.java:1143)\nat com.codename1.ui.html.HTMLComponent.streamReady(HTMLComponent.java:1058)\nat com.codename1.components.WebBrowser$4$1.readResponse(WebBrowser.java:138)\nat com.codename1.io.ConnectionRequest.performOperation(ConnectionRequest.java:483)\nat com.codename1.io.NetworkManager$[NetworkThread.run](http://NetworkThread.run)([NetworkManager.java](http://NetworkManager.java):282)\nat [com.codename1.impl.Codename…](http://com.codename1.impl.CodenameOneThread.run)([CodenameOneThread.java](http://CodenameOneThread.java):176)\nWhat could be the problem?\nShai Almog — July 20, 2016 at 4:26 am (permalink) Make sure you are running under Java 8. You are falling back to use code that doesn’t have access to the webkit browser.\nHristo Vrigazov — July 20, 2016 at 2:01 pm (permalink) Thanks, that was the problem! Awesome tutorials by the way\nAyushi Gupta — December 7, 2016 at 10:32 pm (permalink) Ayushi Gupta says:\nfollowed all the instructions \u0026amp; this is what happened ….\nant -f C:\\Users\\Administrator\\Documents\\NetBeansProjects\\SocialChat1 -Dnb.internal.action.name=run run\nNo GUI Entries available\ninit:\nDeleting: C:UsersAdministratorDocumentsNetBeansProjectsSocialChat1buildbuilt-jar.properties\ndeps-jar:\nUpdating property file: C:UsersAdministratorDocumentsNetBeansProjectsSocialChat1buildbuilt-jar.properties\nCompile is forcing compliance to the supported API’s/features for maximum device compatibility. This allows smaller\ncode size and wider device support\ncompile:\nrun:\nDec 08, 2016 3:56:07 AM java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node SoftwareJavaSoftPrefs at root 0x80000002. Windows RegCreateKeyEx(…) returned error code 5.\njava.lang.ClassNotFoundException: com.mycompany.myapp.MyApplication\nat java.net.URLClassLoader.findClass(URLClassLoader.java:381)\nat java.lang.ClassLoader.loadClass(ClassLoader.java:424)\nat sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)\nat java.lang.ClassLoader.loadClass(ClassLoader.java:357)\nat java.lang.ClassLoader.findSystemClass(ClassLoader.java:1004)\nat com.codename1.impl.javase.ClassPathLoader.findClass(ClassPathLoader.java:100)\nat com.codename1.impl.javase.ClassPathLoader.loadClass(ClassPathLoader.java:50)\nat java.lang.Class.forName0(Native Method)\nat java.lang.Class.forName(Class.java:264)\nat com.codename1.impl.javase.Executor$[1.run](http://1.run)([Executor.java](http://Executor.java):86)\nat java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)\nat java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)\nat java.awt.EventQueue.access$500(EventQueue.java:97)\nat java.awt.EventQueue$[3.run](http://3.run)([EventQueue.java](http://EventQueue.java):709)\nat java.awt.EventQueue$[3.run](http://3.run)([EventQueue.java](http://EventQueue.java):703)\nat java.security.AccessController.doPrivileged(Native Method)\nat java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)\nat java.awt.EventQueue.dispatchEvent(EventQueue.java:726)\nat java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)\nat java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)\nat java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)\nat java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)\nat java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)\nat [java.awt.EventDispatchThrea…](http://java.awt.EventDispatchThread.run)([EventDispatchThread.java](http://EventDispatchThread.java):82)\nJava Result: 1\nBUILD SUCCESSFUL (total time: 2 seconds)\nPlease help this is 2nd time i m trying to make this chat app\nShai Almog — December 8, 2016 at 6:18 am (permalink) Shai Almog says:\nIt clearly says: ClassNotFoundException: com.mycompany.myapp.MyApplication\nYou created a project and then modified the package/class name after the fact without fixing it everywhere.\nAyushi Gupta — December 8, 2016 at 4:16 pm (permalink) Ayushi Gupta says:\nnow how can i fix it ….when i was making first one…my application was used by me but now Social Chat and Message are 2 classes as mentioned in tutorials …..so now what to do…..\u0026amp; plz tell me that where i need to fix it Plzz let me know how to fix it\ni guess i have done that….but now there is java:108 indicating problem in roundPlaceholder = EncodedImage.createFromImage(userPlaceholder.scaled(mask.getWidth(), mask.getHeight()).applyMask(mask.createMask()), false);\nthis is what happened\nCompile is forcing compliance to the supported API’s/features for maximum device compatibility. This allows smaller\ncode size and wider device support\ncompile:\nrun:\nDec 09, 2016 2:30:38 AM java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node SoftwareJavaSoftPrefs at root 0x80000002. Windows RegCreateKeyEx(…) returned error code 5.\njava.lang.NullPointerException\nat com.mycompany.myapp.Gchat.init(Gchat.java:108)\nat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\nat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\nat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImp…:43)\nat java.lang.reflect.Method.invoke(Method.java:498)\nat com.codename1.impl.javase.Executor$1$[1.run](http://1.run)([Executor.java](http://Executor.java):81)\nat com.codename1.ui.Display.processSerialCalls(Display.java:1152)\nat com.codename1.ui.Display.mainEDTLoop(Display.java:969)\nat [com.codename1.ui.RunnableWr…](http://com.codename1.ui.RunnableWrapper.run)([RunnableWrapper.java](http://RunnableWrapper.java):120)\nat [com.codename1.impl.Codename…](http://com.codename1.impl.CodenameOneThread.run)([CodenameOneThread.java](http://CodenameOneThread.java):176)\nplz let me know how to fix it\nAyushi Gupta — December 9, 2016 at 4:10 pm (permalink) Ayushi Gupta says:\ni guess i have fixed it …but now i got this\nDec 09, 2016 9:37:28 PM java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node SoftwareJavaSoftPrefs at root 0x80000002. Windows RegCreateKeyEx(…) returned error code 5.\njava.lang.NullPointerException\nat com.mycompany.myapp.Gchat.init(Gchat.java:108)\nat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\nat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\nat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImp…:43)\nat java.lang.reflect.Method.invoke(Method.java:498)\nat com.codename1.impl.javase.Executor$1$[1.run](http://1.run)([Executor.java](http://Executor.java):81)\nat com.codename1.ui.Display.processSerialCalls(Display.java:1152)\nat com.codename1.ui.Display.mainEDTLoop(Display.java:969)\nat [com.codename1.ui.RunnableWr…](http://com.codename1.ui.RunnableWrapper.run)([RunnableWrapper.java](http://RunnableWrapper.java):120)\nat [com.codename1.impl.Codename…](http://com.codename1.impl.CodenameOneThread.run)([CodenameOneThread.java](http://CodenameOneThread.java):176)\nJava Result: 1\nPlzzz let me know how to fix it\nAyushi Gupta — December 9, 2016 at 5:44 pm (permalink) Ayushi Gupta says:\ni fixed it …but now when i press signin with google after asking my e-mail and password it goes to codenameone page and says PAGE NOT FOUND and when i press signin with facebook it says \u0026ldquo;Can’t Load URL: The domain of this URL isn’t included in the app’s domains. To be able to load this URL, add all domains and subdomains of your app to the App Domains field in your app settings\u0026rdquo;\nPllzzz let me know how to fix it\nShai Almog — December 10, 2016 at 6:16 am (permalink) Shai Almog says:\nThat usually means you got a login callback with success and that the page is no longer relevant. Notice that the experience on the device differs greatly from the experience in the simulator since you will use the native login there.\nMake sure you defined the app correctly and have the right calls within the login success/fail.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/building-a-chat-app-with-codename-one-part-6/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/building-a-chat-app-with-codename-one-part-6/chat-app-tutorial-chat-form-5.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThis will be the last installment of this tutorial which was pretty complete in the previous section already. We might\u003cbr\u003e\nhave additional installments mostly for covering enhancements such as \u0026ldquo;invite a friend\u0026rdquo; and other similar capabilites\u003cbr\u003e\nbut this is probably as good a place as any to finish the app and let you try it live.\u003c/p\u003e\n\u003ch3 id=\"native-push\"\u003eNative Push\u003c/h3\u003e\n\u003cp\u003eUp until now we used PubNub to implement the push functionality which is excellent especially if you opt for the\u003cbr\u003e\npaid option which can also persist messages and offers quite a few additional perks for an app such as this.\u003cbr\u003e\nHowever, when the app isn’t running PubNub can’t push anything and in that case we need an OS native push to\u003cbr\u003e\nsend the message.\u003c/p\u003e","title":"Building A Chat App With Codename One Part 6"},{"content":"\nThis past Thursday morning, I hosted our third tech-talk/webinar for the community. The first two included tutorials that were targeted at absolute beginners. This time I wanted drill down and cover a more advanced topic: creating themes.\nCodename One provides extensive support for designing beautiful user interfaces, but it isn’t necessarily obvious to new developers how to achieve their desired results. A common workflow for app design includes a PSD file with mock-ups of the UI, created by a professional designer.\nFor this tutorial, I adapted a very slick looking sign-up form that I found online, and converted it to a Codename One component that can be used inside an application. The process I followed was:\nFind the PSD design I want to use I found this nice sign-up form in this PSD file created by Adrian Chiran :\nRe-create the general structure and layout of the design in a Codename One component using nested components and layout managers. Here is a break-down of how I structured the component hierarchy in my Codename One Component: Extract the images we needed using Photoshop.\nExtracted the fonts, colors, and styles we needed to reproduce the design in Codename One.\nImported images into our Codename one project, and defined theme styles so that are component matches the look of the original design.\nHere is a screenshot of the resulting component running inside the Codename One simulator:\nI also built this demo project using the Codename One Javascript port and have posted it online with simulated densities for the iPhone 3G, iPhone 4, and iPhone 5, so you can try out the form, and see how it adjusts to different screen densities and resolutions.\nClick here to try out the this component in your browser.\n__ Currently only Chrome, Firefox, and Safari are supported. Here is a video of the tutorial:\nBy applying just a few simple techniques, you can spice up your App’s UI and set it apart from all the rest.\nSneak Peak at CSS Support Near the end of the tutorial, I gave a sneak peak at the upcoming CSS theming support, and showed how we can produce the same design using CSS instead of using the resource editor. Personally I prefer to use a text-based format like CSS for defining my themes. It is easier to re-use styles between projects and share themes with other developers. Once you are well-versed in CSS, it is generally also much faster than working with a GUI tool.\nJust to give you a taste of what is involved in theming a component with CSS, here is the Java source for my SignUpForm component. Pay special note to the setUIID() calls which register components with specific IDs that I target from CSS:\npackage com.codename1.demos.css; import com.codename1.ui.Button; import com.codename1.ui.Command; import com.codename1.ui.Component; import com.codename1.ui.Container; import com.codename1.ui.Display; import com.codename1.ui.Form; import com.codename1.ui.Label; import com.codename1.ui.TextField; import com.codename1.ui.events.ActionEvent; import com.codename1.ui.layouts.BorderLayout; import com.codename1.ui.layouts.BoxLayout; import com.codename1.ui.layouts.FlowLayout; import com.codename1.ui.layouts.GridLayout; import com.codename1.ui.util.Resources; /** * * @author shannah */ public class SignUpForm extends Form { final Resources res; public SignUpForm(Resources res) { super(\u0026quot;Sign Up\u0026quot;); this.setUIID(\u0026quot;SignUpForm\u0026quot;); this.res = res; setLayout(new BorderLayout()); Container north = new Container(new FlowLayout(Component.CENTER)); north.setUIID(\u0026quot;SignUpNorth\u0026quot;); Button photoButton = new Button(res.getImage(\u0026quot;profile-photo-button.png\u0026quot;)); photoButton.setUIID(\u0026quot;PhotoButton\u0026quot;); north.addComponent(photoButton); this.addComponent(BorderLayout.NORTH, north); Container center = new Container(new BoxLayout(BoxLayout.Y_AXIS)); center.setUIID(\u0026quot;SignUpCenter\u0026quot;); Container row1 = new Container(new GridLayout(1,2)); TextField firstName = new TextField(); firstName.setUIID(\u0026quot;SignUpField\u0026quot;); firstName.setHint(\u0026quot;First Name\u0026quot;); firstName.getHintLabel().setUIID(\u0026quot;SignupFieldHint\u0026quot;); TextField lastName = new TextField(); lastName.setUIID(\u0026quot;SignUpField\u0026quot;); lastName.setHint(\u0026quot;Last Name\u0026quot;); lastName.getHintLabel().setUIID(\u0026quot;SignupFieldHint\u0026quot;); row1.addComponent(firstName); row1.addComponent(lastName); center.addComponent(row1); center.setScrollableY(true); TextField email = new TextField(); email.setUIID(\u0026quot;SignUpField\u0026quot;); center.addComponent(email); email.setHint(\u0026quot;Email Address\u0026quot;); email.getHintLabel().setUIID(\u0026quot;SignupFieldHint\u0026quot;); TextField password = new TextField(); password.setUIID(\u0026quot;SignUpField\u0026quot;); password.setConstraint(TextField.PASSWORD); password.setHint(\u0026quot;Choose Password\u0026quot;); password.getHintLabel().setUIID(\u0026quot;SignupFieldHint\u0026quot;); center.addComponent(password); Container row4 = new Container(new BorderLayout()); Label code = new Label(\u0026quot;+1\u0026quot;); code.setUIID(\u0026quot;SignUpLabel\u0026quot;); row4.addComponent(BorderLayout.WEST, code); TextField phoneNumber = new TextField(); phoneNumber.setUIID(\u0026quot;SignUpField\u0026quot;); phoneNumber.setHint(\u0026quot;Phone Number\u0026quot;); phoneNumber.getHintLabel().setUIID(\u0026quot;SignupFieldHint\u0026quot;); row4.addComponent(BorderLayout.CENTER, phoneNumber); center.addComponent(row4); this.addComponent(BorderLayout.CENTER, center); Button getStarted = new Button(\u0026quot;Get Started\u0026quot;, res.getImage(\u0026quot;right_arrow.png\u0026quot;)); getStarted.setGap(getStarted.getStyle().getFont().getHeight()); getStarted.setUIID(\u0026quot;SignUpButton\u0026quot;); getStarted.setTextPosition(Component.LEFT); this.addComponent(BorderLayout.SOUTH, getStarted); this.addCommand(new Command(\u0026quot;Done\u0026quot;) { @Override public void actionPerformed(ActionEvent evt) { } }); this.setBackCommand(new Command(\u0026quot;\u0026quot;, res.getImage(\u0026quot;back-arrow.png\u0026quot;)) { @Override public void actionPerformed(ActionEvent evt) { } }); } } And here is the CSS I used to style the app to look like the PSD design:\n/** * Import the TTF font to use for all the buttons */ @font-face { font-family: \u0026quot;Source Sans Pro\u0026quot;; src: url(https://raw.githubusercontent.com/google/fonts/master/ofl/sourcesanspro/SourceSansPro-Light.ttf); } @media cn1 { /** * Import the images that we want to use in our form. */ ProfilePhoto { background-image: url(../assets/profile-photo-button.png); cn1-image-id: \u0026quot;profile-photo-button.png\u0026quot;; } RightArrow { background-image: url(../assets/right_arrow.png); cn1-image-id: \u0026quot;right_arrow.png\u0026quot;; } BackArrow { background-image: url(../assets/back-arrow.png); cn1-image-id: \u0026quot;back-arrow.png\u0026quot;; } /** * Set background for the form itself. */ SignUpForm { cn1-derive: Form; background-image: url(../assets/signup-form-bg.png); } /** * Make the title bar transparent. */ TitleArea { background-color: transparent; } /** * Use the TTF font in all components that need it. */ Title, SignUpField, SignUpLabel, SignUpButton, TitleCommand, BackCommand, SignupFieldHint { font-family: \u0026quot;Source Sans Pro\u0026quot;; } /** * Make the top-right \u0026quot;Done\u0026quot; button text pink. */ TitleCommand { color: rgb(247, 50, 103); } /** * When the \u0026quot;Done\u0026quot; button is pressed, make the text white. */ TitleCommand.pressed { color: white; } /** * Add styles for the text fields. */ SignUpField, SignUpLabel { border: 1px solid rgb(245, 245, 245); padding: 2mm; background-color: transparent; color: rgb(77, 96, 111); margin: 0; } /** * Text fields use iternal Label for hints. Set styles on those separately. */ SignupFieldHint { color: rgb(77, 96, 111); font-size: small; } /** * White background for center panel (behind text fields). */ SignUpCenter { background-color: white; margin: 0; } /** * Bottom pink \u0026quot;Getting Started button\u0026quot; */ SignUpButton { background-color: rgb(247, 50, 103); margin: 0; padding: 2mm; text-align: center; color: white; } /** * Make getting started button gray background when pressed. */ SignUpButton.pressed { background-color: gray; } } Here is a video tutorial showing how to create the theme for the sign-up form using CSS:\nI don’t have an exact date when CSS support will be released to the wild, but it will be soon. Some of the features include:\nSupport for all current Codename One styles: colors, alignment, background images, borders (both regular and 9-piece), padding, margin, etc..\nGradients, shadows, rounded corners, and other nice CSS effects – that are performant.\nAuto 9-piece border generation for backgrounds and borders that require it (e.g. for rounded corners, shadows, and gradients).\nAuto multi-image generation.\nLoading images and fonts from both local paths and remote URLs.\nI’ll be posting more on this soon. Stay tuned.\nA Social Experience While the tech talk was centered around the tutorial, it also provided a forum for the community to interact and socialize. Throughout the presentation, the chat area was active with questions and discussions. With Chen participating in the discussion, and answering questions, this did not interfere at all with the tutorial, and it seemed to add a nice social dimension to the webinar. I hope this continues in future webinars, and I hope you’ll join us and become part of the conversation.\nDo You Want to Share? As these webinars will be happening every two weeks, I’d like to make some time for members of the community to talk about things that they’ve been working on. Have you developed something in Codename One that you want to share with the community?\nArchived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — September 15, 2015 at 8:55 pm (permalink) Great tutorial. Is there any reason you copied/pasted the unselected UUID’s to selected, and didn’t right click -\u0026gt; Derive them ?\nEliecer Hernández Garbey — March 13, 2016 at 3:38 am (permalink) Just amazing. A real inspirational and interesting video.\nHtml Pro — April 20, 2017 at 5:52 am (permalink) Love this article. Nicely explain all the points with code example and self explaining images. Amazing . More then enough for the beginner. He/she can learn alot of thing by such amazing tutorials.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/psd-to-app-converting-a-beautiful-design-into-a-native-mobile-app/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/psd-to-app-converting-a-beautiful-design-into-a-native-mobile-app/psd_to_app_title_image.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis past Thursday morning, I hosted our third tech-talk/webinar for the community. The first two included tutorials that were targeted at absolute beginners. This time I wanted drill down and cover a more advanced topic: creating themes.\u003c/p\u003e\n\u003cp\u003eCodename One provides extensive support for designing beautiful user interfaces, but it isn’t necessarily obvious to new developers how to achieve their desired results. A common workflow for app design includes a PSD file with mock-ups of the UI, created by a professional designer.\u003c/p\u003e","title":"PSD to App: Converting a Beautiful Design into a Native Mobile App"},{"content":"\nWe’ve been so busy recently that changes and features keep piling up with no end…\nPermanent Sidemenu It was always possible to create a permanent side menu but up until now it wasn’t trivial. For Tablets/Desktops\nthe side menu UI is perfect, but the folding aspect of it isn’t as great. We have more space so we’d like to keep\nit open all the time.\nUnfortunately, the side menu implementation wasn’t very suited for such usage. With the Toolbar this became\nmuch easier to implement in a generic way. Right now we hardcoded the side menu to the left, fixing it to work\nfor all sides would requite some effort. But its still pretty neat, just do something like this in your init(Object)\nmethod and your code will implicitly adapt to tablets/desktops if you used the Toolbar API.\n// will return true for desktops as well... if(Display.getInstance().isTablet()) { Toolbar.setPermanentSideMenu(true); } All Styles We recommend using the designer and UIID’s for styles but sometimes its just inconvenient or wrong. That’s why\nwe allow things such as:\nmyCmp.getUnselectedStyle().setFgColor(0xffffff); A lot of people misuse getStyle() for this case which returns the current style based on state. Also\nwith focusable or pressable components (e.g. Button) this becomes a HUGE chore. If I want to disable a border\nfor a button in all of its states I need to do this:\nmyButton.getUnselectedStyle().setBorder(null); myButton.getSelectedStyle().setBorder(null); myButton.getPressedStyle().setBorder(null); myButton.getDisabledStyle().setBorder(null); If I need to set more than one property this becomes a huge pain and I’d want to refactor this into a method that\naccepts a Style object etc… Painful!\nSo to simplify this common use case we finally came up with something simple: getAllStyles().\nThis new method returns a special \u0026ldquo;fake\u0026rdquo; style object that will implicitly call all the above setters in a single go.\nImportant: the getters for this style return meaningless values and should never be used,\nwe would have added an exception for them but this would create a performance penalty.\nTo use this new style for the above use case just do:\nmyButton.getAllStyles().setBorder(null); Minor Updates Chen added support for customizing the audio when a push arrives in Android, he posted the details to the\nrelevant issue in git. We added a setter to the Picker allowing you to specify a SimpleDateFormat to properly format the displayed date. We added a new utility method to Container that makes the common process of wrapping a Component in a\nContainer trivial. E.g.\nContainer enclosed = Container.encloseIn(new BorderLayout(), new Button(\u0026quot;Up North\u0026quot;), BorderLayout.NORTH); Creating A Scrollbar in Codename One Codename One has always been \u0026ldquo;mobile first\u0026rdquo; and while we do have a desktop/web port it still feels like\na mobile app even there which is normally fine by us.\nIn the past some guys asked for scrollbar functionality and we thought it would be a bit tough, but recently\na discussion in the forums\nmade my aging brain cogs spin a bit and I came up with a really simple way to implement a scrollbar in\nCodename One with almost no code!\nWe might build something like this into Codename One proper if there is demand for it although right now I think\nthis should be enough for most cases:\nprivate Container makeScrollable(final Component scrollable, Image thumb) { scrollable.setScrollVisible(false); final Slider scroll = new Slider(); scroll.setThumbImage(thumb); Container sc = new Container(new BorderLayout()); sc.addComponent(BorderLayout.CENTER, scrollable); sc.addComponent(BorderLayout.EAST, scroll); scroll.setVertical(true); scroll.setMinValue(0); scroll.setEditable(true); scroll.setMaxValue(scrollable.getScrollDimension().getHeight()); scroll.setProgress(scroll.getMaxValue()); final boolean[] lock = new boolean[1]; scroll.addDataChangedListener(new DataChangedListener() { public void dataChanged(int type, int index) { if(!lock[0]) { lock[0] = true; scrollable.scrollRectToVisible(0, scroll.getMaxValue() - index, 5, scrollable.getHeight(), scrollable); lock[0] = false; } } }); scrollable.addScrollListener(new ScrollListener() { public void scrollChanged(int scrollX, int scrollY, int oldscrollX, int oldscrollY) { if(!lock[0]) { lock[0] = true; scroll.setProgress(scroll.getMaxValue() - scrollY); lock[0] = false; } } }); return sc; } Coming Soon I have the last part of the chat app tutorial practically ready. It was delayed waiting for the new push stuff to\ncome out and then got delayed because of some bugs related to specific usage of the certificate wizard.\nI’ll try to get this out next week or the week after that time permitting.\nI’ve been working on some apps recently, most specifically I was building an app in my free time for my spouses\nYoga Studio and I’ve been playing with the excellent\nParse cn1lib from Chidiebere Okwudire.\nI was pleasantly surprised by how mature and solid it felt!\nThis has been something I procrastinated on for more than 4 years and I got the whole thing done in 4 days!\nThe Parse/server storage logic took me less than 24 hours and worked on the first try which is something that\ntook me by surprise…\nWe have some other apps mostly built as PoC’s and demos, we are thinking of a way to expose them to\na wider audience probably as a bundle.\nAt the top of the post you can see some screenshots of a couple of those apps. Ideally we’ll pair this with\na course that would hopefully refresh the now ageing CodenameOne 101 with something more similar to the Learn mobile programming by example with Codename One course.\nUpdate: Since writing this we’ve launched the Codename One Academy. Check it out… Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — September 10, 2015 at 9:22 am (permalink) Chidiebere Okwudire says:\nThanks for the compliments about parse4cn1. Of course, the main credit goes to the author of parse4j, Thiago Locatelli, who already laid a solid foundation in terms of design and implementation that I built upon.\nParse offers some other ‘goodies’ that might be interesting to the CN1 community like analytics (though from the last I remember, Flurry had better options for analysis and segmentation). Then there’s also the now rather infamous/controversial push notification service 😉 I hope others will contribute to parse4cn1 to further extend the coverage.\npollaris — April 30, 2017 at 11:53 pm (permalink) pollaris says:\nYour comments about getAllStyles saved me a lot of grief. The simulator was allowing a null exception when I was using getUnselectedStyle, but the device was failing it; my main form would not show, and all I had to go on was a null exception error message when my app started up on my device. I thought of your comments, and changed all of my styling for fonts to getAllStyles, and sure enough, the simulator caught the null exceptions and I was able to debug.\n(I am sending to Universal Windows Phone). Thanks again!\n-Russ\nBlessing Mahlalela — October 22, 2017 at 4:16 pm (permalink) Blessing Mahlalela says:\nHi, how can I disable tensile drag on side menu. I tried to inspect the components but I can’t seem to find a container that is within Toolbar… disabling tensile drag on form worked On form only and not the Side menu. Note the app is hand coded\nShai Almog — October 22, 2017 at 4:38 pm (permalink) Shai Almog says:\nHi,\nIt’s a special case. There is a special theme constant for that: sideMenuTensileDragBool which you can set to false.\nNotice we’ll switch to the on-top side menu this weekend (hopefully) so I’ll try to make that flag work over there too.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/permanent-sidemenu-getallstyles-scrollbar-and-more/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/permanent-sidemenu-getallstyles-scrollbar-and-more/yoga-and-rest-shots.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve been so busy recently that changes and features keep piling up with no end…\u003c/p\u003e\n\u003ch4 id=\"permanent-sidemenu\"\u003ePermanent Sidemenu\u003c/h4\u003e\n\u003cp\u003eIt was always possible to create a permanent side menu but up until now it wasn’t trivial. For Tablets/Desktops\u003cbr\u003e\nthe side menu UI is perfect, but the folding aspect of it isn’t as great. We have more space so we’d like to keep\u003cbr\u003e\nit open all the time.\u003cbr\u003e\nUnfortunately, the side menu implementation wasn’t very suited for such usage. With the \u003ccode\u003eToolbar\u003c/code\u003e this became\u003cbr\u003e\nmuch easier to implement in a generic way. Right now we hardcoded the side menu to the left, fixing it to work\u003cbr\u003e\nfor all sides would requite some effort. But its still pretty neat, just do something like this in your \u003ccode\u003einit(Object)\u003c/code\u003e\u003cbr\u003e\nmethod and your code will implicitly adapt to tablets/desktops if you used the \u003ccode\u003eToolbar\u003c/code\u003e API.\u003c/p\u003e","title":"Permanent SideMenu, getAllStyles, Scrollbar \u0026 more"},{"content":"\nA couple of weeks ago I created a simple social network app as part of the Codename One webinar. This app provided functionality similar to the Facebook app.\nSend and Accept friend requests\nPost news\nView news items posted by you and your friends\nFor the server, I used a PHP/MySQL REST interface, and wrote a very thin client in Codename One. Both the server and client project are on GitHub so you can review it and install it yourself on your own server.\nSome screenshots of the app running in the Codename One Simulator:\nI decided to port this app to Parse.com as a proof-of-concept.\nHere is a 3-minute screencast of the app powered by Parse.com:\nWhat is Parse.com? Parse.com is like a back-end in a box. You get a highly scalable REST server and NoSQL database without having to manage it yourself. This allows you to focus on your Codename one client app – making it slick and beautiful. No worries about scaling, server software patches, or any of that noise. Just the app.\nI particularly like the fact that Parse.com is free for apps that get a small amount of traffic (up to 30 requests per second). As your app grows, you just pay for the added bandwidth.\nA Birds-Eye View of the Porting Process I started with a fully functional app. The only portion of the Codename One app that required changes was the SocialClient class, which is where all of the interaction with the server happened.\nOn the server side, the process was roughly:\nSign up for an account on Parse.com\nCreate a new App ID\nSet up my data model\nImplement a thin REST interface for my data using Parse’s cloud functions.\nThe Client API The full API for this class is as follows:\n// Registers new user public void register(String username, String password) throws IOException; // Logs in as user public void login(String username, String password) throws IOException; // Logs current user out public void logout() throws IOException; // Gets list of friends of current user public List\u0026lt;Map\u0026gt; getFriends() throws IOException; // Finds users with username matching query string public List\u0026lt;Map\u0026gt; findUsers(String query) throws IOException; // Finds pending friend requests for current user public List\u0026lt;Map\u0026gt; getPendingFriendRequests() throws IOException; // Sends a friend request to given user public void sendFriendRequest(String username) throws IOException; // Accepts a friend request from a given user public void acceptFriendRequest(String username) throws IOException; // Decline a friend request from a given user public void declineFriendRequest(String username) throws IOException; // Gets the profile of a given user public Map getProfile(String username) throws IOException; // Updates the profile of a given user with specified values public void updateProfile(Map profile) throws IOException; // Posts a news item public long post(Map post) throws IOException; // Gets the news feed for the given user public List\u0026lt;Map\u0026gt; getFeed(Date olderThan) throws IOException; // Gets the username of the current user public String getUsername(); To interact with the PHP/MySQL back-end this API was implemented directly on top of ConnectionRequest and the NetworkManager to issue HTTP GET and POST requests directly to the server. JSON was used to transmit the response back from the server to the client, and this was converted into Maps and Lists.\n__ You’ll notice that this API does not make use of Java’s strong typing…​ I’m just using lists and maps. This was for flexibility while I was fleshing out the API. At some point, in a real-world app, I would probably refactor to use some custom Java types. For the Parse back-end we could also just write a thin REST client on top of ConnectionRequest, but there is an easier way, thanks to Chidiebere Okwudire’s parse4cn1 cn1lib, which wraps the Parse REST API providing a Java API that is very similar to the official Parse Java API.\nCreating the Parse App Log into Parse.com\nCreate a new App\nCreating the Data Model Once your app has been created you need to create your data model. In Parse.com this is done by defining a set of classes. This is analogous to creating tables in an SQL database. In order to motivate this exercise, let’s take a look at the schema for the MySQL database in the previous version. The following is the PHP (with embedded SQL code) that was used to generate the database:\n\u0026lt;?php class conf_Installer { function update_1() { $q[] = \u0026quot;create table users ( username varchar(32) primary key not null, password varchar(64) )\u0026quot;; $q[] = \u0026quot;create table sessions ( username varchar(32), token_id varchar(64) primary key not null, expires INT(11) )\u0026quot;; $q[] = \u0026quot;create table friends ( user1 varchar(32), user2 varchar(32), primary key (user1, user2 ) )\u0026quot;; $q[] = \u0026quot;create table friend_requests ( sender varchar(32), receiver varchar(32), primary key (sender, receiver) )\u0026quot;; $q[] = \u0026quot;create table profiles ( username varchar(32) primary key not null, screen_name varchar(100), avatar varchar(100), avatar_mimetype varchar(100) )\u0026quot;; $q[] = \u0026quot;create table posts ( post_id int(11) not null auto_increment primary key, username varchar(32), date_posted INT(11), photo varchar(255), photo_mimetype varchar(100), comment text )\u0026quot;; df_q($q); } } ?\u0026gt; For the Parse data model, my first instinct was to just create a class for each table. However, I discovered that that a one-to-one mapping was not ideal. This is due, in part, to the fact that Parse already provides some of the functionality out of the box, and also that Parse’s database is not relational as MySQL is.\n__ Parse supports relations but they work a little bit different than they do in a relational database like MySQL. We’ll explore the differences in more detail later. In the end, I settled on the following classes for my the app:\nUser – For user accounts. I folded the profile table data into this single class as well to simplify the model.\nPost – For news items posted by users.\nStep By Step : Creating the Data Model Creating the \u0026ldquo;User\u0026rdquo; class In the \u0026ldquo;Data\u0026rdquo; section of the \u0026ldquo;Core\u0026rdquo; tab, click on \u0026ldquo;Add Class\u0026rdquo;: Select \u0026ldquo;User\u0026rdquo; from the dialog, and click \u0026ldquo;Create Class\u0026rdquo;: Create screen_name column. Click the \u0026ldquo;+ Col\u0026rdquo; button on the top menu. Then select type = \u0026ldquo;String\u0026rdquo; and name = \u0026ldquo;screen_name\u0026rdquo;:\nCreate avatar column of type \u0026ldquo;File\u0026rdquo;: Add \u0026ldquo;friends\u0026rdquo; and \u0026ldquo;pendingFriendRequests\u0026rdquo; relations.. Add them as columns of type \u0026ldquo;Relation\u0026rdquo;: Creating the \u0026ldquo;Post\u0026rdquo; class Create a new class named \u0026ldquo;Post\u0026rdquo;: Add \u0026ldquo;comment\u0026rdquo; column. Add \u0026ldquo;photo\u0026rdquo; column with type \u0026ldquo;File\u0026rdquo;: Add \u0026ldquo;postedBy\u0026rdquo; column as type \u0026ldquo;Pointer\u0026rdquo; to the \u0026ldquo;_User\u0026rdquo; class: Uploading Files I also ended up creating an Upload class but this was purely to help with file uploads, and is not part of the conceptual design.\nAren’t we missing a lot of tables?!! How did we reduce a database down from 6 tables to only 2 classes? Well:\nThe sessions table is no longer necessary in Parse because Parse takes care of all aspects of user registration, login, and session management.\nAs mentioned before, I just folded the profiles data directly into the User class. This was for simplicity and to minimize the number of data requests to obtain profile data.\nThe friends and friend_requests tables were join tables meant to relate users to each other. In Parse, we handle this by adding a column of type Relation to our classes. E.g. The User class has a friends relation and an pendingFriendRequests relation that provide equivalent functionality to the friends and friend_requests tables.\nRelations As I mentioned above, relations are handled a little differently in Parse than in a relational database. Parse provides two column types for \u0026ldquo;pointing\u0026rdquo; to other records in the database:\nPointer – A type you can use for adding a reference to a single record in that column. E.g. If you wanted to track if a User was the parent of another User, you might add a column named \u0026ldquo;parent\u0026rdquo; to the \u0026ldquo;User\u0026rdquo; class with type \u0026ldquo;Pointer\u0026rdquo;.\nRelation – A type used for storing references to multiple records in that column. E.g. If you wanted to track all of the children of a User, you might add a column to the \u0026ldquo;User\u0026rdquo; class named \u0026ldquo;children\u0026rdquo; with type \u0026ldquo;Relation\u0026rdquo;.\nIn our data model, we needed to track two relationships between user records:\nWhether they are friends\nWhether there is a pending friend request from one to the other.\nSo I added a columns named \u0026ldquo;friends\u0026rdquo; and \u0026ldquo;pendingFriendRequests\u0026rdquo; to the \u0026ldquo;User\u0026rdquo; class, both with type \u0026ldquo;Relation\u0026rdquo;.\n__ Relationships are one-way only. E.g. If you add \u0026ldquo;Steve\u0026rdquo; to the friends relation of \u0026ldquo;Doug\u0026rdquo;, then that does not automatically add \u0026ldquo;Doug\u0026rdquo; to \u0026ldquo;Steve\u0026rdquo;‘s friends relation. For the \u0026ldquo;pendingFriendRequests\u0026rdquo; relationship this is what we want anyways, but for the \u0026ldquo;friends\u0026rdquo; relationship we wanted it to be two-way, so we need to add Steve to Doug and Doug to Steve when making them friends. Accessing the Database from Codename One Now that we have our database set up, let’s try to connect to it from our Codename one app.\nInstalling parse4cn1 library The first thing that we need to do is download and install the parse4cn1 library. You can download it from here.\nCopy the parse4cn1.cn1lib file into your project’s lib directory, then select \u0026ldquo;Refresh\u0026rdquo; libs (i.e. right click on the project \u0026gt; \u0026ldquo;Codename One\u0026rdquo; \u0026gt; Refresh Libs).\nYou will also need to install the CN1JSON library which the parse4cn1 library depends on.\nInitializing the Parse4CN1 API Before we do anything else, we need to initialize the Parse API by calling Parse.initialize() method. I place this method inside the constructor for my client class:\npublic SocialClientParse() { Parse.initialize(\u0026quot;\u0026lt;APP ID\u0026gt;\u0026quot;, \u0026quot;\u0026lt;CLIENT KEY\u0026gt;\u0026quot;); } The Application ID and client key can be found in the \u0026ldquo;Keys\u0026rdquo; tab when logged in to Parse.com.\n__ Make sure to use the \u0026ldquo;Client Key\u0026rdquo; and not the \u0026ldquo;REST API Key\u0026rdquo; or \u0026ldquo;Master Key\u0026rdquo; when connecting to Parse from a client device, as is most likely the case with Codename One apps. The REST API key and Master Key provide full permissions to your database and should not be embedded anywhere in your app for security reasons. These keys are for use in secure settings like a server-side application that connects to your parse application. Logging In The implementation of the login method for our REST client is as follows.\nParseUser user; String token; ... public void login(String username, String password) throws IOException { try { user = ParseUser.create(username, password); user.login(); token = user.getSessionToken(); } catch (ParseException ex) { Log.e(ex); throw new IOException(ex.getMessage()); } } and logging out:\npublic void logout() throws IOException { try { user.logout(); user = null; token = null; } catch (ParseException ex) { Log.e(ex); throw new IOException(ex.getMessage()); } } User Registration User registration is very similar to logging in. It just uses the ParseUser.signUp() method instead of ParseUser.login().\npublic void register(String username, String password) throws IOException { try { ParseUser user = ParseUser.create(username, password); user.put(\u0026quot;screen_name\u0026quot;, username); user.signUp(); } catch (ParseException ex) { Log.e(ex); throw new IOException(ex.getMessage()); } } The rest of the REST API The Parse API provides support for CRUD (Create-Read-Update-Delete) directly from the client to the data source. For security it supports ACLs at both the class-level and the object level. Therefore, if you set up your ACLs appropriately, you could interact with the database directly from your Codename one client app. You can see API examples on the parse4cn1 wiki.\nHere are a few reasons why you should NOT do this\nOffering direct database access to the client makes the app very difficult to secure. Any server-side engineer worth a salt know that YOU CANNOT TRUST THE CLIENT. If you want actions to be available to some users but not others – and they are using the same client app, then you need to be very careful about the ACLs that you use in your database.\nSome operations may require multiple database requests which can slow the app down. Better to just send a single request to the parse server, and let server-side code handle the multiple queries.\nCloud Code Parse allows you to implement server-side REST web services, known as \u0026ldquo;cloud code\u0026rdquo;. Because this code is running on the server side, you can allow them to run with the master key – so you don’t have to rely on ACLs to limit access to records and classes. You can use your own logic to decide who can do what. This model maps more closely to running your own server and provides more control. AND it allows you to lock down your database so you don’t need to provide direct access to clients.\nCloud code uses the Parse Javascript API – which is equivalent to the REST and Java APIs. In order to use them, you need to install the parse command-line tools.\nCreating Local Cloud Code Project It allows you to create a local version of the Parse app, in so much as developing cloud code is concerned. Here is the readout of parse new, the command for setting up the local development project:\nSteves-iMac:social-network-parse shannah$ parse new Please log in to Parse using your email and password. Email: [[email protected]](/cdn-cgi/l/email-protection) Password (will be hidden): Would you like to create a new app, or add Cloud Code to an existing app? Type \u0026quot;(n)ew\u0026quot; or \u0026quot;(e)xisting\u0026quot;: e 1:\tSocial Demo Select an App to add to config: 1 Awesome! Now it's time to setup some Cloud Code for the app: \u0026quot;Social Demo\u0026quot;, Next we will create a directory to hold your Cloud Code. Please enter the name to use for this directory, or hit ENTER to use \u0026quot;Social Demo\u0026quot; as the directory name. Directory Name: social-demo-parse-2 Your Cloud Code has been created at /Users/shannah/cn1_files/incubator/social-network-parse/social-demo-parse-2. Next, you might want to deploy this code with \u0026quot;parse deploy\u0026quot;. This includes a \u0026quot;Hello world\u0026quot; cloud function, so once you deploy you can test that it works, with: curl -X POST -H \u0026quot;X-Parse-Application-Id: xxxxxxxxxxxxxxxxxx\u0026quot; -H \u0026quot;X-Parse-REST-API-Key: xxxxxxxxxxxxxxxxxxxx -H \u0026quot;Content-Type: application/json\u0026quot; -d '{}' https://api.parse.com/1/functions/hello This creates a scaffold for my app project in the directory \u0026ldquo;social-demo-parse-2\u0026rdquo;. The directory structure is:\n./cloud ./cloud/main.js ./config ./config/global.json ./public ./public/index.html The only file that matters here is the ./cloud/main.js file, which will include all of the cloud code. It starts you off with a nice sample \u0026ldquo;hello\u0026rdquo; function that can be called via the REST API. Its contents are as follows:\n// Use Parse.Cloud.define to define as many cloud functions as you want. // For example: Parse.Cloud.define(\u0026quot;hello\u0026quot;, function(request, response) { response.success(\u0026quot;Hello world!\u0026quot;); }); This is a simple function that simply returns the string \u0026ldquo;Hello world!\u0026rdquo;. You can call this function directly from your Codename One app by simply calling:\nString result = (String)ParseCloud.callFunction(\u0026quot;hello\u0026quot;, null); System.out.println(result); // Hello world! Writing End Points for the REST API Now, we just need to create end points for all of our client’s pertinent functions. Let’s start by inserting placeholders for our API end points:\nParse.Cloud.define(\u0026quot;send_friend_request\u0026quot;, function(request, response) { ... }); Parse.Cloud.define(\u0026quot;accept_friend_request\u0026quot;, function(request, response) { ... }); Parse.Cloud.define(\u0026quot;decline_friend_request\u0026quot;, function(request, response) { }); Parse.Cloud.define(\u0026quot;get_pending_friend_requests\u0026quot;, function(request, response) { }); Parse.Cloud.define(\u0026quot;get_friends\u0026quot;, function(request, response) { }); Parse.Cloud.define(\u0026quot;post\u0026quot;, function(request, response) { }); Parse.Cloud.define(\u0026quot;update_profile\u0026quot;, function(request, response) { }); Parse.Cloud.define(\u0026quot;get_profile\u0026quot;, function(request, response) { }); Parse.Cloud.define(\u0026quot;get_feed\u0026quot;, function(request, response) { }); Parse.Cloud.define(\u0026quot;find_users\u0026quot;, function(request, response) { }); In order to remain consistent with the PHP/MySQL REST API in the previous version, we will have these end points always return a JSON object with the following form:\n//For errors: {code : 500, message : \u0026quot;Some error message\u0026quot;, ...} // For successes {code : 200, ... } That way the client can always check the \u0026ldquo;code\u0026rdquo; property to find out if the action was successful.\nFor successful operations, there may be three types of return values:\nNo return value. E.g. accept_friend_request, send_friend_request.\nReturns a list of objects. E.g. find_users, get_friends, etc..\nReturns a single object. E.g. get_profile\nWriting Codename One Web Service Client So on the client side (in our Codename One app), I created 3 utility wrappers to handle these cases:\n/** * Calls cloud code function with void return type. * @param funcName The name of the function to call. * @param params Parameters passed to the function. Accepts null. */ private void callFunc(String funcName, Map params) throws IOException { try { JSONObject response = (JSONObject)ParseCloud.callFunction(funcName, params); int code = response.getInt(\u0026quot;code\u0026quot;); if (code != 200) { throw new IOException(response.getString(\u0026quot;message\u0026quot;)); } } catch (Throwable ex) { Log.e(ex); ex.printStackTrace(); throw new IOException(ex.getMessage()); } } /** * Calls a cloud code function whose result will be a list of objects. * @param funcName The name of the cloud code function to call. * @param params Parameters passed to the cloud code. Accepts null. * @param listKey The JSON key in the response object that contains the list of objects that * were returned by the cloud code. */ private List\u0026lt;Map\u0026gt; getList(String funcName, Map params, String listKey) throws IOException { try { JSONObject response = (JSONObject)ParseCloud.callFunction(funcName, params); System.out.println(response); int code = response.getInt(\u0026quot;code\u0026quot;); if (code != 200) { throw new IOException(response.getString(\u0026quot;message\u0026quot;)); } else { ArrayList\u0026lt;Map\u0026gt; out = new ArrayList\u0026lt;Map\u0026gt;(); JSONArray posts = response.getJSONArray(listKey); int len = posts.length(); for (int i=0; i\u0026lt;len; i++) { JSONObject row = posts.getJSONObject(i); out.add(toMap(row)); } return out; } } catch (Throwable ex) { Log.e(ex); ex.printStackTrace(); throw new IOException(ex.getMessage()); } } /** * Calls cloud code function that returns a single object. * @param funcName The name of the cloud code function to call. * @param params Parameters passed to the cloud code function. Accepts null. * @param mapKey The JSON key of the response object that contains the object that * was returned from the cloud code function. */ private Map getMap(String funcName, Map params, String mapKey) throws IOException { try { JSONObject response = (JSONObject)ParseCloud.callFunction(funcName, params); int code = response.getInt(\u0026quot;code\u0026quot;); if (code != 200) { throw new IOException(response.getString(\u0026quot;message\u0026quot;)); } else { JSONObject row = response.getJSONObject(mapKey); return toMap(row); } } catch (Throwable ex) { Log.e(ex); ex.printStackTrace(); throw new IOException(ex.getMessage()); } } For convenience I also created thin wrappers around these utility functions to be able to pass an array objects for the parameters instead of a Map.\nClient \u0026amp; Server Code for get_feed Now that we have the foundation in place for the server and client sides of the REST API, let’s flesh it out a little bit more to see exactly how the code will look on both the server-side and client-side. Take the getFeed() method, for example, that is meant to return a list of the posts that should appear in the current user’s news feed.\nThe server code will look like:\nParse.Cloud.define(\u0026quot;get_feed\u0026quot;, function(request, response) { // ... some logic to retrieve the posts from the database if (success) { response.success({code : 200, posts : [...]}); } else { response.success({code : 500, message : 'Some error message'}); } }); This omits all of the logic and is massively simplified, but the key here is that it is returning a JSON object using the response.success() callback. If there were no errors, the posts are contained in an array under the posts key of the resulting JSON object. So the web service client will use our getList() utility method as follows:\npublic List\u0026lt;Map\u0026gt; getFeed(Date olderThan) throws IOException { return getList(\u0026quot;get_feed\u0026quot;, \u0026quot;posts\u0026quot;); } Sending, Getting, \u0026amp; Accepting Friend Requests Recall from our database design that friends and friend requests are supported via the \u0026ldquo;friends\u0026rdquo; and \u0026ldquo;pendingFriendRequests\u0026rdquo; relations in the users table. Sending a friend request to a user involves, adding the current user to the \u0026ldquo;pendingFriendRequests\u0026rdquo; relation of that user. Accepting a friend request from a user involves adding the current user to that user’s \u0026ldquo;friends\u0026rdquo; relation, adding that user to the current user’s \u0026ldquo;friends\u0026rdquo; relation, and removing that user from the current user’s \u0026ldquo;pendingFriendRequests\u0026rdquo; relation. The code for send_friend_request is as follows:\nParse.Cloud.define(\u0026quot;send_friend_request\u0026quot;, function(request, response) { Parse.Cloud.useMasterKey(); (new Parse.Query(Parse.User)).equalTo(\u0026quot;username\u0026quot;, request.params.username).each(function(friend) { friend.relation(\u0026quot;pendingFriendRequests\u0026quot;).add(Parse.User.current()); friend.save().then(function(result) { response.success({code: 200, message: \u0026quot;Successfully sent friend request\u0026quot;}); }); }); }); Some things to note here:\nParse.Cloud.useMasterKey() gives us carte blanche on the parse API. We don’t have any security restrictions. Without this all access would be subject to security restrictions on the currently logged in user.\n(new Parse.Query(Parse.User)).equalTo(\u0026quot;username\u0026quot;, request.params.username).each(function(friend) {\nCreates a query on the User class for all users with \u0026ldquo;username\u0026rdquo; equal to the \u0026ldquo;username\u0026rdquo; parameter passed as part of the request. The each() method then iterates over the results with the provided callback.\nfriend.relation(\u0026quot;pendingFriendRequests\u0026quot;).add(Parse.User.current()); Adds the current user to the \u0026ldquo;pendingFriendRequests\u0026rdquo; relation of the found user.\nfriend.save().then(function(result) { We save the user object. save() returns a promise so that calling then() will result in us being able to defer what comes next until the save is complete. If you’re not familiar with promises, it’s really just cute syntax for a callback.\nresponse.success({code: 200, message: \u0026quot;Successfully sent friend request\u0026quot;}); This finally returns the response to the client as a JSON object.\nThe code for getting a list of the pending friend requests is as follows:\nParse.Cloud.define(\u0026quot;get_pending_friend_requests\u0026quot;, function(request, response) { Parse.Cloud.useMasterKey(); var out = []; var user = Parse.User.current(); user.relation(\u0026quot;pendingFriendRequests\u0026quot;).query().each(function(friend) { out.push({ sender : friend.get(\u0026quot;username\u0026quot;), receiver : user.get(\u0026quot;username\u0026quot;), avatar : friend.get(\u0026quot;avatar\u0026quot;) ? friend.get(\u0026quot;avatar\u0026quot;).url() : null, screen_name : friend.get(\u0026quot;screen_name\u0026quot;) }); }) .then(function(result) { response.success({code: 200, requests: out}); }); }); And accepting pending friend requests:\nParse.Cloud.define(\u0026quot;accept_friend_request\u0026quot;, function(request, response) { Parse.Cloud.useMasterKey(); var currentUser = Parse.User.current(); var pendingRequests = currentUser.relation(\u0026quot;pendingFriendRequests\u0026quot;); pendingRequests.query().equalTo(\u0026quot;username\u0026quot;, request.params.username).each(function(friend) { currentUser.relation(\u0026quot;friends\u0026quot;).add(friend); pendingRequests.remove(friend); currentUser.save().then(function(result) { friend.relation(\u0026quot;friends\u0026quot;).add(currentUser); return friend.save(); }, function(error) { response.success({code : 500, message : error}); }).then(function(result) { response.success({code: 200, message: \u0026quot;Friend request accepted\u0026quot;}); }, function(error) { response.success({code : 500, message : error}); }); }); }); The Full Cloud Code Source You can view the full source for this cloud code here. Each method follows roughly the same pattern:\nFetch some data from the database\nIterate through the results to build a JSON response.\nSome queries, especially queries involving complex relations like the one in get_feed were a little bit tricky to figure out, but in the end I was impressed by the Parse’s flexibility in being able to support quite complex queries. I won’t delve into the details here, but I will note that Parse’s documentation is exceptional and it seems to have quite a large user base, judging by the number of questions \u0026amp; answers related to parse that are already available online in their forums and elsewhere. I scarcely had to spend more than 5 minutes of googling to find the answer to my questions when I got stuck.\nBuild the App Yourself The full project, both the Codename One client project and the parse cloud code are posted on Github to you can download and build the project yourself.\nInstall the App on Android I have posted an Android build of this app so you can install it directly on your phone is you wish:\nDownload APK Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — September 9, 2015 at 10:28 am (permalink) Interesting tutorial…\nI completely agree that the client should never be trusted (that’s also why parse4cn1 by design does not include any operations requiring the master key). However, I’m not convinced that it’s always a better/more secure idea (or even necessary) to write cloud code.\nThe combination of ACLs, CLP (class level permissions) and the new pointer permissions http://blog.parse.com/learn… is quite powerful and should be used when applicable. Applying that the CRUD, my feeling so far is that if the primary operation is \u0026ldquo;Read\u0026rdquo;, in-buit parse security measures are more than sufficient. For the \u0026ldquo;C\u0026rdquo;, \u0026ldquo;U\u0026rdquo;, and \u0026ldquo;D\u0026rdquo;, a per-case judgment is needed. Always reverting to cloud code might be a pitfall from other paradigms where such security measures as are present in Parse were missing. And it may slow down development with little or no added value. Of course, I’m neither a security expert nor a Parse expert so what am saying might not be completely correct; just food for thought 🙂\nshannah78 — September 9, 2015 at 3:57 pm (permalink) \u0026ldquo;Security is inconvenient\u0026rdquo;, said Ashley Madison. The difficulty in securing an application increases exponentially with the number of access points. If you allow CRUD directly client side — or even just \u0026ldquo;R\u0026rdquo; — then you effectively have hundreds or thousands of access points (or millions depending on how you count). If your app has only a handful of \u0026ldquo;functions\u0026rdquo; though, you can limit the access point to just that handful and you can easily secure each point manually.\nTake the social network example. Even if the app were only read only (and it’s not), we have the challenge of allowing users to see only news items that were posted by their friends. Using the ACL method, every post would need to have an ACL entry for every friend of the poster. And when a friend is added or removed, the ACL entries for all posts of both friends would need to be modified accordingly. This, in itself is expensive and challenging, …. And it’s still easy to miss something.\nFurther, you generally don’t want profile information to be readable by anyone other than someone’s friends. How would you provide this sort of limitation securely without cloud code? You can’t make the profiles table readable by everyone, so you would need to add ACLs at the record level – same problem as with the posts. The ACLs need to be added when profiles become friends, but\nBasically if you are doing any filtering client side for the purpose of security, your app is probably vulnerable to unauthorized access. That doesn’t mean that there aren’t occasions where you can get away with direct client-side CRUD. But you have to do a lot more thinking at each step. Or one day you’ll be \u0026ldquo;that guy\u0026rdquo; .. the guy who has to explain to his boss that the database was breached and client information was stolen. Don’t be that guy!\nShai Almog — September 9, 2015 at 4:24 pm (permalink) While I generally agree with all your points I wrote the app for my spouses yoga studio using this CRUD API on top of Parse.\nI can live with one lock (the parse keys) and since this isn’t an app for global distribution the chances of these getting hacked are pretty low. The fact that this isn’t a database of interest for hackers also makes it a safe choice.\nWriting a JavaScript DAO for the code seemed like a pain so I’m totally fine with that level of security.\nMaybe for the future version of the parse lib we should integrate TeaVM so we can write the server side code in Java too 😉\nNote: that was a joke, please don’t do that! 😉\nshannah78 — September 9, 2015 at 4:54 pm (permalink) Definitely agree that level of interest to hackers should be taken into consideration. The question I usually ask myself is \u0026ldquo;how bad would it be if this database were leaked to the world\u0026rdquo;. If the answer is anything worse than \u0026ldquo;it would be perfectly fine\u0026rdquo;, then designing for security should be top priority. That said, it is possible to write a secure app using the client-side CRUD API. It is just much harder. It requires a comprehensive understanding of Parse’s system – and also a lot more thought at each step of database design.\nI actually considered writing an ANT task to be able to write and deploy cloud code using TeaVM, but that would just be proof of concept. Most access point functions were trivial, and their Javascript API is quite nice to work with directly.\nChidiebere Okwudire — September 10, 2015 at 9:09 am (permalink) Thanks guys for sharing your thoughts. Security remains a difficult but very important subject and should be treated as such.\n@shannah78:disqus: One thing to bear in mind is that cloud code is not a silver bullet. It still needs to be combined with ACLs and/or CLPs. For instance, in the social networking example, all the security gains of using cloud code will be almost useless if the corresponding classes are still directly readable or even worse writable(!) to the public because anyone getting hold of the Parse app keys would wreak havoc by directly accessing the classes directly. That aspect is missing in the blog post. Please consider mentioning it.\nshannah78 — September 11, 2015 at 5:09 am (permalink) You’re right that is missing from the post, and class level acls are still necessary to lock down the database when cloud code is used.\nSophiaVermon — September 14, 2015 at 8:02 am (permalink) Thanks for this detailed article with complete code and pictures, I will try to run it in my application.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/cloud-powered-mobile-apps-with-parse-and-codenameone/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/cloud-powered-mobile-apps-with-parse-and-codenameone/parse.com-post-header.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA couple of weeks ago I created a \u003ca href=\"https://github.com/shannah/social-network\" target=\"_blank\" rel=\"noopener noreferrer\"\u003esimple social network app\u003c/a\u003e as part of the \u003ca href=\"/blog/java-mobile-dev-webinar-recap/\"\u003eCodename One webinar\u003c/a\u003e. This app provided functionality similar to the Facebook app.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003eSend and Accept friend requests\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ePost news\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eView news items posted by you and your friends\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eFor the server, I used a \u003ca href=\"https://github.com/shannah/social-network-server/blob/master/actions/friends_api.php\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ePHP/MySQL REST interface\u003c/a\u003e, and wrote a very \u003ca href=\"https://github.com/shannah/social-network/blob/master/social-network/src/com/codename1/demos/socialnet/SocialClient.java\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ethin client\u003c/a\u003e in Codename One. Both the \u003ca href=\"https://github.com/shannah/social-network-server\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eserver\u003c/a\u003e and \u003ca href=\"https://github.com/shannah/social-network\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eclient\u003c/a\u003e project are on GitHub so you can review it and install it yourself on your own server.\u003c/p\u003e","title":"Building Cloud-powered Native Mobile Apps with Parse.com and Codename One"},{"content":"\nJetBrains recently announced that they are moving to a subscription service and people\nfreaked.\nAs an entrepreneur and a guy who spent a lot of time in big companies (e.g. Sun/Oracle) I totally applaud\nJetBrains for the move and think they did the right thing!\nYes some customers will complain loudly and use inappropriate language. But ultimately\nsoftware is a service and should be sold as a service. The complainers should not focus on their own issues\nand start looking at the issues of running a software company.\nSoftware is developed by people who need salaries, subscriptions mean we can hire easily and know\nreasonably well that we will have enough for salaries/expansion. Licenses complicate things financially and\ncause a great deal of fluctuations. They also create lopsided companies where the sales team is much bigger\nand more dominant than development (e.g. Oracle vs. Sun).\nYou can’t satisfy all the users with any pricing model, even if your pricing is competitive/cheaper people will always\nhave issues. But unfortunately a company can’t start tailoring every possible package to every possible use case.\nIf you like a product and want the company to have a sustainable business model, you should root for it to go\ninto the subscription model, its not greed: its sustainability.\nHistorically software companies would take lines of credit from banks/venture so they could develop the software\nand would then include the cost of the credit into the final shrink wrap cost. With SaaS the need for credit/funding\nis far smaller and companies can scale with demand more easily. This eventually rolls down to the users in more\ncompetitive pricing.\nSo no, you can’t buy a product and expect it to work indefinitely with a subscription model. But when could you\ndo it with shrink wrapped software?\nEvery single piece of shrink wrapped software I have on my shelf is completely useless to me at this moment,\nif I used a subscription I would have paid less and just stopped the subscription. OS’s update, JVM’s change and\nso do needs, so IMHO JetBrains did the right thing both for itself and its customers. This will allow them to\nimprove their product and make it more accessible to people.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/jetbrains-is-totally-right-with-its-subscription-model/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/jetbrains-is-totally-right-with-its-subscription-model/Logo_intellij_idea.gif\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://www.jetbrains.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eJetBrains\u003c/a\u003e recently announced that they are moving to a subscription service and people\u003cbr\u003e\n\u003ca href=\"http://developers.slashdot.org/story/15/09/05/1347204/jetbrains-moving-its-dev-tools-to-subscription-model\" target=\"_blank\" rel=\"noopener noreferrer\"\u003efreaked\u003c/a\u003e.\u003cbr\u003e\nAs an entrepreneur and a guy who spent a lot of time in big companies (e.g. Sun/Oracle) I totally applaud\u003cbr\u003e\nJetBrains for the move and think they did the right thing!\u003c/p\u003e\n\u003cp\u003eYes some customers will complain \u003cstrong\u003eloudly\u003c/strong\u003e and use inappropriate language. But ultimately\u003cbr\u003e\nsoftware is a service and should be sold as a service. The complainers should not focus on their own issues\u003cbr\u003e\nand start looking at the issues of running a software company.\u003cbr\u003e\nSoftware is developed by people who need salaries, subscriptions mean we can hire easily and know\u003cbr\u003e\nreasonably well that we will have enough for salaries/expansion. Licenses complicate things financially and\u003cbr\u003e\ncause a great deal of fluctuations. They also create lopsided companies where the sales team is much bigger\u003cbr\u003e\nand more dominant than development (e.g. Oracle vs. Sun).\u003c/p\u003e","title":"Jetbrains Is Totally Right With Its Subscription Model"},{"content":"\nWe are starting the complete overhaul of our push implementation that will allow us to deliver improved push\nrelated fixes/features and provide more reliability to the push service. When we designed our push offering\ninitially it was focused around the limitations of Google App Engine which we are finally phasing out. The new\nservers are no longer constrained by this can scale far more easily and efficiently for all requirements.\nHowever, as part of this we decided to separate the push functionality into two very different capabilities:\npush \u0026amp; device registration.\nCurrently only push is supported and so the feature of pushing to all devices is effectively unsupported at the moment.\nHowever, once the device registration API is exposed it will allow you to perform many tasks that were often\nrequested such as the ability to push to a cross section of devices (e.g. users in a given city).\nThe original push API mixed device tracking and the core push functionality in a single API which meant we\nhad scaling issues when dealing with large volumes of push due to database issues. So the new API discards\nthe old device id structure which is just a numeric key into our database. With the new API we have a new\ndevice key which includes the native OS push key as part of its structure e.g. cn1-ios-nativedevicekey\ninstead of 999999.\nAssuming you store device ids in your server code you can easily convert them to the new device ids, your server\ncode can check if a device id starts with cn1- and if not convert the old numeric id to the new ID\nusing this request (assuming 999999 is the device id):\nhttps://codename-one.appspot.com/token?m=id\u0026amp;i=999999 The response to that will be something like this:\n{\u0026quot;key\u0026quot;:\u0026quot;cn1-ios-nativedevicecode\u0026quot;} The response to that will be something or this:\n{\u0026quot;error\u0026quot;:\u0026quot;Unsupported device type\u0026quot;} To verify that a push is being sent by your account and associate the push quotas correctly the new API\nrequires a push token. You can see your push token in the developer console at the bottom of the account\nsettings tab. If it doesn’t appear logout and login again.\nThe new API is roughly identical to the old API with two major exceptions:\nWe now need to replace usage of Push.getDeviceKey() with Push.getPushKey().\nWe thought about keeping the exact same API but eventually decided that creating a separate API will simplify\nmigration and allow you to conduct it at your own pace. All push methods now require the push token as their first argument. The old methods will push to the old push servers\nand the new identical methods that accept a token go to the new servers. To send a push directly to the new servers you can use very similar code to the old Java SE code we provided just\nchanging the URL, adding the token and removing some of the unnecessary arguments. Send the push to the\nURL https://push.codenameone.com/push/push which accepts the following arguments:\ntoken – your developer token to identify the account sending the push device – one or more device keys to send the push to. You can send push to up to 500 devices with a single push. type – the message type identical to the old set of supported types in the old push servers body – the body of the message auth – the Google push auth key production – true/false whether to push to production or sandbox environment in iOS certPassword – password for the push certificate in iOS push cert – http or https URL containing the push certificate for an iOS push E.g. we can send push to the new servers using something like this from Java SE/EE:\nURLConnection connection = new URL(\u0026quot;https://push.codenameone.com/push/push\u0026quot;).openConnection(); connection.setDoOutput(true); connection.setRequestMethod(\u0026quot;POST\u0026quot;); connection.setRequestProperty(\u0026quot;Content-Type\u0026quot;, \u0026quot;application/x-www-form-urlencoded;charset=UTF-8\u0026quot;); String query = \u0026quot;token=TOKEN\u0026amp;device=\u0026quot; + deviceId1 + \u0026quot;\u0026amp;device=\u0026quot; + deviceId2 + \u0026quot;\u0026amp;device=\u0026quot; + deviceId3 + \u0026quot;\u0026amp;type=1\u0026amp;auth=GOOGLE_AUTHKEY\u0026amp;certPassword=URL_ENCODED_CERTIFICATE_PASSWORD\u0026amp;\u0026quot; + \u0026quot;cert=URL_ENCODED_LINK_TO_YOUR_P12_FILE\u0026amp;body=\u0026quot; + URLEncoder.encode(MESSAGE_BODY, \u0026quot;UTF-8\u0026quot;) + \u0026quot;\u0026amp;production=false\u0026quot;; try (OutputStream output = connection.getOutputStream()) { output.write(query.getBytes(\u0026quot;UTF-8\u0026quot;)); } int c = connection.getResponseCode(); ... read response and parse JSON Unlike the previous API which was completely asynchronous and decoupled the new API is mostly synchronous\nso we return JSON that you should inspect for results and to maintain your device list. E.g. if there is an error\nthat isn’t fatal such as quota exceeded etc. you will get an error message like this:\n{\u0026quot;error\u0026quot;:\u0026quot;Error message\u0026quot;} A normal response though, will be an array with results:\n[ {\u0026quot;id\u0026quot;=\u0026quot;deviceId\u0026quot;,\u0026quot;status\u0026quot;=\u0026quot;error\u0026quot;,\u0026quot;message\u0026quot;=\u0026quot;Invalid Device ID\u0026quot;}, {\u0026quot;id\u0026quot;=\u0026quot;cn1-gcm-nativegcmkey\u0026quot;,\u0026quot;status\u0026quot;=\u0026quot;updateId\u0026quot; newId=\u0026quot;cn1-gcm-newgcmkey\u0026quot;}, {\u0026quot;id\u0026quot;=\u0026quot;cn1-gcm-okgcmkey\u0026quot;,\u0026quot;status\u0026quot;=\u0026quot;OK\u0026quot;}, {\u0026quot;id\u0026quot;=\u0026quot;cn1-gcm-errorkey\u0026quot;,\u0026quot;status\u0026quot;=\u0026quot;error\u0026quot; message=\u0026quot;Server error message\u0026quot;}, {\u0026quot;id\u0026quot;=\u0026quot;cn1-ios-iphonekey\u0026quot;,\u0026quot;status\u0026quot;=\u0026quot;inactive\u0026quot; }, ] There are several things to notice in the responses above:\nIf the response contains status=updateId it means that the GCM server wants you to update the device id to\na new device id. You should do that in the database and avoid sending pushes to the old key. iOS doesn’t acknowledge device receipt but it does send a status=inactive result which\nyou should use to remove the device from the list of devices. Update: It seems that APNS (Apple’s push service) returns uppercase key results. So you need\nto query the database in a case insensitive way.\nMoving Forward Right now the legacy push system still sends to its own push destination. We will redirect the old push servers\nto the new servers which will effectively mean that every push sent to the old push servers will go to the new\nservers and it should allow us to keep them up longer. However, we’ll eventually retire them as we will retire\nthe entire App Engine infrastructure so you should try to migrate at your own pace instead of rushing thru\nit at the last moment.\nWe are aware that for some corporate requirements push is strategically important so we are working on the ability\nto integrate with 3rd party push providers such as Urban Airship to provide scale for higher push volumes and\nbuiltin features for cross section/analytics. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJaanus Hansen — September 2, 2015 at 9:01 pm (permalink) Jaanus Hansen says:\nA stupid question – why we just can’t use Apple’s and Google’s push services? Why is it better to have one more constant connection up to use push services from CN1?\nShai Almog — September 3, 2015 at 3:39 am (permalink) Shai Almog says:\nIts only 1 instead of 3 (RIM too) and potentially more as we move forward (e.g. Amazon etc.).\nAPNS sucks, its really hard to work with and isn’t just a simple webservice.\nCarlos — September 10, 2015 at 5:56 pm (permalink) Carlos says:\nYou say:\ndevice – one or more device keys to send the push to. You can send push to up to 500 devices with a single push.\nHow can I do this with more than one device if I use cn1 ConnectionRequest instead of Java SE URLConnection?\nCan I pass the argument just like this?\n\u0026ldquo;\u0026amp;device=\u0026rdquo; + deviceId1 + \u0026ldquo;\u0026amp;device=\u0026rdquo; + deviceId2 + \u0026ldquo;\u0026amp;device=\u0026rdquo; + deviceId3\nShai Almog — September 11, 2015 at 3:58 am (permalink) Shai Almog says:\nYes. Notice that in the JavaSE code listed above I did just that.\nWim Bervoets — September 15, 2015 at 7:51 am (permalink) Wim Bervoets says:\nWhen will the old Push infrastructure stop working?\nWim\nShai Almog — September 15, 2015 at 1:38 pm (permalink) Shai Almog says:\nWe didn’t schedule this. We are looking at it as a multi-stage process:\n1 – make sure the new push infrastructure works and is robust\n2 – confirm this by making all of the old API push calls effectively redirect to the new servers (this will be seamless to guys using the old push servers but will demonstrate to us that the new push servers can handle the load).\n3 – Start migrating old API users and evaluate the transition process for everyone using the API.\nWe’re at stage 1 and haven’t scheduled stage 2 at this time. We’ll probably leave the compatibility layer running as long as we can but we have to migrate off of app engine eventually and we’ll try to do it when everyone finished the migration.\nSo you have plenty of time right now and I doubt we’ll shut them down in the next 6 months. I’ll consider it a success if we can make the entire migration in one year.\nGerben Kegel — February 16, 2016 at 11:51 am (permalink) Gerben Kegel says:\nIs there a reason why the response is not (always) valid JSON?\nShai Almog — February 17, 2016 at 3:33 am (permalink) Shai Almog says:\nBug. Can you give a specific example? We’ll fix those cases.\nGerben Kegel — February 17, 2016 at 9:17 am (permalink) Gerben Kegel says:\n[ {\u0026quot;id\u0026quot;=\u0026quot;deviceId\u0026quot;,\u0026quot;status\u0026quot;=\u0026quot;error\u0026quot;,\u0026quot;message\u0026quot;=\u0026quot;Invalid Device ID\u0026quot;}, {\u0026quot;id\u0026quot;=\u0026quot;cn1-gcm-nativegcmkey\u0026quot;,\u0026quot;status\u0026quot;=\u0026quot;updateId\u0026quot; newId=\u0026quot;cn1-gcm-newgcmkey\u0026quot;}, {\u0026quot;id\u0026quot;=\u0026quot;cn1-gcm-okgcmkey\u0026quot;,\u0026quot;status\u0026quot;=\u0026quot;OK\u0026quot;}, {\u0026quot;id\u0026quot;=\u0026quot;cn1-gcm-errorkey\u0026quot;,\u0026quot;status\u0026quot;=\u0026quot;error\u0026quot; message=\u0026quot;Server error message\u0026quot;}, {\u0026quot;id\u0026quot;=\u0026quot;cn1-ios-iphonekey\u0026quot;,\u0026quot;status\u0026quot;=\u0026quot;inactive\u0026quot; }, ]\nYou use = instead of : and not always doublequote the key (newId and message)\nShai Almog — February 18, 2016 at 3:27 am (permalink) Shai Almog says:\nThanks, this should be fixed now.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-push-servers/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-push-servers/push-megaphone.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are starting the complete overhaul of our push implementation that will allow us to deliver improved push\u003cbr\u003e\nrelated fixes/features and provide more reliability to the push service. When we designed our push offering\u003cbr\u003e\ninitially it was focused around the limitations of Google App Engine which we are finally phasing out. The new\u003cbr\u003e\nservers are no longer constrained by this can scale far more easily and efficiently for all requirements.\u003c/p\u003e","title":"New Push Servers"},{"content":"\nOn Thursday morning we rolled the cameras for chapter 2 of our exciting new webinar series. This time around there were far fewer (though not zero) technical issues, and we were able to share a productive hour of mobile app development in the company of our fellow coders.\nLast time, we built a social media app similar to Facebook. It highlighted how you can easily build REST client using Codename One. This time around we changed directions and built a game: Classic Flickr Concentration. Basically it is a matching game where you get a set of cards, and you tap them to flip them over. You just need to find the matches. My two-year-old daughter loves this game, by the way.\nHere is a 1-minute screen-cast of the game being played side-by-side on both an iPad Air 2, and a Nexus 5:\nAfter the tutorial, Clement Levallois spoke a little bit about CodApps and its upcoming bus tour around Europe to teach beginners how to build mobile apps.\nVideo of the Webinar A video recording of the webinar:\nAlternatively, the tutorial portion can be viewed here using Adobe Connect’s webinar viewer. This version allows you to experience the webinar almost like it was live. You can see the chats, and there are helpful book marks to navigate directly to parts of the tutorial that interest you.\nSource Code Get the full source code for the demo project from the github repo.\nYou can also download the android apk directly to try it on your device.\nWe Want Your Input Now that we have completed two webinars, we would are working on scheduling content further in advance. We will be holding them every two weeks and we’d like your input.\nWhat kinds of topics would you like to have covered?\nWould you like to share any of the work you’ve been doing? Do you have a cool app or sample that you have built in Codename One that you’d like to share? Let us know.\nI think we all had a good time talking and learning about Codename One. Hope to see you all there for the threequel. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nSteve Nganga — August 31, 2015 at 4:13 pm (permalink) Steve Nganga says:\nHi Steve….Great job there…We would like to see a tutorial where you are using native interfaces\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/java-mobile-dev-webinar-sequel-recap/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/java-mobile-dev-webinar-sequel-recap/webinar-header-graphic.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOn Thursday morning we rolled the cameras for chapter 2 of our exciting new webinar series. This time around there were far fewer (though not zero) technical issues, and we were able to share a productive hour of mobile app development in the company of our fellow coders.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/blog/java-mobile-dev-webinar-recap/\"\u003eLast time\u003c/a\u003e, we built a \u003ca href=\"https://github.com/shannah/social-network\" target=\"_blank\" rel=\"noopener noreferrer\"\u003esocial media app\u003c/a\u003e similar to Facebook. It highlighted how you can easily build REST client using Codename One. This time around we changed directions and built a game: \u003cstrong\u003eClassic Flickr Concentration\u003c/strong\u003e. Basically it is a matching game where you get a set of cards, and you tap them to flip them over. You just need to find the matches. My two-year-old daughter loves this game, by the way.\u003c/p\u003e","title":"Java Mobile Development Webinar 2: The Sequel"},{"content":"\nDeprecations We decided to discontinue support for building without a certificate, this support was added initially because\ngenerating an iOS certificate was so difficult and we wanted developers to see that \u0026ldquo;it works\u0026rdquo; before committing\nto the expense. However, this process is wrought with bugs that are often hard to trace back and error prone.\nAdded to that is the fact that we now have the new certificate wizard\nwhich makes the process simpler thus removing the final blocker (no need for a Mac).\nWe will block this functionality in the build servers by next week and thru the plugin after that.\nWe also decided to remove the ability to push with a null device id with the new push servers overhaul.\nIt was a tough decision to make but I’m sure you will get behind it when\nyou see the other features we intend to add specifically: delivery reports, status \u0026amp; batched pushes.\nWe’ll probably restore this functionality in the future in a different form that will allow other features such as\nsmart segmentations etc. The API will probably take a very different form and be designed for server side\nusage.\nLast but not least, we still kept the original web UI that Codename One used in the old appspot server. If you\nare still using that UI then it will be discontinued soon! We suggest you migrate to the new web UI in this\nwebsite.\nIf there are features or capabilities missing from the current web UI please let us know.\nBuild Hints in cn1libs Some cn1libs are pretty simple to install, just place them under the lib directory and refresh. However, many of the more\nelaborate cn1libs need some pretty complex configurations. This is the case when native code is involved where\nwe need to add permissions or plist entries for the various native platforms to get everything to work. This makes\nthe cn1lib’s helpful but less than seamless which is where we want to go.\nIf you don’t intend to write a cn1lib you can skip to the next section, for you this post just means that future cn1lib\ninstall instructions would no longer include build hints… However, if you are writing cn1libs then this is a pretty big\nnew feature…\nWe now support two new files that can be placed into the cn1lib root and exist when you create a new library using\nthe new project wizard: codenameone_library_required.properties \u0026amp; codenameone_library_appended.properties.\nIn these files you can just write a build hint as codename1.arg.ios.plistInject=... for the various\nhints. The obvious question is why do we need to files?\nThere are two types of build hints: required and appended. Required build hints can be something like ios.objC=true\nwhich we want to always work. E.g. if a cn1lib defines ios.objC=true and another cn1lib defines\nios.objC=false things won’t work since one cn1lib won’t get what it needs…\nIn this case we’d\nwant the build to fail so we can remove the faulty cn1lib.\nAn appended property would be something like codename1.arg.ios.plistInject=\u0026lt;key\u0026gt;UIBackgroundModes\u0026lt;/key\u0026gt;\u0026lt;array\u0026gt;\u0026lt;string\u0026gt;audio\u0026lt;/string\u0026gt; \u0026lt;/array\u0026gt;\nNotice that this can still collide e.g. if a different cn1lib defines its own background mode… However, there are\nmany valid cases where ios.plistInject can be used for other things. In this case we’ll append\nthe content of the ios.plistInject into the build hint if its not already there.\nThere are a couple of things you need to keep in mind:\nThis code happens with every \u0026ldquo;refresh libs\u0026rdquo; call not dynamically on the server. This means it should be pretty\nsimple for the developer to investigate issues in this process. Changing flags is problematic – there is no \u0026ldquo;uninstall\u0026rdquo; process. Since the data is copied into the codenameone_settings.properties\nfile. If you need to change a flag later on you might need to alert users to make changes to their properties essentially\nnegating the value of this feature… So be very careful when adding properties here. The rule of thumb is that a build hint that has a numeric or boolean value is always required. If an entry has a string that you can append with another string\nthen its probably an appended entry\nThese build hints are probably of the \u0026ldquo;required\u0026rdquo; type:\nandroid.debug\tandroid.release\tandroid.installLocation android.licenseKey\tandroid.stack_size android.statusbar_hidden android.googleAdUnitId android.includeGPlayServices android.headphoneCallback android.gpsPermission android.asyncPaint android.supportV4 android.theme android.cusom_layout1 android.versionCode android.captureRecord android.removeBasePermissions android.blockExternalStoragePermission android.min_sdk_version android.smallScreens android.streamMode android.enableProguard android.targetSDKVersion android.web_loading_hidden facebook.appId ios.keyboardOpen ios.project_type ios.newStorageLocation ios.prerendered_icon ios.application_exits ios.themeMode ios.xcode_version javascript.inject_proxy javascript.minifying javascript.proxy.url javascript.sourceFilesCopied javascript.teavm.version rim.askPermissions google.adUnitId ios.includePush ios.headphoneCallback ios.enableAutoplayVideo ios.googleAdUnitId ios.googleAdUnitIdPadding ios.enableBadgeClear ios.locationUsageDescription ios.bundleVersion ios.objC ios.testFlight desktop.width desktop.height desktop.adaptToRetina desktop.resizable desktop.fontSizes desktop.theme desktop.themeMac desktop.themeWin desktop.windowsOutput noExtraResources\tj2me.iconSize These build hints should probably be appended\nandroid.xapplication\tandroid.xpermissions\tandroid.xintent_filter\tandroid.facebook_permissions android.stringsXml android.style android.nonconsumable android.xapplication_attr android.xactivity android.pushVibratePattern android.proguardKeep android.sharedUserId\tandroid.sharedUserLabel\tios.urlScheme ios.interface_orientation ios.plistInject\tios.facebook_permissions ios.applicationDidEnterBackground ios.viewDidLoad ios.glAppDelegateHeader ios.glAppDelegateBody ios.beforeFinishLaunching ios.afterFinishLaunching ios.add_libs Theme Layering Theme layering is something that comes up often in support queries and we don’t have a good reference for it\nso I decided to write a quick tutorial on that.\nThere are two use cases in which you would want to use layering:\nYou want a slightly different theme in one platform You want the ability to customize your theme for a specific use case, e.g. let a user select larger fonts This is actually pretty easy to do and doesn’t require re-doing the entire theme. You can do something very similar\nto the cascading effect of CSS where a theme is applied \u0026ldquo;on top\u0026rdquo; of another theme. To do that just add a new\ntheme, make sure to remove the include native theme constant in the new theme. Then in the new theme define\nthe changes e.g. if you just want a larger default font define only that property for all the relevant UIID’s and ignore\nall other properties!\nFor a non-gui builder app the theme loading looks like this:\npublic void init(Object context) { try { theme = Resources.openLayered(\u0026quot;/theme\u0026quot;); UIManager.getInstance().setThemeProps(theme.getTheme(theme.getThemeResourceNames()[0])); } catch (IOException e) { e.printStackTrace(); } } Or for newer apps like this:\ntheme = UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;); You should fix it to look like this:\ntheme = UIManager.initNamedTheme(\u0026quot;/theme\u0026quot;, \u0026quot;Theme\u0026quot;); Notice, this assumes the name of your main theme is \u0026ldquo;Theme\u0026rdquo; (not the layer theme you just added). This is important\nsince the original code relies on the theme being in the 0 position in the theme name array which might not be\nthe case!\nThen when you want to add a layer just use:\nUIManager.getInstance().addThemeProps(theme.getTheme(\u0026quot;NameOfLayerTheme\u0026quot;)); The addThemeProps call will layer the secondary theme on top of the primary \u0026ldquo;Theme\u0026rdquo; and\nkeep the original UIID’s defined in \u0026ldquo;Theme\u0026rdquo; intact.\nFor a GUI builder app this is just as simple, you can override the initTheme method in the state machine in\nexactly the same way to specify the theme name explicitly:\nprotected void initTheme(Resources res) { UIManager.getInstance().setThemeProps(res.getTheme(\u0026quot;Theme\u0026quot;)); } Then use the addThemeProps anywhere you want, notice that you can just get the theme using\nfetchResourceFile() in the state machine.\nIf you apply theme changes to a running application you can use Form‘s refreshTheme()\nto update the UI instantly and provide visual feedback for the theme changes.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/deprecations-simplified-cn1lib-installs-theme-layering/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/deprecations-simplified-cn1lib-installs-theme-layering/ios-cert-wizard-blog-post-header.png\"\u003e\u003c/p\u003e\n\u003ch4 id=\"deprecations\"\u003eDeprecations\u003c/h4\u003e\n\u003cp\u003eWe decided to discontinue support for building without a certificate, this support was added initially because\u003cbr\u003e\ngenerating an iOS certificate was so difficult and we wanted developers to see that \u0026ldquo;it works\u0026rdquo; before committing\u003cbr\u003e\nto the expense. However, this process is wrought with bugs that are often hard to trace back and error prone.\u003cbr\u003e\nAdded to that is the fact that we now have the new \u003ca href=\"/blog/ios-certificate-wizard.html\"\u003ecertificate wizard\u003c/a\u003e\u003cbr\u003e\nwhich makes the process simpler thus removing the final blocker (no need for a Mac).\u003cbr\u003e\nWe will block this functionality in the build servers by next week and thru the plugin after that.\u003c/p\u003e","title":"Deprecations, Simplified cn1lib installs \u0026 Theme Layering"},{"content":"\nThe concept of threads in the Javascript community is a controversial one. The founders and leaders are dogmatically against threads, and have been from very early on. This 2007 article by Brendan Eich reveals his feeling on threads (they suck!) and the advancements in subsequent years seem to have followed this sentiment by vigorously avoiding anything thread-like.\nCountless \u0026ldquo;solutions\u0026rdquo; and workarounds have been developed by clever programmers to try to improve the situation without actually adding threads. Web Workers solve some concurrency issues, but don’t come close to solving the general case, and Promises are currently a popular way to make threadless code more readable. Now with ES6, we have generators and the yield statement offering yet a new ugly workaround for this glaring language omission. These are all ugly patches that make code less readable and less maintainable, not more.\nIn the olden days, Javascript was only used for adding a little interactivity to web pages so keeping it \u0026ldquo;thead-less\u0026rdquo; made sense. It reduced complexity and precluded the possibility of running into complex race conditions or dead-locks related to threading. Guess what, Javascript, it’s not the olden days anymore. Serious developers are building serious apps in Javascript now, and they are bending over backwards to work around this deficiency.\nNetflix talks a little bit about how they deal with asynchronous programming in this video. The first part of the video shows \u0026ldquo;the problem\u0026rdquo; – which includes race conditions, callback hell, etc… If you’ve developed anything of decent size in Javascript, you are well aware of these problems. Their solutions appear to be optimal considering Javascript’s lack of threads. But it just pains me to see everybody quite happy to jump through these hoops when the answer is staring them in the face. Just support threads!\nTeaVM is a Java to Javascript compiler that supports threads by using static analysis to cleverly convert the application into continuations. I have been using it quite a bit over the past few months (we are using it as a platform to port Codename One into Javascript), and it has just reminded me how nice it is to program synchronously.\nFor example any time you are writing a function that has to call a \u0026ldquo;slow\u0026rdquo; function, like making a network request, accessing local data (e.g. IndexedDB), you have to break it up into multiple callbacks in Javascript. Rather than having a single \u0026ldquo;black box\u0026rdquo; function that takes inputs and returns outputs, you have to consider whether that function will need to access any services that require a callback.\nConsider an example function that returns the current user’s age. Our first version might always have the user’s age stored in a variable so we don’t need to worry about callbacks\nfunction getAge() { return this.userAge; } So you build other parts of the app to depend on this function. Then one day, your requirements change, and you may need to load the age from a data source.\ne.g.\nfunction getAge() { if (this.userAge === -1) { self = this; requestUserAgeFromService(function(response) { self.userAge = response.age; }); } return this.userAge; } Well, the first time this is called, userAge won’t be initialized yet, so you need to jump through some hoops to make sure it’s loaded. For this reason, in Javascript, all APIs should really be written to use promises or callbacks JUST IN CASE you need to do something that you can’t do synchronously.\nLook at the same function in Java with TeaVM:\nint getAge() { if (userAge === -1) { userAge = requestUserAgeFromService(); } return userAge; } We don’t know what kind of stuff needs to happen under the hood of requestUserAgeFromService(), and we shouldn’t need to. It’s a black box. IMO this code is much more readable, and far easier to maintain than any solution involving promises, callbacks, generators – or ANY solution that can currently be used in Javascript.\nDuring the process of developing the Javascript port for Codename One, whenever I was adding a new feature, I would evaluate available Javascript APIs to see how best to achieve the feature. In many cases the APIs have required callbacks – because that’s how Javascript has to work. My first order of duty, then, is to write a synchronous wrapper API for the library so that I can use the code synchronously. This isn’t difficult using the built-in Java threading primitives like wait and notify. But the result is an API that is WAY easier to understand and maintain. And thus far more enjoyable to use.\nThis period of being able to build web apps with threading has spoiled me. I don’t think I can go back to just plain Javascript. The lack is just too present.\nIf you’re looking to build web apps that support threading, you can check out TeaVM and its related sub-project, Flavour, that provides bindings similar to Knockout and Angular. It’s not for every project, but once it reaches a certain size, being able to write code synchronously will pay dividends while providing a much more pleasant development experience. Codename One has supported threads from the beginning on every platform, and with the help of TeaVM we also support threads in the browser.\nI have been developing in both Java and Javascript for years, so needing to use Java to have threads is no big deal, but for Javascript developers it may be more of a \u0026ldquo;change\u0026rdquo; than they want. It is especially for those developers that Javascript needs to grow up and get threaded. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nBrendanEich — August 24, 2015 at 4:20 pm (permalink) BrendanEich says:\nThis post is out of date in many ways, and it misses the reasons why threads suck for JS as a language used by millions of programmers (data races without any proof system like Rust’s ownership/type system to make races static errors; races leaking into pure JS objects; easily-misused primitives meant for compilers and experts, not appropriate in the most widely used programming language on the planet). Have you been tracking the SharedArrayBuffer and Atomics work by Lars T. Hansen at Mozilla? Or WebAssembly?\nDogmatic equation of \u0026ldquo;threads\u0026rdquo; with \u0026ldquo;growing up\u0026rdquo; did not make the case. Compiling real C++ programs to asm.js did. SharedArrayBuffer and Atomics are not yet in standard JS, and even if they make it (which I think is likely; they’re on the agenda for the September TC39 meeting, but who knows?), they won’t be for almost all of the millions of hand-coding JS programmers. Because threads suck.\n/be\nshannah78 — August 24, 2015 at 5:27 pm (permalink) shannah78 says:\nThanks for commenting. Big fan of your work.\nI have to concede that threads are involved in most \u0026ldquo;newbie\u0026rdquo; mistakes in java. If I had a nickel for every time I had to point out \u0026ldquo;You’re modifying the UI off the EDT — big no-no\u0026rdquo;, I’d be … more wealthy than I am. And you might be right about threads not being needed by most Javascript developers. But…\n\u0026quot;\u0026quot;\u0026quot;\neasily-misused primitives meant for compilers and experts, not appropriate in the most widely used programming language on the planet\n\u0026quot;\u0026quot;\u0026quot;\nThis makes it sound like you have lower expectations of Javascript developers than other languages- as if JS is a training-wheel language that is only appropriate for newbies. I.e. don’t give them threads because they can’t handle threads. On the contrary, some of the best minds in the world are now working in Javascript for most of their productive hours. These guys can handle a few sharp objects.\nI do appreciate the caution in adding features that could confuse copy-paste coders, and things like SharedArrayBuffer/Atomics is definitely moving in the right direction. In fact due to this caution, Javascript is well positioned to add concurrency in a safe way.\nI’ve been doing some experimentation with parse.com cloud functions – which requires me to use server-side JS – and I find myself wincing as I write the code and then realize — oh , have to make another db call here…. ok.. let’s wrap this in another promise, and change the flow of the entire function to work with promises now. Enjoyment factor just tanks as soon as I have to do that.\nI am watching the progress of WASM with anticipation, and I fully expect that JS will add threads – or at least the basis upon which threads could be implemented at some time in the future. I’d just like to see it sooner than later. I still contend that threads (or at least concurrency with easily shared memory) are a feature of any \u0026ldquo;grown-up\u0026rdquo; language, and JS devs need the option of removing the training wheels from time to time.\nJason Mulligan — August 25, 2015 at 10:31 am (permalink) Jason Mulligan says:\nYou don’t need threads in your \u0026ldquo;core\u0026rdquo; reactor, but do you need to understand how to write code for the env/language. Use promises for IO, events for user interaction and stateless functions for the rest; you’ll do fine. IPC may seem undesirable, but it forces you to really think about what you’re doing.\nshannah78 — August 25, 2015 at 2:15 pm (permalink) shannah78 says:\nOf course you need to understand how to write code for the env/language. For JS you have three choices:\n1. All public APIs need to be written with return vals going to callbacks.\n2. All public APIs need to return promises.\n3. You may need to change the public API every time you make an implementation change due to the need to do some optional IO.\nSyntactically this results in the degradation of a nice language to a horrible kludge of functions chained together. StratifiedJS and TeaVM have good solutions for this – but it still seems laughable that everyone is happy with this status quo.\nOf course you don’t need threads. But that’s an argument in minimality. You don’t need objects, or functions, or arrays, or etc… either. They just make the language nicer to use.\nPromises and other reactive patterns for working asynchronously are all very clever developments by very smart people to solve a problem that shouldn’t need to be solved.\nJason Mulligan — August 25, 2015 at 2:47 pm (permalink) Jason Mulligan says:\n1. CSP\n2. Futures\n3. PEBCAK\nI disagree with the rest, as I can only assume you’ve trapped yourself with a way of thinking.\nshannah78 — August 25, 2015 at 3:03 pm (permalink) shannah78 says:\nThanks for the CSP ref. Wasn’t familiar with that one. Looks promising. PEBCAK must have been a self reference. Cheer up. It will be ok.\nBrendanEich — September 2, 2015 at 3:34 pm (permalink) BrendanEich says:\nI have appropriate expectations for most programmers of as widely used and heretofore single-threaded a language as JS is. The vast majority of JS programmers should not touch SharedArrayBuffer or Atomics, period, full stop — even if a few are expert enough to do so.\nWe can haggle about how tiny vs. minuscule the fraction representing those few is, but it’s very small.\n/be\nAlexey Andreev — September 4, 2015 at 4:14 am (permalink) Alexey Andreev says:\neasily-misused primitives meant for compilers and experts, not appropriate in the most widely used programming language on the planet\nThere are still developers that can and want to deal with threads. 99% of developers use frameworks, and remaining 1% write them. The problem that the latter ones need more \u0026ldquo;powerful\u0026rdquo; features of a language, and they usually (I belive) realize what are they doing. Example is: when I write business code for an enterprise application in Java using Spring, Hibernate, Servlet container, I don’t bother with threads at all. On the other hand I don’t bother with \u0026ldquo;asyncronous\u0026rdquo; nature of underlying infrastructure, because there is not asynchronousity at all. Consider the following code:\nfor (Role role : employee.getRoles()) {\nSystem.out.println(role.getName());\n}\nDependending on configuration, this code may cause additional SQL query. I mean getRoles method that may be marked as lazy association, so instead of returning simple ArrayList, it returns Hibernate implementation of List, which executes an SQL query as soon as data get fetches from the list the first time. So Hibernate end-user simply uses it without knowing how how Hibernate really works and when it makes SQL queries.\nI can’t do the same trick with callbacks or promises, since I first have to declare all of my associations, that might cause SQL queries during their resolution, as returning promises of lists (or sets) instead of simple list.\nCallbacks can be easily implemented with threads. Actor model can be easily implemented with threads. STM can be (not quite easily) implemented with threads. But according to my experience with implementing threads via callbacks in TeaVM, this is pain in the ass, requiring you to use advanced compiler hacker knowledge.\nthey won’t be for almost all of the millions of hand-coding JS programmers\nwhat about millions of Java programmers?\nAsmithdev — September 14, 2015 at 7:30 pm (permalink) Asmithdev says:\nI guess you’ve never heard of http://www.hamsters.io/\nAsmithdev — September 14, 2015 at 7:38 pm (permalink) Asmithdev says:\nThreads don’t suck with the use of the current web worker API and transferrable objects…although I do agree the API itself sucks on many levels the memory model makes threading extremely safe, I’m not entirely sure why people are unwilling to open their minds up to multithreading in JavaScript as the problem isn’t the language but rather lack of creativity and dedication to making them usable in a practical way. I wrote WebHamsters (http://hamsters.io) specifically for this very reason, the tools are freely available for use by anyone who cares to invest the time to learn them. I don’t know why you would throw the potential of 100’s of % performance improvements with automatic parallelization because something \u0026ldquo;sucks\u0026rdquo; on an idealogical level.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/javascript-get-threaded/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/javascript-get-threaded/html5-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe concept of threads in the Javascript community is a controversial one. The founders and leaders are dogmatically against threads, and have been from very early on. \u003ca href=\"https://brendaneich.com/2007/02/threads-suck/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eThis 2007 article by Brendan Eich\u003c/a\u003e reveals his feeling on threads (they suck!) and the advancements in subsequent years seem to have followed this sentiment by vigorously avoiding anything thread-like.\u003c/p\u003e\n\u003cp\u003eCountless \u0026ldquo;solutions\u0026rdquo; and workarounds have been developed by clever programmers to try to improve the situation without actually adding threads. Web Workers solve some concurrency issues, but don’t come close to solving the general case, and Promises are currently a popular way to make threadless code more readable. Now with ES6, we have generators and the yield statement offering yet a new ugly workaround for this glaring language omission. These are all ugly patches that make code less readable and less maintainable, not more.\u003c/p\u003e","title":"Javascript, Grow up and Get Threaded"},{"content":"\nWhen StartApp first launched a few years ago, they were a unique innovative new monetization channel to make money on Android.\nThe Android developer bundled their SDK and once the app was installed a new search shortcut would appear on the user’s device,\nthis allowed them to monetize on the search functionality.\nWe had a smart integration with StartApp, were the developer checked a CheckBox on the plugin and the SDK got bundled on the cloud build.\nThis unique new monetization channel was a hit.\nStartApp on VentureBeat 2 years ago\nBut it was a matter of time until Google will prohibit this from their platform, taking money from Google on Android with a different Search engine utility…\nWell, Google did changed their terms eventually and started banning apps from their play store with this integration.\nNowadays, StartApp has managed to recover and become a strong new innovative Ads network for iOS and Android.\nWe are now introducing a new cn1lib to allow you to monetize your apps using their channel.\nThe new integration is quite simple.\nFirst get yourself an account from their portal Create 2 apps on their portal – one for Android and another for iOS Grab the cn1lib from here Place the CN1StartApp.cn1lib under your projects lib folder Right click on your project and select \u0026ldquo;Codename One-\u0026gt;Refresh Libs\u0026rdquo; Now follow the Usage instructions here Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nugochukwu — August 24, 2015 at 4:15 pm (permalink) ugochukwu says:\nshai thanks for this great tutorial\nValeriy Skachko — January 11, 2016 at 2:07 pm (permalink) Valeriy Skachko says:\nHi Chen! I could not make integration.\nprivate StartAppManager manager;\n….\npublic void init(Object context) {\ntry{\nResources theme = Resources.openLayered(\u0026quot;/beer\u0026quot;);\nUIManager.getInstance().setThemeProps(theme.getTheme(theme.getThemeResourceNames()[0]));\n//init the startapp SDK\nmanager = new StartAppManager();\nmanager.initAndroidSDK(\u0026ldquo;000000000\u0026rdquo;, \u0026ldquo;00000000\u0026rdquo;, true);\n}catch(IOException e){\ne.printStackTrace();\n}}\n…\npublic void start() {\nmanager.loadAd(StartAppManager.AD_INTERSTITIALS);\n…\nmanager.showAd();\n}\nBut, receive on android device – An internal application error occurred: java.lang. AssertionError\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/startapp-integration/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/startapp-integration/startapp.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen StartApp first launched a few years ago, they were a unique innovative new monetization channel to make money on Android.\u003cbr\u003e\nThe Android developer bundled their SDK and once the app was installed a new search shortcut would appear on the user’s device,\u003cbr\u003e\nthis allowed them to monetize on the search functionality.\u003cbr\u003e\nWe had a smart integration with StartApp, were the developer checked a CheckBox on the plugin and the SDK got bundled on the cloud build.\u003c/p\u003e","title":"StartApp integration"},{"content":"\nA few weeks ago, in cooperation with Simon Fraser University’s School for Interactive Arts and Technology COOP office, I held a java mobile development workshop. This was a bit of an experiment to find out whether there was interest – plus it got me out of the code dungeon for a few hours :). As it turns out, SFU students do indeed have an appetite for learning, or for mobile development, or both. The workshop \u0026ldquo;sold\u0026rdquo; out within days of the initial email announcement.\nSince the workshop was being held in the SIAT (Interactive Arts \u0026amp; Technology) department, I didn’t know what level of Java experience the students would bring to the table, so I designed a program that maximized the use of the WYSIWYG GUI builder, and minimized custom code. As it turns out, nearly everyone that attended was familiar with and experienced with Java. Who knew that SIAT students were so well rounded 🙂\nThe Format and Content The workshop followed a strict tutorial format. Once the students were ready, and introductions had been made, we commenced development of a mobile application using Netbeans and Codename One. The source for the app are available on GitHub. It is a simple \u0026ldquo;tour guide\u0026rdquo; app for SFU, that allows users to find useful services at SFU.\nWhile the app, in this form, isn't all that useful since the content is hard-coded in Java and not connected to a database, it is a good starting point for developers who want to build this type of app. What I Learned As this was the first time doing this type of workshop, I didn’t really know what to expect going in, but I learned a lot from the experience. To anyone who is planning on holding similar workshops at a school or university, here are some suggestions:\nAsk questions in the sign-up form to gauge the participants’ experience level in the pertinent technologies. This will help you to customize the workshop content to the audience.\nDon’t just jump straight into a tutorial – even if that’s what students came for. Spend 10 minutes first on the big picture. Introducing the technology, showing samples of existing apps, etc. This helps to motivate the students and think beyond the simple introductory project that they will be working on through the rest of the workshop.\nMake the workshop as interactive as possible. Computing students don’t want to ask questions unless they absolutely have to. Even if they can’t get something working, they would rather not raise their hand. Do whatever you can throughout the workshop to keep the students engaged and provide them with pain-free ways to interact.\nOverbook and use Waiting List. For free tutorials like this everyone signs up, but there is no consequence for not showing up. As such, we sold out very quickly, but during the actual workshop there were empty seats. It is better to overbook, and use a waiting list for when even the \u0026ldquo;overbooking\u0026rdquo; gets filled. And make it clear that it will be first come first served. In this workshop, about 60% of people who signed up, actually showed up. I don’t know yet if this is typical, but for the next one I’ll be overbooking by 50%.\nFuture Workshops Much of the feedback from the first workshop was positive, and we plan to hold more in the future. Once piece of feedback that was common was that the content was \u0026ldquo;too easy\u0026rdquo;. I definitely underestimated the audience. Future workshops will therefore be more challenging.\nI’m located in the Vancouver, Canada area – which is why I did the workshop at SFU (I’m also an SFU grad, so that is another reason). If you would like me to hold a similar workshop in your school, and you are in the Vancouver area, please drop me a line.\nUntil then. Happy developing!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/sfu-mobile-development-workshop/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/sfu-mobile-development-workshop/sfu-workshop-jul-30.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA few weeks ago, in cooperation with \u003ca href=\"http://www.sfu.ca/siat.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eSimon Fraser University’s School for Interactive Arts and Technology\u003c/a\u003e \u003ca href=\"http://www.sfu.ca/coop/programs/iat/home.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCOOP office\u003c/a\u003e, I held a java mobile development workshop. This was a bit of an experiment to find out whether there was interest – plus it got me out of the code dungeon for a few hours :). As it turns out, SFU students do indeed have an appetite for learning, or for mobile development, or both. The workshop \u0026ldquo;sold\u0026rdquo; out within days of the initial email announcement.\u003c/p\u003e","title":"SFU Mobile Development Workshop"},{"content":"\nThe chat UI is what we’ve been working at and in todays post we are going to build exactly that!\nEven better…​ We’ll integrate with Pubnub to make the app almost fully functional as a rudimentary chat app, which\nis pretty spectacular. In this section we’ll cover UI, storage (externalization), Pubnub \u0026amp; its JSON API…​ We’ll\nalso use InteractionDialog to show notifications of incoming messages…​\nBefore we get started you will need to login to pubnub.com and sign up for an account\nwhere you will get two ID’s necessary when subscribing and pushing.\nWe also need to install the Pubnub cn1lib and its dependencies, place the following files in the lib directory\nunder the project hierarchy:\nBouncyCastleCN1Lib.cn1lib,\nPubnub-CodeNameOne-3.7.4.cn1lib \u0026amp;\njson.cn1lib.\nOnce you placed the files into the lib directory right click the project and select \u0026ldquo;Codename One→Refresh Libs\u0026rdquo;.\nThis will install the libraries into your classpath and allow you to use them while enjoying features such as code\ncompletion etc.\nYou will also need images for the chat bubbles specifically this one:\nAnd this one:\nTheme Changes We need to start by setting up the theme elements that we will use later on for the bubble chat, we effectively need the\ntwo speech bubbles mentioned above to map to the UIID’s BubbleMe \u0026amp; BubbleThem. So we start by adding the\ntheme element BubbleMe where we set transparency to 0 (since we will use an image border) and the foreground\ncolor to white ffffff:\nThen we need to set the padding for the speech bubble to the text won’t be on top of the speech arrow or the border\nitself. We set the padding in millimeters to keep the design portable and set 3mm on the left side to leave room\nfor the arrow:\nNow we need to cut the image border using the image border wizard and the chat-bubble-left.png image we\nmentioned earlier. Notice that we take the lines as close as possible to each other to make the border work:\nWe need to do the exact same thing for the BubbleThem UIID with the only difference being the chat-bubble-right.png\nand larger padding on the right side instead of the left side.\nThe Message Class Up until now we used mostly inner classes in a single file which makes things rather simple for a demo. But now\nwe’ll add a new Message class that will represent a message sent/received and encapsulate the JSON parsing\nlogic required for PubNub communication.\nThis class is Externalizeable which means we can store it into storage relatively easily. That’s important to keep\npast messages in the conversation in place:\npublic class Message implements Externalizable { private long time; private String senderId; private String recepientId; private String picture; private String name; private String message; /** * Required default constructor for externalizable to work... */ public Message() {} public Message(String senderId, String recepientId, String picture, String name, String message) { this.senderId = senderId; this.recepientId = recepientId; this.picture = picture; this.name = name; this.message = message; } public Message(JSONObject obj) { try { time = Long.parseLong(obj.getString(\u0026quot;time\u0026quot;)); senderId = obj.getString(\u0026quot;fromId\u0026quot;); recepientId = obj.getString(\u0026quot;toId\u0026quot;); message = obj.getString(\u0026quot;message\u0026quot;); name = obj.getString(\u0026quot;name\u0026quot;); picture = obj.getString(\u0026quot;pic\u0026quot;); } catch (JSONException ex) { // will this ever happen? Log.e(ex); } } public JSONObject toJSON() { JSONObject obj = createJSONObject(\u0026quot;fromId\u0026quot;, senderId, \u0026quot;toId\u0026quot;, recepientId, \u0026quot;name\u0026quot;, name, \u0026quot;pic\u0026quot;, picture, \u0026quot;time\u0026quot;, Long.toString(System.currentTimeMillis()), \u0026quot;message\u0026quot;, message); return obj; } /** * Helper method to create a JSONObject */ JSONObject createJSONObject(String... keyValues) { try { JSONObject o = new JSONObject(); for(int iter = 0 ; iter \u0026lt; keyValues.length ; iter += 2) { o.put(keyValues[iter], keyValues[iter + 1]); } return o; } catch(JSONException err) { // will this ever happen? err.printStackTrace(); } return null; } @Override public int getVersion() { return 1; } @Override public void externalize(DataOutputStream out) throws IOException { out.writeLong(time); Util.writeUTF(senderId, out); Util.writeUTF(recepientId, out); Util.writeUTF(picture, out); Util.writeUTF(name, out); Util.writeUTF(message, out); } @Override public void internalize(int version, DataInputStream in) throws IOException { time = in.readLong(); senderId = Util.readUTF(in); recepientId = Util.readUTF(in); picture = Util.readUTF(in); name = Util.readUTF(in); message = Util.readUTF(in); } @Override public String getObjectId() { return \u0026quot;Message\u0026quot;; } public long getTime() { return time; } public String getSenderId() { return senderId; } public String getRecepientId() { return recepientId; } public String getPicture() { return picture; } public String getName() { return name; } public String getMessage() { return message; } } This class is pretty simple, notice a few interesting things about externalization:\nWe use Util.writeUTF and Util.readUTF which adds support for null strings by writing/reading a boolean first\nto indicate if the value is null…​\ngetObjectId is a hardcoded string and not something like getClass().getName(). Using class name is a very\ncommon mistake which is why I’m mentioning it. It will work in the simulator and seem to work during development\nbut will fail with upgrades since class names are obfuscated on some devices and might result in serious problems.\nWe also need the default constructor for externalization support.\nGlobal Variables \u0026amp; Initialization To get started we need to add some global variables:\nprivate Pubnub pb; private Image roundedMeImage; private final WeakHashMap\u0026lt;String, EncodedImage\u0026gt; roundedImagesOfFriends = new WeakHashMap\u0026lt;\u0026gt;(); These should be pretty self explanatory, pubnub represents the API for push. The roundedMeImage is a cached\nversion of the image we created earlier. It allows us to reuse that UI element in different forms. The WeakHashMap\nallows us to cache pictures of friends without triggering a memory leak…​\nWe also need to add this to the init method:\npublic void init(Object context) { ... Util.register(\u0026quot;Message\u0026quot;, Message.class); ... } This effectively registers the Message class into the system so when we de-serialize it on loading we can recognize the\nclass. Developers often make the mistake of using the static initializer code in the class to register itself. That’s\nproblematic since the class might not be loaded before it is read.\nListening To Messages We’d like to start listening to incoming messages the moment we are logged in and this happens in the\nshowContactsForm so we can add this call to the top of that method:\nvoid showContactsForm(UserData data) { listenToMessages(); ... } private void listenToMessages() { try { pb = new Pubnub(\u0026quot;pub-c-*********-****-****-****-*************\u0026quot;, \u0026quot;sub-c-*********-****-****-****-*************\u0026quot;); pb.subscribe(tokenPrefix + uniqueId, new Callback() { @Override public void successCallback(String channel, Object message, String timetoken) { Display.getInstance().callSerially(() -\u0026gt; { respond(new Message((JSONObject)message)); }); } }); } catch(PubnubException err) { Log.e(err); Dialog.show(\u0026quot;Error\u0026quot;, \u0026quot;There was a communication error: \u0026quot; + err, \u0026quot;OK\u0026quot;, null); } } Subscribing to messages thru pubnub is trivial, we convert the JSON object received by response and send it to the method\nthat posts the response. Notice that we wrap the call in a call serially since the response is received off the EDT\nand processing it should probably be on the EDT as we will interact with the UI. We’ll get deeper into the response\nprocessing later…​\nPubNub works by providing message queues that you can subscribe to and publish to, imagine this like email\nwhere you can subscribe to a mailing list and handle incoming messages. However, if you aren’t listening a message\nmight be gone…​ They do provide an option for a persistent queue that will keep the last 100 messages for you which\ncan be very useful for this sort of app!\nThe architecture we are going to use is pretty simple, every person just listens on his own unique ID. That way\nto send a message to a specific person just publish to his queue and that person can reply by publishing to yours.\nWe include sender details in every message thus allowing us to distinguish among the people we are chatting with.\nThe Chat Form That’s a screenshot from a chat on my Android device…​ The chat form is created via this method which is a bit\nverbose but relatively simple.\nvoid showChatForm(ContactData d, Component source) { Form chatForm = new Form(d.name); // this identifies the person we are chatting with, so an incoming message will know if this is the right person... chatForm.putClientProperty(\u0026quot;cid\u0026quot;, tokenPrefix + d.uniqueId); chatForm.setLayout(new BorderLayout()); Toolbar tb = new Toolbar(); final Container chatArea = new Container(new BoxLayout(BoxLayout.Y_AXIS)); chatArea.setScrollableY(true); chatArea.setName(\u0026quot;ChatArea\u0026quot;); chatForm.setToolBar(tb); chatForm.setBackCommand(new Command(\u0026quot;Contacts\u0026quot;) { @Override public void actionPerformed(ActionEvent evt) { source.getComponentForm().showBack(); } }); // Provides the ability to swipe the screen to go back to the previous form SwipeBackSupport.bindBack(chatForm, (args) -\u0026gt; { return source.getComponentForm(); }); // Gets a rounded version of our friends picture and caches it Image roundedHimOrHerImage = getRoundedFriendImage(d.uniqueId, d.imageUrl); // load the stored messages and add them to the form java.util.List\u0026lt;Message\u0026gt; messages = (java.util.List\u0026lt;Message\u0026gt;)Storage.getInstance().readObject(tokenPrefix + d.uniqueId); if(messages != null) { for(Message m : messages) { if(m.getRecepientId().equals(tokenPrefix + uniqueId)) { respondNoLayout(chatArea, m.getMessage(), roundedHimOrHerImage); } else { sayNoLayout(chatArea, m.getMessage()); } } } // to place the image on the right side of the toolbar we just use a command that does nothing... Command himOrHerCommand = new Command(\u0026quot;\u0026quot;, roundedHimOrHerImage); tb.addCommandToRightBar(himOrHerCommand); // we type the message to the chat partner in the text field on the south side TextField write = new TextField(30); write.setHint(\u0026quot;Write to \u0026quot; + d.name); chatForm.addComponent(BorderLayout.CENTER, chatArea); chatForm.addComponent(BorderLayout.SOUTH, write); // the action listener for the text field creates a message object, converts it to JSON and publishes it to the listener queue write.addActionListener((e) -\u0026gt; { String text = write.getText(); final Component t = say(chatArea, text); // we make outgoing messages translucent to indicate that they weren't received yet t.getUnselectedStyle().setOpacity(120); write.setText(\u0026quot;\u0026quot;); final Message messageObject = new Message(tokenPrefix + uniqueId, tokenPrefix + d.uniqueId, imageURL, fullName, text); JSONObject obj = messageObject.toJSON(); pb.publish(tokenPrefix + d.uniqueId, obj, new Callback() { @Override public void successCallback(String channel, Object message) { // a message was received, we make it opauqe and add it to the storage t.getUnselectedStyle().setOpacity(255); addMessage(messageObject); } @Override public void errorCallback(String channel, PubnubError error) { chatArea.removeComponent(t); chatArea.revalidate(); Dialog.show(\u0026quot;Error\u0026quot;, \u0026quot;Connection error message wasn't sent\u0026quot;, \u0026quot;OK\u0026quot;, null); } }); }); chatForm.show(); } There are several things of interest in the above method:\nchatArea contains all the chat entries, notice we give it a name explicitly! This is useful later on, when a chat\nmessage arrives if we are in the chat form we’d like to add the message into that form…​\nWe use a client property on the chat form cid to store the user we are chatting with. That way if we are chatting\nwith a different contact an incoming message from another contact won’t get pushed into that conversation.\nThe chat area is scrollable and the text field is in the south. Notice that since we set the layout to border layout\nthe default scrollability of the form’s content pane was implicitly disabled.\nWe used a command that does nothing to place the image of the contact on the toolbar, its simpler than the effect\nwe had in the previous form but still pretty nice.\nWe load the existing messages if available from storage using the object externalization capability of the Storage\nclass.\nBy default we have a say and respond methods that encapsulate the bubble chat component creation. However,\nthey do a nice incoming animation that we don’t want when a new message arrives so we use a version that doesn’t\ndo the layout for both during construction of the form\nThis is all the code you need to work with PubNub! That’s pretty cool…​ Everything else is handled for us.\nThere are several important methods used by this method and we’ll go over them one by one:\nprivate Component say(Container chatArea, String text) { Component t = sayNoLayout(chatArea, text); t.setY(chatArea.getHeight()); t.setWidth(chatArea.getWidth()); t.setHeight(40); chatArea.animateLayoutAndWait(300); chatArea.scrollComponentToVisible(t); return t; } private Component sayNoLayout(Container chatArea, String text) { SpanLabel t = new SpanLabel(text); t.setIcon(roundedMeImage); t.setTextBlockAlign(Component.LEFT); t.setTextUIID(\u0026quot;BubbleMe\u0026quot;); chatArea.addComponent(t); return t; } These two methods essentially print out what we have to say as a chat bubble. The latter method just sets the span label\nicon to my picture (which we made previously) and aligns the block to the left. It also sets the bubble UIID we created\npreviously to the text portion of the span label.\nThe former method makes the bubble animate from the bottom by setting the size/location of the component and then doing an\nanimate layout that flows it into the right place.\nThe basic respond methods are practically identical with some minor changes:\nprivate void respond(Container chatArea, String text, Image roundedHimOrHerImage) { Component answer = respondNoLayout(chatArea, text, roundedHimOrHerImage); answer.setX(chatArea.getWidth()); answer.setWidth(chatArea.getWidth()); answer.setHeight(40); chatArea.animateLayoutAndWait(300); chatArea.scrollComponentToVisible(answer); } private Component respondNoLayout(Container chatArea, String text, Image roundedHimOrHerImage) { SpanLabel answer = new SpanLabel(text); answer.setIcon(roundedHimOrHerImage); answer.setIconPosition(BorderLayout.EAST); answer.setTextUIID(\u0026quot;BubbleThem\u0026quot;); answer.setTextBlockAlign(Component.RIGHT); chatArea.addComponent(answer); return answer; } The main difference here is the UIID and alignment to the right, also you will notice that we pass the image of the speaker\nas an argument since it might not be available…​\nBut the big difference is that those methods aren’t invoked for incoming chat entries directly, instead we use:\nprivate void respond(Message m) { String clientId = (String)Display.getInstance().getCurrent().getClientProperty(\u0026quot;cid\u0026quot;); addMessage(m); EncodedImage rounded = getRoundedFriendImage(m.getSenderId(), m.getPicture()); if(clientId == null || !clientId.equals(m.getSenderId())) { // show toast, we aren't in the chat form... InteractionDialog toast = new InteractionDialog(); toast.setUIID(\u0026quot;Container\u0026quot;); toast.setLayout(new BorderLayout()); SpanButton messageButton = new SpanButton(m.getMessage()); messageButton.setIcon(rounded); toast.addComponent(BorderLayout.CENTER, messageButton); int h = toast.getPreferredH(); toast.show(Display.getInstance().getDisplayHeight() - h - 10, 10, 10, 10); UITimer uit = new UITimer(() -\u0026gt; { toast.dispose(); }); uit.schedule(3000, false, Display.getInstance().getCurrent()); messageButton.addActionListener((e) -\u0026gt; { uit.cancel(); toast.dispose(); showChatForm(getContactById(m.getSenderId()), Display.getInstance().getCurrent()); }); } else { Container chatArea = getChatArea(Display.getInstance().getCurrent().getContentPane()); respond(chatArea, m.getMessage(), rounded); } } As you recall from the original subscribe call, this is the method invoked internally as a message arrives from pubnub.\nAt that point we are logged in but we might be in a chat with someone else or we might even be in the contacts form\nin one of those two cases the id will be either null or different to the current ID so we will show an interaction dialog effect\nthat you can see in the video below, otherwise we just invoke the regular respond method we saw above:\nThe interaction dialog is just a container placed on the layered pane. Because of that it doesn’t block input\nlike a regular dialog would, so if I’m chatting with someone when a message arrives this shouldn’t cause a problem.\nWe use a UITimer to automatically dispose of the dialog, the UITimer is convenient since its invoked on the EDT\nunlike a regular timer so the effort is minimal.\nWe use a button for the notification so we can click it and go directly to the chat window as is shown at the end of the\nvideo above.\nprivate Container getChatArea(Container cnt) { String n = cnt.getName(); if(n != null \u0026amp;\u0026amp; n.equals(\u0026quot;ChatArea\u0026quot;)) { return cnt; } for(Component cmp : cnt) { if(cmp instanceof Container) { Container cur = getChatArea((Container)cmp); if(cur != null) { return cur; } } } return null; } You’ll notice we used getChatArea above as a simple tool to abstract the chat area. We could also save the reference\nto chatArea in the class itself but that might risk a memory leak so this is simpler. I’m not too concerned about threads\nor race conditions since pretty much everything is on the EDT.\nprivate EncodedImage getRoundedFriendImage(String uid, String imageUrl) { EncodedImage roundedHimOrHerImage = roundedImagesOfFriends.get(uid); if(roundedHimOrHerImage == null) { roundedHimOrHerImage = URLImage.createToStorage(roundPlaceholder, \u0026quot;rounded\u0026quot; + uid, imageUrl, URLImage.createMaskAdapter(mask)); roundedImagesOfFriends.put(uid, roundedHimOrHerImage); } return roundedHimOrHerImage; } We mentioned this method much earlier, its relatively simple so I glossed over it. Its roughly identical to the \u0026ldquo;me picture\u0026rdquo;\nwe had in the previous posts just applied to pictures of friends.\nprivate void addMessage(Message m) { String personId; // if this is a message to me then store based on sender otherwise store based on recepient if(m.getRecepientId().equals(tokenPrefix + uniqueId)) { personId = m.getSenderId(); } else { personId = m.getRecepientId(); } java.util.List messages = (java.util.List)Storage.getInstance().readObject(personId); if(messages == null) { messages = new ArrayList(); } messages.add(m); Storage.getInstance().writeObject(personId, messages); } The last method of interest stores the message data into storage. We use an array list of messages which is pretty\nsimple.\nPotential Improvements Next time we’ll discuss push messages, in this version of the app messages that don’t arrive get lost…​ That’s a problem.\nFor that case we’ll use push notification from the OS to alert the other side.\nWe can also enable storage for the message queue thus allowing messages to remain cached until the next time the\nuser logs in.\nThere is also an issue if the user logs in from multiple devices he won’t see the chat history and one device\nwill grab incoming messages that might not reach another…​ This can be easily solved with a central database\narchitecture or possibly persistent queues in pubnub (although I don’t have experience there).\nOther potential improvements can be:\nFacebook’s invite friends and share buttons\nUnread count and icon badging for iOS\nNotification bar entries\nAttachments and more complex data\nAll of those should be pretty trivial. We’ll publish the full source code and the project with the next update of this\nseries and let you guys play with it.\nOther Posts In This Series This is a multi-part series of posts including the following parts:\nPart 1 – Initial UI\nPart 2 – Login With Google\nPart 3 – Login With Facebook\nPart 4 – The Contacts Form\nPart 5 – The Chat Form\nPart 6 – Native Push \u0026amp; Finishing Up\nYou can check out the final source code of this tutorial here. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nLanre Makinde — August 17, 2015 at 6:37 pm (permalink) Whoaoooooo. U guys are so far ahead. For you to despite your busy schedule have time for this kinda tutorials. Although I will wish to see login through twitter handled in your tutorial as well. Thanks great guys, great work.\nsalah Alhaddabi — November 19, 2016 at 1:34 pm (permalink) Dear Shai, I have tried the chat app up until now without the pubnub functionality. I have copied the exact same code from here and also missing pieces from gethub. When I use it on the simulator and clock on google login I login ok. But when I try to get friends I get an error even when the token is valid. I immediately get 400 error code when I try to use facebook login. I have tried the app on my android device S7 and I get a message the socialChat app has closed when I click on google login.\nShai Almog — November 20, 2016 at 6:13 am (permalink) Try running with the device connected with a cable and DDMS to see the output.\nsalah Alhaddabi — November 20, 2016 at 6:34 pm (permalink) Dear Shai,\nI have downloaded the apk file and start android studoi and opened the apk file in android studo and connected my samsung to PC with a USB cable but not sure what to do next as nothing appears in the console when the application fails. Can you please instruct me on how to go about this debugging??\nShai Almog — November 21, 2016 at 4:52 am (permalink) You don’t need to open the APK in Android studio. Just run the app as usual on the device and in android studio select the DDMS tool. This will open a special console on the bottom where you can pick your device and look thru the logs.\nsalah Alhaddabi — November 21, 2016 at 6:59 pm (permalink) Dear Shai,\nThis is what I get from the DDMS log when I run SocialChat.\nInitially after installing the app I get google login asking me to allow SocialChat to access my google account. Then I get transfered to the initial screen and stay on the login form without opening the contact form. The When I try to click again on the google login it tells me the \u0026ldquo;Unfortunately, SocialChat has stopped\u0026rdquo;. This is what I get when I try to do the google login again while connected my device through USB and use the DDMS tool:\n11-21 22:29:15.822: E/AndroidRuntime(27804): at com.codename1.social.GoogleImpl$a.a(GoogleImpl.java:187)\n11-21 22:29:15.822: E/AndroidRuntime(27804): at com.codename1.social.GoogleImpl$a.doInBackground(GoogleImpl.java:179)\nAs for the Facebook login, I login successfuly but the contact form is empty with no contacts loaded even though I am sure many of my contacts are online.\nYour help is much appreciated.\nShai Almog — November 22, 2016 at 4:49 am (permalink) As explained in the article Facebook doesn’t provide access to all your contacts. It only provides access to contacts who installed the app…\nThere is more output in the Google login which should probably clarify that. Also make sure you are building with API level 21 to workaround this issue: https://github.com/codename…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/building-a-chat-app-with-codename-one-part-5/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/building-a-chat-app-with-codename-one-part-5/chat-app-tutorial-chat-form-5.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe chat UI is what we’ve been working at and in todays post we are going to build exactly that!\u003c/p\u003e\n\u003cp\u003eEven better…​ We’ll integrate with Pubnub to make the app almost fully functional as a rudimentary chat app, which\u003cbr\u003e\nis pretty spectacular. In this section we’ll cover UI, storage (externalization), Pubnub \u0026amp; its JSON API…​ We’ll\u003cbr\u003e\nalso use \u003ccode\u003eInteractionDialog\u003c/code\u003e to show notifications of incoming messages…​\u003c/p\u003e\n\u003cp\u003eBefore we get started you will need to login to \u003ca href=\"http://www.pubnub.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003epubnub.com\u003c/a\u003e and sign up for an account\u003cbr\u003e\nwhere you will get two ID’s necessary when subscribing and pushing.\u003c/p\u003e","title":"Building A Chat App With Codename One Part 5"},{"content":"\nTuesday morning I held a webinar on Java mobile development using Codename One. First of all, I’d like to thank all who signed up and attended. Unfortunately there were some technical difficulties with the Webinar software that caused some major glitches. Double thanks to those who endured and stayed to the end. We’ve learned from this experience and we will do better in future webinars.\nSince most of the people who signed up for the webinar indicated that they had no experience with Codename One, I spent the first 10 minutes or so introducing the framework, and showing some demos of some existing apps to give participants an idea of the possibilities.\nThe rest of the presentation was spent building custom social media app similar to facebook. I created a simple PHP/MySQL server-side application before hand and deployed it on the internet so that the mobile app would be able to connect to it from anywhere in the world. Therefore, the finished result, is actually a usable social network – though it is only \u0026ldquo;demo\u0026rdquo; grade, and I’ll probably take it down in a few months.\nHere are some screenshots of the app:\nThe tutorial was structured like a cooking show, where I break the development of the app down into 12 \u0026ldquo;steps\u0026rdquo;. By the end of it we have a working app.\nSince there were technical difficulties with the actual webinar, I \u0026ldquo;refilmed\u0026rdquo; it afterwards using Screenflow, and I am quite happy with the results. It has been posted on YouTube here.\nAnd you can access the source of the app (both client and server) here.\nFinally, you can try out the app on Android here.\nThe Next Webinar In the next session, we will take this bare-bones, yet functional, social mobile app as a starting point and discuss ways to make it better. Since this is literally an app that was built in a day, there are obviously lots of low-hanging fruit that we can pick on. The agenda hasn’t been finalized, and the date isn’t set in stone, but it will be within the next two weeks, and some of the potential agenda items may include:\nImproving look and feel using styles, borders, and icons.\nAdding Push support so users will be notified when news is posted, or when they receive friend requests.\nImproving performance using various techniques including image compression, pre-sizing of images, network threads, and sprites.\nIntroducing Local storage for offline support.\nAdding chat support\nIf there are particular issues you would like to cover in the next webinar, please post them in the comments below, and I’ll see if I can incorporate them.\nThe Webinar Software For this webinar, I used GotoWebinar because I was familiar with GotoMeeting. Unfortunately there were some issues that make it less than a perfect fit for our needs. I’ve been reviewing Google Hangouts, and may try that out for the next one. If you have suggestions, I’m also interested in hearing what solutions you have used.\nHappy coding, and hope to see you all in the next session! Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nugochukwu — August 15, 2015 at 9:03 am (permalink) thanks for this great tutorial\nugochukwu — August 15, 2015 at 9:04 am (permalink) ugochukwu says:\ni would like you to put create group feature in the next webinar\nLanre Makinde — August 17, 2015 at 10:35 pm (permalink) Lanre Makinde says:\nI really love this. Very straight to the nitty gritty details. And i really love the fact that the next webinar is going to be within 2 weeks. What a resourceful way to spend my summer break. However, there are a lot of stuffs i could ask you to treat in the next webinar. Below are a list you may take your pick.\n1. Hybrid chats i.e. chat handling messages, pictures, video and audio sharing\n2. Other social platform logins such as twitter, yahoo, etc\n3. Can we have the location manager as a background service with a view to showcase a users/subscriber location accurately enough especially to showcase changes in geo coordinates.\n4. Status of chats/messsages/hybrid chats unread/unaccessed as well as a notification on of chat arrivals, etc\nThanks\nkilani rabah — February 2, 2016 at 1:13 pm (permalink) kilani rabah says:\nhow to solve his problem can ????:\nNo GUI Entries available\ninit:\nDeleting: C:UsersMoiDocumentsNetBeansProjectsCodenameOne6buildbuilt-jar.properties\ndeps-jar:\nUpdating property file: C:UsersMoiDocumentsNetBeansProjectsCodenameOne6buildbuilt-jar.properties\nCompile is forcing compliance to the supported API’s/features for maximum device compatibility. This allows smaller\ncode size and wider device support\ncompile:\nrun:\nfévr. 02, 2016 1:56:37 PM java.util.prefs.WindowsPreferences WARNING: Could not open/create prefs root node SoftwareJavaSoftPrefs at root 0x80000002. Windows RegCreateKeyEx(…) returned error code 5.\njava.lang.reflect.InvocationTargetException\nat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\nat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\nat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImp…:43)\nat java.lang.reflect.Method.invoke(Method.java:498)\nat com.codename1.impl.javase.Executor$1$[1.run](http://1.run)([Executor.java](http://Executor.java):75)\nat com.codename1.ui.Display.processSerialCalls(Display.java:1149)\nat com.codename1.ui.Display.mainEDTLoop(Display.java:966)\nat [com.codename1.ui.RunnableWr…](http://com.codename1.ui.RunnableWrapper.run)([RunnableWrapper.java](http://RunnableWrapper.java):120)\nat [com.codename1.impl.Codename…](http://com.codename1.impl.CodenameOneThread.run)([CodenameOneThread.java](http://CodenameOneThread.java):176)\nCaused by: java.lang.NullPointerException\nat com.mycompany.myapp.SocialNetwork.init(SocialNetwork.java:85)\n… 9 more\nJava Result: 1\nBUILD SUCCESSFUL (total time: 19 seconds)\nShai Almog — February 3, 2016 at 3:34 am (permalink) Shai Almog says:\nDid you create a GUI builder app or a handcoded app?\nThe default is to create a handcoded app and if so you need to select the GUI builder option explicitly.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/java-mobile-dev-webinar-recap/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/java-mobile-dev-webinar-recap/webinar-header-graphic.png\"\u003e\u003c/p\u003e\n\u003cp\u003eTuesday morning I held a webinar on Java mobile development using Codename One. First of all, I’d like to thank all who signed up and attended. Unfortunately there were some technical difficulties with the Webinar software that caused some major glitches. Double thanks to those who endured and stayed to the end. We’ve learned from this experience and we will do better in future webinars.\u003c/p\u003e\n\u003cp\u003eSince most of the people who signed up for the webinar indicated that they had no experience with Codename One, I spent the first 10 minutes or so introducing the framework, and showing some demos of some existing apps to give participants an idea of the possibilities.\u003c/p\u003e","title":"Java Mobile Development Webinar Recap"},{"content":"\nCodename One already has two separate socket APIs: a low-level API similar to java.net.Socket and a higher-level event-based approach. So why do we need WebSockets?\nHere are 3 reasons:\n1. Simplifies Server Code With low-level TCP sockets, you can’t just add a servlet to your existing Java web app to handle socket connections. You have to create your own server, and have it listen for connections on some custom port. You have to create your own sort of protocol. And all this just so you can pass messages.\nWith Web Sockets, you simply add an end point to your Java web app, and implement a few callbacks (e.g. onMessage(), onOpen(), onClose(), onError()), and you’re good to go.\nE.g. Here is the full code for server-side of the chat app demo:\n@ServerEndpoint(\u0026quot;/chat\u0026quot;) public class ChatDemoEndpoint { private static Set\u0026lt;Session\u0026gt; peers = Collections.synchronizedSet(new HashSet\u0026lt;Session\u0026gt;()); @OnMessage public String onMessage(Session session, String message) { System.out.println(session.getUserProperties()); if (!session.getUserProperties().containsKey(\u0026quot;name\u0026quot;)) { session.getUserProperties().put(\u0026quot;name\u0026quot;, message); return null; } for (Session peer: peers) { try { peer.getBasicRemote().sendText(session.getUserProperties().get(\u0026quot;name\u0026quot;)+\u0026quot;: \u0026quot;+message); } catch (IOException ex) { Logger.getLogger(ChatDemoEndpoint.class.getName()).log(Level.SEVERE, null, ex); } } return null; } @OnOpen public void onOpen(Session peer) { peers.add(peer); } @OnClose public void onClose(Session peer) { peers.remove(peer); } } The server just keeps a list of the open sessions, then it distributes messages received from any session to all sessions. Simple.\n2. Simplifies Client Code Codename One’s existing high-level sockets API, being event-based, already takes some of the nasties out of socket programming. But Web sockets are still simpler. The symmetry between the client and server APIs makes for a pleasant experience. Just implement the same callbacks in the client, and you’re in business. Passing messages between server and clients couldn’t be simpler.\nE.g. Here is the companion client code for the chat app demo:\nsock = new WebSocket(SERVER_URL) { @Override protected void onOpen() { System.out.println(\u0026quot;In onOpen\u0026quot;); } @Override protected void onClose(int statusCode, String reason) { } @Override protected void onMessage(final String message) { System.out.println(\u0026quot;Received message \u0026quot;+message); Display.getInstance().callSerially(new Runnable() { public void run() { if (chatContainer == null) { return; } SpanLabel label = new SpanLabel(); label.setText(message); chatContainer.addComponent(label); chatContainer.animateHierarchy(100); } }); } @Override protected void onError(Exception ex) { System.out.println(\u0026quot;in onError\u0026quot;); } @Override protected void onMessage(byte[] message) { } }; System.out.println(\u0026quot;Sending connect\u0026quot;); sock.connect(); This connects to the server using a url (just like any GET or POST request), then listens for messages from the server in the onMessage() method.\n3. Easier to Implement Cross-Platform Implementing low-level TCP sockets in the Javascript port looked like it would be challenging, at best, and possibly impossible. But I wanted to be able to write cross-platform apps in Codename One that use sockets – and I wanted to be able to deploy to the Javascript port. Since WebSockets are a first-class citizen in the web, adding support to the Javascript port was trivial.\nSince the websocket standard is now widely established and supported, it should be fairly easy to implement on other platforms as well. So far, I’ve implemented JavaSE, Android, iOS, and Javascript. Notably I’m missing Windows Phone, but it shouldn’t be hard to implement if a WinPhone developer wants to take on the challenge.\nIntegrating WebSockets in your Project Check out the cn1-websockets project for more information Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — December 19, 2017 at 12:33 pm (permalink) Francesco Galgani says:\nI’m starting to search information on Codename One WebSockets because this discussion:\nhttps://stackoverflow.com/q…\nI didn’t find information on WebSockets in the developer guide, but I found this page. Please note that the following page gives a 404 error: https://www.codenameone.com…\nShai Almog — December 20, 2017 at 6:33 am (permalink) Shai Almog says:\nThanks, I’ll remove that tag.\nWebSockets is an external cn1lib so it’s not in the developer guide. I hope to add a chapter covering important cn1libs such as websockets, google maps etc. at some point in the future. Currently the best up to date docs for websocket support are here: https://github.com/shannah/…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/introducing-codename-one-websocket-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/introducing-codename-one-websocket-support/html5-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One already has two separate socket APIs: \u003ca href=\"https://github.com/shannah/CN1Sockets\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ea low-level API\u003c/a\u003e similar to \u003ccode\u003ejava.net.Socket\u003c/code\u003e and \u003ca href=\"http://www.codenameone.com/blog/sockets-multiline-trees.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ea higher-level event-based approach\u003c/a\u003e. So why do we need WebSockets?\u003c/p\u003e\n\u003cp\u003eHere are 3 reasons:\u003c/p\u003e\n\u003ch3 id=\"1-simplifies-server-code\"\u003e1. Simplifies Server Code\u003c/h3\u003e\n\u003cp\u003eWith low-level TCP sockets, you can’t just add a servlet to your existing Java web app to handle socket connections. You have to create your own server, and have it listen for connections on some custom port. You have to create your own sort of protocol. And all this just so you can pass messages.\u003c/p\u003e","title":"Introducing Codename One WebSocket Support"},{"content":"\nThis tutorial is starting to get interesting…​. In this section we’ll go deep into animations, special effects, search\nstyling and extracting contacts. In the previous sections we built the first form of the app, logged in and now we\nneed to show the actual login form. Even more importantly we need to show it with style like this:\n(notice that you should see an animated gif above naturally we reduced quality to make it smaller but it still takes\na moment to load).\nWhat we see here is how the login form animates out by sliding out the buttons to the right then morphing the background\ninto the title area of the following form. We’ll get into how this is done soon enough…​ But first lets get the contact details!\nNew Contacts API First we need to add contact access permissions to the Google API by adding the line\n‘gc.setScope(\u0026ldquo;profile email https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.me\u0026rdquo;);’\ninto the initial login as such:\nloginWithGoogle.addActionListener((e) -\u0026gt; { tokenPrefix = \u0026quot;google\u0026quot;; Login gc = GoogleConnect.getInstance(); gc.setScope(\u0026quot;profile email https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.me\u0026quot;); gc.setClientId(\u0026quot;1013232201263-lf4aib14r7g6mln58v1e36ibhktd79db.apps.googleusercontent.com\u0026quot;); gc.setRedirectURI(\u0026quot;https://www.codenameone.com/oauth2callback\u0026quot;); gc.setClientSecret(\u0026quot;uvu03IXOhx9sO8iPcmDfuX3R\u0026quot;); doLogin(gc, new GoogleData()); }); We are effectively asking for more permissions. Notice that profile and email are shorthand syntax for the full URI\naccepted by Google and the values in the scope are separated by a space.\nTo make contacts access generic we changed a few things in the interfaces defined in the previous steps:\nstatic class ContactData { public String uniqueId; public String name; public String imageUrl; } First we added the simple contact data abstract class to represent a specific contact. Normally, we would just use\nsomething simpler but since Google \u0026amp; Facebook have radically different image sources we had to create two\ndifferent implementations of this class.\nstatic interface UserData { public String getName(); public String getId(); public String getImage(); public void fetchData(String token, Runnable callback); public ContactData[] getContacts(); } We only added one method to user data, the getContacts method. For simplicity we fetch all the contacts and do\nso synchronously. In a future iteration we might improve this by creating an implementation that \u0026ldquo;streams\u0026rdquo; the contacts\nbut for now we wanted something simple that will also lend itself well to search.\nGetting The Contacts On Google We connect to the Google webservice and get all visible contacts. Here we don’t have to limit ourselves to people\nwho installed the app and this gives us more information:\nprivate String token; @Override public ContactData[] getContacts() { ArrayList\u0026lt;ContactData\u0026gt; dat = new ArrayList\u0026lt;\u0026gt;(); ConnectionRequest req = new ConnectionRequest() { @Override protected void readResponse(InputStream input) throws IOException { JSONParser parser = new JSONParser(); Map\u0026lt;String, Object\u0026gt; parsed = parser.parseJSON(new InputStreamReader(input, \u0026quot;UTF-8\u0026quot;)); java.util.List\u0026lt;Object\u0026gt; data = (java.util.List\u0026lt;Object\u0026gt;)parsed.get(\u0026quot;items\u0026quot;); for(Object current : data) { Map\u0026lt;String, Object\u0026gt; cMap = (Map\u0026lt;String, Object\u0026gt;)current; String name = (String)cMap.get(\u0026quot;displayName\u0026quot;); if(name == null) { continue; } String type =(String)cMap.get(\u0026quot;objectType\u0026quot;); if(!type.equals(\u0026quot;person\u0026quot;)) { continue; } String id = cMap.get(\u0026quot;id\u0026quot;).toString(); ContactData cd = new ContactData(); cd.name = name; cd.uniqueId = id; if(cMap.containsKey(\u0026quot;image\u0026quot;)) { cd.imageUrl = (String)((Map\u0026lt;String, Object\u0026gt;)cMap.get(\u0026quot;image\u0026quot;)).get(\u0026quot;url\u0026quot;);; } dat.add(cd); } } }; req.setPost(false); req.setUrl(\u0026quot;https://www.googleapis.com/plus/v1/people/me/people/visible\u0026quot;); if(token == null) { token = Preferences.get(\u0026quot;googletoken\u0026quot;, (String)null); } req.addArgumentNoEncoding(\u0026quot;key\u0026quot;, token); NetworkManager.getInstance().addToQueueAndWait(req); ContactData[] cd = new ContactData[dat.size()]; dat.toArray(cd); return cd; } The code is a bit large but is in fact really simple, we get the Google token which we provide to the\nGoogle API to request the contacts list. We then do a synchronous call using addToQueueAndWait which is\nreally convenient in this case and add all the entries into an array list.\nNotice that we skip object types that aren’t \u0026ldquo;person\u0026rdquo;, in the Google+ API the pages you follow are also returned so\nits necessary to remove some redundant noise.\nThe JSON returned keeps all the contacts who are connected under the data property so we parse the JSON and\nget the array of friends from the items property. Then its just a matter of going over the contacts and constructing\na new contact object.\nGetting The Contacts From Facebook Facebook is pretty similiar, we need to query the Graph API for the users and iterate them. The current code only\ngets the first page of users hence its a bit flawed but it should be easily adaptable for paging thru the full result list.\nNotice that Facebook will only return the users that signed in to the app so while the result might list your hundreds of\nfriends you might still get a blank list if none of them signed into the app.\n@Override public ContactData[] getContacts() { ArrayList\u0026lt;ContactData\u0026gt; dat = new ArrayList\u0026lt;\u0026gt;(); ConnectionRequest req = new ConnectionRequest() { @Override protected void readResponse(InputStream input) throws IOException { JSONParser parser = new JSONParser(); Map\u0026lt;String, Object\u0026gt; parsed = parser.parseJSON(new InputStreamReader(input, \u0026quot;UTF-8\u0026quot;)); //name = (String) parsed.get(\u0026quot;name\u0026quot;); java.util.List\u0026lt;Object\u0026gt; data = (java.util.List\u0026lt;Object\u0026gt;)parsed.get(\u0026quot;data\u0026quot;); for(Object current : data) { Map\u0026lt;String, Object\u0026gt; cMap = (Map\u0026lt;String, Object\u0026gt;)current; String name = (String)cMap.get(\u0026quot;name\u0026quot;); if(name == null) { continue; } String id = cMap.get(\u0026quot;id\u0026quot;).toString(); ContactData cd = new ContactData(); cd.name = name; cd.uniqueId = id; cd.imageUrl = \u0026quot;http://graph.facebook.com/v2.4/\u0026quot; + id + \u0026quot;/picture\u0026quot;; dat.add(cd); } } }; req.setPost(false); req.setUrl(\u0026quot;https://graph.facebook.com/v2.4/me/friends\u0026quot;); if(token == null) { token = Preferences.get(\u0026quot;facebooktoken\u0026quot;, (String)null); } req.addArgumentNoEncoding(\u0026quot;access_token\u0026quot;, token); NetworkManager.getInstance().addToQueueAndWait(req); ContactData[] cd = new ContactData[dat.size()]; dat.toArray(cd); return cd; } This is almost identical to the Google version, the only differences are in the structure of the JSON returned and the URL’s.\nAdding The Things We Need To The Theme For the next section to work we need to add several multi-images to the theme using Quick Add Multi Image in the image\nmenu in the designer then picking \u0026ldquo;Very High\u0026rdquo; as the source image resolution. This will automatically adapt the image\nto all DPI’s.\nFirst we need rounded-mask.png:\nThis image will be used to convert square pictures into round images as my picture in the title area that you can see above.\nEffectively masking uses the black pixels to remove the corresponding pixels in the image while leaving the white pixels,\ngray pixels will remain translucent.\nThen we need rounded-border.png:\nWe will place this image underneath the mask image thus resulting in a border/shadow effect. This is important for\nappearance since the source image is downloaded from Facebook/Google etc. and might have a color clash with the\ntoolbar. That way we guarantee that the border will fit in with the toolbar.\nLastly we add the image that will be placed in the toolbar area social-chat-tutorial-image-top.jpg:\nNow that all the images are in place we need to add some UIID’s into the theme to support the additional components\nwe will use, first we start with the LargeIconFont UIID which is very similar to the IconFont UIID we introduced the\nlast time around, but it doesn’t override the foreground color and is sized at 4mm. This icon font is used in the body\nof the application so we want it to use the default colors so it will integrate properly, otherwise the white foreground\nof the standard icon font might vanish.\nWe’ll also add the rounded-border image as a UIID that we can apply to the actual image later by adding a UserImage\nUIID and setting the background image to rounded-border.png and the background behavior to scaled to fit. We\nalso need to set the transparency to 0 to make sure that the style is transparent.\nWe also want to make the TitleArea more controllable thru opacity. Currently its defined as an\nimage border which is problematic so we will change the border to be \u0026ldquo;Empty\u0026rdquo;, define the background color to\n5bc8fb and set the transparency to 255 which will give the same effect but allow us more control in the code.\nAnd finally MultiButton’s don’t have a clickable state in the default theme so we need to update their selected state to have 255 transparency (opaque) and have the background color 5bc8fb` which will provide us with a click effect.\nShowing The Contacts To show the contacts we will need several new UI elements and several new class variables so first lets define the new\nclass members that are needed for this:\nprivate String fullName; private String uniqueId; private String imageURL; private static EncodedImage userPlaceholder; private EncodedImage roundPlaceholder; private Image mask; private ContactData[] contacts; These members are defined in the main class and include images that we will use to show the individual entries and\ncreate a \u0026ldquo;rounding\u0026rdquo; mask to make the rounded picture effect on the title bar area. We also added a variable containing\nthe contacts array that we can use later in the code.\nTo initialize these variables we’ll use the init(Object context) method, of the main class right after the theme initialization.\nThis code happens only once per app execution and is a great place to load/initialize things. Notice that it should\nstill be a relatively fast method so don’t do heavy processing there otherwise app launch might be slowed down and the\nOS might kill your unresponsive app.\nStyle iconFontStyle = UIManager.getInstance().getComponentStyle(\u0026quot;LargeIconFont\u0026quot;); iconFontStyle.setBgTransparency(255); FontImage fnt = FontImage.create(\u0026quot; ue80f \u0026quot;, iconFontStyle); userPlaceholder = fnt.toEncodedImage(); mask = theme.getImage(\u0026quot;rounded-mask.png\u0026quot;); roundPlaceholder = EncodedImage.createFromImage(userPlaceholder.scaled(mask.getWidth(), mask.getHeight()).applyMask(mask.createMask()), false); fullName = Preferences.get(\u0026quot;fullName\u0026quot;, null); uniqueId = Preferences.get(\u0026quot;uniqueId\u0026quot;, null); imageURL = Preferences.get(\u0026quot;imageURL\u0026quot;, null); We are doing several interesting things here, we are defining the icon style to use the LargeIconFont UIID which\nallows us to create a scalable placeholder image. This is then used for two purposes in the code, placeholder for\npictures of our contacts (before the image is downloaded by URLImage) and for \u0026ldquo;my picture\u0026rdquo; (currently logged in user)\nin the title area. In the \u0026ldquo;my picture\u0026rdquo; case it will be rounded using the rounded-mask image mentioned above.\nThis line is pretty complex so lets break it down a bit:\nroundPlaceholder = EncodedImage.createFromImage(userPlaceholder.scaled(mask.getWidth(), mask.getHeight()).applyMask(mask.createMask()), false); What we do here is several different things, userPlaceholder.scaled(mask.getWidth(), mask.getHeight()) takes the\nuserPlaceholder and makes sure it matches the size of the mask perfectly. If it doesn’t we’ll get an exception.\nWe then take the mask image mask.createMask() and convert it to an internal representation. You might\nrecall from above that the mask image is this:\nSo the createMask method extracts these pixels and converts them to an internal representation that we can\nlater apply to an arbitrary image. This is a slightly expensive operation so we don’t recommend doing it often.\nWe then take the scaled image and apply the newly created mask onto the scaled image which generates\na round image with the call to applyMask.\nHowever, we need an instance of EncodedImage and not just a regular image so we use EncodedImage.createFromImage\nwith the false argument (indicating the image isn’t opaque) to convert the resulting placeholder to an encoded image.\nNotice that if the image is already an encoded image this method does nothing…​\nWe need an encoded image since later in the code we will use URLImage which expects EncodedImage, the\nEncodedImage is generally a more efficient way of storing images in terms of RAM and it allows us to get the image\ndata more effectively. It means the image PNG/JPEG data is still available…​ All standard/multi images returned form the resource\nfile are `EncodedImage’s which helps with memory utilization.\nNow that everything is in place we can start with the main method that shows the UI:\nvoid showContactsForm(UserData data) { Form contactsForm = new Form(\u0026quot;Contacts\u0026quot;); contactsForm.setLayout(new BoxLayout(BoxLayout.Y_AXIS)); // the toolbar is created into a layer on the content pane. This allows us to render behind it and leave it semi transparent Toolbar tb = new Toolbar(true); // we want the title area to be transparent so it won't get in the way contactsForm.getTitleArea().setUIID(\u0026quot;Container\u0026quot;); // folds the toolbar automatically as we scroll down, shows it if we scroll back up tb.setScrollOffUponContentPane(true); contactsForm.setToolBar(tb); // we want the image behind the toolbar to stretch and fit the entire screen and leave no margin Label titleLabel = new Label(\u0026quot; \u0026quot;); Style titleLabelStyle = titleLabel.getUnselectedStyle(); titleLabelStyle.setBgImage(theme.getImage(\u0026quot;social-chat-tutorial-image-top.jpg\u0026quot;)); titleLabelStyle.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); titleLabelStyle.setPadding(tb.getPreferredH(), tb.getPreferredH(), tb.getPreferredH(), tb.getPreferredH()); titleLabelStyle.setPaddingUnit(Style.UNIT_TYPE_PIXELS, Style.UNIT_TYPE_PIXELS, Style.UNIT_TYPE_PIXELS, Style.UNIT_TYPE_PIXELS); titleLabelStyle.setMargin(0, 0, 0, 0); contactsForm.addComponent(titleLabel); // the behavior of the title is rather complex so we extract it to a separate method tb.setTitleComponent(createTitleComponent(contactsForm)); InfiniteProgress ip = new InfiniteProgress(); contactsForm.addComponent(ip); loadContacts(data, ip, contactsForm.getContentPane()); // creates the morph and other animations from the main form to the second form of the app createMorphEffect(titleLabel); contactsForm.show(); } This is a relatively big method but it delegates most of the hard work to other methods so most of the stuff done\nhere isn’t very complex or even interesting. Here:\ncontacts.getTitleArea().setUIID(\u0026quot;Container\u0026quot;); We just make the title area transparent (since the Container UIID is always transparent), this allows us to style\nthe toolbar in a rather elaborate way in the createTitleComponent method.\nThis code:\nLabel titleLabel = new Label(\u0026quot; \u0026quot;); Style titleLabelStyle = titleLabel.getUnselectedStyle(); titleLabelStyle.setBgImage(theme.getImage(\u0026quot;social-chat-tutorial-image-top.jpg\u0026quot;)); titleLabelStyle.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); titleLabelStyle.setPadding(tb.getPreferredH(), tb.getPreferredH(), tb.getPreferredH(), tb.getPreferredH()); titleLabelStyle.setPaddingUnit(Style.UNIT_TYPE_PIXELS, Style.UNIT_TYPE_PIXELS, Style.UNIT_TYPE_PIXELS, Style.UNIT_TYPE_PIXELS); titleLabelStyle.setMargin(0, 0, 0, 0); Initializes the image behind the title:\nNotice we style it in code since we want it to be positioned in a very specific way and gain the size of the toolbar. Because\nof that we use the padding from the toolbar to set the size properly. Notice that we explicitly state the padding unit otherwise\nsome platforms which default to millimeter padding might end up out of whack.\nWe can do this sort of effect in several different ways but this specific approach with the \u0026ldquo;scaled to fill\u0026rdquo; option allows\nthe image to adapt nicely to device orientations without losing proportionality.\nThere are several methods used within this block, we will go thru them from the easiest to the hardest:\nprivate MultiButton createContactComponent(ContactData d) { MultiButton mb = new MultiButton(); mb.putClientProperty(\u0026quot;uid\u0026quot;, d.uniqueId); mb.setTextLine1(d.name); if(d.imageUrl != null) { mb.setIcon(URLImage.createToStorage(userPlaceholder, \u0026quot;userPic\u0026quot; + d.uniqueId, d.imageUrl, URLImage.RESIZE_SCALE_TO_FILL)); } else { mb.setIcon(userPlaceholder); } mb.addActionListener((e) -\u0026gt; { showChatForm(d, mb); }); return mb; } An entry within the contacts list is just a multi-button without much funfair, we place the uid as a client property using the\nputClientProperty call. This effectively allows us to place objects into a Map that exists within a Component that\nway later on in the code when the button click is handled we can invoke mb.getClientProperty(\u0026quot;uid\u0026quot;); and get the unique\nidentifier represented by the button. That’s great for decoupling the application logic from the UI.\nprivate void createMorphEffect(Label titleLabel) { // animate the components out of the previous form if we are coming in from the login form Form parent = Display.getInstance().getCurrent(); if(parent.getUIID().equals(\u0026quot;MainForm\u0026quot;)) { for(Component cmp : parent.getContentPane()) { cmp.setX(parent.getWidth()); } // moves all the components outside of the content pane to the right while fading them out over 400ms parent.getContentPane().animateUnlayoutAndWait(400, 0); parent.getContentPane().removeAll(); // we can't mutate a form into a component in another form so we need to convert the background to an image and then morph that // this is especially easy since we already removed all the components Label dummy = new Label(); dummy.setShowEvenIfBlank(true); dummy.setUIID(\u0026quot;Container\u0026quot;); dummy.setUnselectedStyle(new Style(parent.getUnselectedStyle())); parent.setUIID(\u0026quot;Form\u0026quot;); // special case to remove status bar on iOS 7 parent.getTitleArea().removeAll(); parent.setLayout(new BorderLayout()); parent.addComponent(BorderLayout.CENTER, dummy); parent.revalidate(); // animate the main panel to the new location at the top title area of the screen dummy.setName(\u0026quot;fullScreen\u0026quot;); titleLabel.setName(\u0026quot;titleImage\u0026quot;); parent.setTransitionOutAnimator(MorphTransition.create(1100).morph(\u0026quot;fullScreen\u0026quot;, \u0026quot;titleImage\u0026quot;)); } } The morph effect shows several effects when leaving the main form. Notice that it only applies when the main\nUI is the source of the transition, which makes sense for most cases. E.g. we will have a different effect when\ngoing back into the contacts form from a chat…​\nWe are showing two distinct effects here, in the first we animate the buttons outside of the screen, we do this by\nplacing them in their end location (outside of the screen to the right) then invoking the animateUnlayoutAndWait\nwhich is the opposite of animateLayoutAndWait. Its designed to show exit animations like this and effectively\nreturns the components to their proper layout positions then animates them out while optionally fading them.\nOnce the components are gone we remove them and then move the image into one big label and turn the UIID\nof the form to a standard form. This is necessary for the morph transition which can only morph elements and not\nthe form itself. Normally this \u0026ldquo;trick\u0026rdquo; would work seamlessly but on iOS we have a StatusBar UIID at the top of the form\nto push the application downwards and allow us to see the content of the status bar (battery etc.). A small hack\nallows us to temporarily remove that component if it exists and prevents a \u0026ldquo;bounce\u0026rdquo; in the transition.\nNext we name the source/destination components for the morph transition and set it to the parent form. That’s\nit, the morph transition does the rest of the work of animating the components into one another.\nThe title area of the form is a standard Toolbar, though instead of using a standard title we used a custom component\ncomprised of layers to create the special effect. The Toolbar still folds automatically as we scroll and provides\nall the standard effects. It also has a cool search feature that we will discuss in the next section.\nprivate Component createTitleComponent(Form parent) { // we want the toolbar to be completely transparent, since we created it on the layered pane (using the true // argument in the constructor) it will flow in the UI parent.getToolbar().setUIID(\u0026quot;Container\u0026quot;); // we create 3 layers within the title, the region contains all the layers, the encspsulate includes the \u0026quot;me image\u0026quot; // which we want to protrude under the title area layer Container titleRegion = new Container(new LayeredLayout()); Container titleEncapsulate = new Container(new BorderLayout()); Container titleArea = new Container(new BorderLayout()); // since the Toolbar is now transparent we assign the title area UIID to one of the layers within and the look // is preserved, we make it translucent though so we can see what's underneath titleArea.setUIID(\u0026quot;TitleArea\u0026quot;); titleArea.getUnselectedStyle().setBgTransparency(128); // We customize the title completely using a component, the \u0026quot;title\u0026quot; is just a label with the Title UIID Label title = new Label(parent.getTitle()); title.setUIID(\u0026quot;Title\u0026quot;); titleArea.addComponent(BorderLayout.CENTER, title); // the search button allows us to search a large list of contacts rather easily Button search = createSearchButton(parent, title, titleArea, titleRegion); // we package everything in a container so we can replace the title area with a search button as needed Container cnt = new Container(new BoxLayout(BoxLayout.X_AXIS)); titleArea.addComponent(BorderLayout.EAST, cnt); cnt.addComponent(search); // this is the Me picture that protrudes downwards. We use a placeholder which is then replace by the URLImage // with the actual image. Notice that createMaskAdapter allows us to not just scale the image but also apply // a mask to it... Label me = new Label(URLImage.createToStorage(roundPlaceholder, \u0026quot;userImage\u0026quot;, imageURL, URLImage.createMaskAdapter(mask))); me.setUIID(\u0026quot;UserImage\u0026quot;); // the search icon and the \u0026quot;me\u0026quot; image are on two separate layers so we use a \u0026quot;dummy\u0026quot; component that we // place in the search container to space it to the side and leave room for the \u0026quot;me\u0026quot; image Label spacer = new Label(\u0026quot; \u0026quot;); Container.setSameWidth(spacer, me); cnt.addComponent(spacer); Container iconLayer = new Container(new BorderLayout()); titleEncapsulate.addComponent(BorderLayout.NORTH, titleArea); titleRegion.addComponent(titleEncapsulate); titleRegion.addComponent(iconLayer); iconLayer.addComponent(BorderLayout.EAST, me); return titleRegion; } The search button encapsulates a lot of functionality, effectively it replaces the title with a TextField that allows\nus to type in a contact name. The cool part is the way in which we filter down the contacts to find the right entry\nthis is done using a data change listener and hiding the irrelevant entries dynamically.\nYou can see this animation in action in this short video:\nAll of this functionality is embedded directly into the code that creates the search button:\nprivate Button createSearchButton(Form parent, Label title, Container titleArea, Container titleRegion) { // we want the search feature to be based on the title style so it will \u0026quot;fit\u0026quot; but we need it to use the font defined // by the icon font UIID so we merge both Style s = new Style(title.getUnselectedStyle()); Style iconFontStyle = UIManager.getInstance().getComponentStyle(\u0026quot;IconFont\u0026quot;); s.setFont(iconFontStyle.getFont().derive(s.getFont().getHeight(), Font.STYLE_PLAIN)); FontImage searchIcon = FontImage.create(\u0026quot; ue806 \u0026quot;, s); FontImage cancelIcon = FontImage.create(\u0026quot; ue81e \u0026quot;, s); // this is the actual search button, but we don't want it to have a border... Button search = new Button(searchIcon); search.setUIID(\u0026quot;Label\u0026quot;); // the search box will be placed in the title area so we can type right into it. We make it look like a title but // explicitly align it to the left for cases such as iOS where the title is centered by default TextField searchBox = new TextField(); searchBox.setUIID(\u0026quot;Title\u0026quot;); searchBox.getUnselectedStyle().setAlignment(Component.LEFT); searchBox.getSelectedStyle().setAlignment(Component.LEFT); // the data change listener allows us to animate the data on every key press into the field searchBox.addDataChangeListener((type, index) -\u0026gt; { String text = searchBox.getText().toLowerCase(); if(text.length() \u0026gt; 0) { Dimension hidden = new Dimension(0, 0); // iterates over the components, if a component matches its set to visible and its size is kept as default // otherwise the component is hidden and set to occupy no space. for(Component cmp : parent.getContentPane()) { if(cmp instanceof MultiButton) { String l1 = ((MultiButton)cmp).getTextLine1(); if(l1.toLowerCase().indexOf(text) \u0026gt; -1) { cmp.setPreferredSize(null); cmp.setVisible(true); } else { cmp.setPreferredSize(hidden); cmp.setVisible(false); } } } } else { // no search string, show all the components by resetting the preferred size to default (thru null) and making them visible for(Component cmp : parent.getContentPane()) { cmp.setPreferredSize(null); cmp.setVisible(true); } } // update the UI with an animation effect parent.getContentPane().animateLayout(200); }); // the action event is invoked when the button is pressed, this can have 2 separate states: during search/before search search.addActionListener((e) -\u0026gt; { if(search.getIcon() == searchIcon) { // Starts the search operation by replacing the title with a text field and launching the native editing search.setIcon(cancelIcon); titleArea.replaceAndWait(title, searchBox, CommonTransitions.createCover(CommonTransitions.SLIDE_VERTICAL, true, 400)); titleRegion.revalidate(); Display.getInstance().editString(searchBox, searchBox.getMaxSize(), searchBox.getConstraint(), \u0026quot;\u0026quot;); } else { // if we are currently searching then cancel the search, return all items to visible and restore everything search.setIcon(searchIcon); for(Component cmp : parent.getContentPane()) { cmp.setPreferredSize(null); cmp.setVisible(true); } parent.getContentPane().animateLayoutAndWait(200); search.setEnabled(true); search.setVisible(true); titleArea.replaceAndWait(searchBox, title, CommonTransitions.createCover(CommonTransitions.SLIDE_VERTICAL, true, 400)); } }); return search; } That’s a bit of a large method but its functionality is relatively simple.\nLast but not least this is the method that actually loads the contacts into place:\nprivate void loadContacts(UserData data, InfiniteProgress ip, Container contactsContainer) { // we sort the contacts by name which is pretty concise code thanks to Java 8 lambdas Display.getInstance().scheduleBackgroundTask(() -\u0026gt; { contacts = data.getContacts(); CaseInsensitiveOrder co = new CaseInsensitiveOrder(); Arrays.sort(contacts, (ContactData o1, ContactData o2) -\u0026gt; { return co.compare(o1.name, o2.name); }); Display.getInstance().callSerially(() -\u0026gt; { if(recentContacts != null \u0026amp;\u0026amp; recentContacts.size() \u0026gt; 0) { Label recentHeader = new Label(\u0026quot;Recent\u0026quot;); recentHeader.setUIID(\u0026quot;ContactsHeader\u0026quot;); contactsContainer.addComponent(recentHeader); for(String cont : recentContacts) { ContactData d = getContactById(cont); contactsContainer.addComponent(createContactComponent(d)); } Label allHeader = new Label(\u0026quot;All Contacts\u0026quot;); allHeader.setUIID(\u0026quot;ContactsHeader\u0026quot;); contactsContainer.addComponent(allHeader); } contactsContainer.removeComponent(ip); for(ContactData d : contacts) { contactsContainer.addComponent(createContactComponent(d)); } contactsContainer.revalidate(); }); }); } There are several interesting things going on here.\nWe start by fetching and sorting the contacts in a low priority thread. We can just do something like new Thread()\nwhich would be pretty similar but scheduleBackgroundTask recycles an existing thread which is slightly more\nefficient.\nWe then return to the EDT using callSerially to add the components to the UI where we create an entry for\nevery component and revalidate to layout the UI\nThere is some code here for a \u0026ldquo;recent\u0026rdquo; entry which should priorities the contacts I’ve contacted recently, its\nfunctionality that’s added in the local code base but isn’t fully implemented.\nNext time we’ll discuss the chat UI.\nNote: The original post neglected to include the body of the loadContacts method.\nOther Posts In This Series This is a multi-part series of posts including the following parts:\nPart 1 – Initial UI\nPart 2 – Login With Google\nPart 3 – Login With Facebook\nPart 4 – The Contacts Form\nPart 5 – The Chat Form\nPart 6 – Native Push \u0026amp; Finishing Up\nYou can check out the final source code of this tutorial here. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nNigel Chomba — August 6, 2015 at 12:58 pm (permalink) I like this,i wish i could do this all day.Questions will come soon\nDiamond — August 6, 2015 at 3:34 pm (permalink) For the image placeholder, will it be possible to use fullName’s first character in Font Icon? For example, My name Diamond having \u0026ldquo;D\u0026rdquo; as the placeholder image just in case user doesn’t have a profile pic.\n\u0026ldquo;A small hack allows us to temporarily remove that component if it exists and prevents a \u0026ldquo;bounce\u0026rdquo; in the transition.\u0026rdquo; Are you referring to iOS status bar? If yes, any idea on how to temporarily hide the status bar?\nShai Almog — August 7, 2015 at 5:02 am (permalink) Sure. You can do this dynamically e.g. Map\u0026lt;character, encodedimage=\u0026quot;\u0026quot;\u0026gt; mm =…; Then use an Image.create(int, int, int) and get the graphics from it to draw the character on it. Cache it in the map so you don’t have to do this all the time…\nYes, the status bar. You can hide the entire title area by using getTitleArea().setPreferredSize(new Dimension(0, 0))); That will also hide the status bar.\n♫☆ Alex Goretoy ☭ ☁ — August 8, 2015 at 1:57 am (permalink) This is great! Thanks so much.\nugochukwu — August 12, 2015 at 9:41 am (permalink) shai am still desprately waiting for next series\nugochukwu — August 12, 2015 at 9:42 am (permalink) this is a great tutorial series! thanks somuch\nOmar Suleiman — March 6, 2017 at 5:42 pm (permalink) I want to ask about chat group room is supported with codename one, or one chat per application without allowing user to create new group and chatting.\nShai Almog — March 7, 2017 at 6:35 am (permalink) This specific demo is for 1 on 1 conversations but the platform has no such restrictions. Check out this post covering a 3rd party who built a pretty nice looking whatsapp clone using Codename One: https://www.codenameone.com…\nFrancesco Galgani — November 28, 2017 at 10:03 am (permalink) A simple question that is not related to the tutorial itself: how did you record the small video of the app? Thank you\nShai Almog — November 29, 2017 at 6:40 am (permalink) With Android it’s really easy. My device has a screen capture app that’s shipped by the vendor and allows recording video so this is really trivial (it’s an OPO with the original cyanogen so probably not applicable).\nBut all modern android devices allow you to capture video via ADB see https://developer.android.c…\nFor iOS I used to use Reflection but those a*holes essentially want to charge again for Relection II after I paid for 1. Turns out you don’t need that at all and it’s a huge waste!\nOn a Mac just connect the device and launch Quick Time. Then launch recording from quicktime and you will literally see the device screen and you can record everything then cut the parts of the video you want/don’t want. Very cool and useful!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/building-a-chat-app-with-codename-one-part-4/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/building-a-chat-app-with-codename-one-part-4/building-a-chat-app-tutorial-part-4.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThis tutorial is starting to get interesting…​. In this section we’ll go deep into animations, special effects, search\u003cbr\u003e\nstyling and extracting contacts. In the previous sections we built the first form of the app, logged in and now we\u003cbr\u003e\nneed to show the actual login form. Even more importantly we need to show it with style like this:\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Login UX\" loading=\"lazy\" src=\"/blog/building-a-chat-app-with-codename-one-part-4/chat-app-tutorial-contacts-form-1.gif\"\u003e\u003c/p\u003e\n\u003cp\u003e(notice that you should see an animated gif above naturally we reduced quality to make it smaller but it still takes\u003cbr\u003e\na moment to load).\u003c/p\u003e","title":"Building A Chat App With Codename One Part 4"},{"content":"\nWe’ve released a burst of small new features that piled up during the code freeze and release cycle, we also have a couple of interesting\n3rd party efforts such as an independent Windows Phone port and websockets implementation. But first lets start with\nFacebooks \u0026ldquo;invite friends\u0026rdquo; feature. Historically with the Facebook API you could just use the Graph API to query\nFacebook for the list of friends. This will return an empty list now and will only expose friends who are already using the\napp. You can use the standard share button or Facebook share both of which are great options to promote your app.\nHowever, Facebook also has a special native API allowing the user to invite his friends into the app…\nThe FacebookConnection class now has support for that feature, its a non-trivial feature and you will need to activate\nsome options within the Facebook application in order to fully utilize it but its a pretty powerful feature if you use\nFacebook login and want to promote your app socially.\nWindows Phone Port As you may recall, we are taking a \u0026ldquo;wait and see\u0026rdquo;\napproach for the future of the Windows Phone port based on MS’s historical flakyness when committing to\ntechnologies. However, some developers need to release a version to Windows Phone now and Fabricio who is one such developer\ntook it upon himself to improve the current port with some interesting results. You can check out his companies project\nhere.\nThere are several inherent problems that would be harder still to fix, they derive from the C# based port that relies on\nXMLVM. Since XMLVM was effectively discontinued and its C# backend was experimental at best it contains a\nlot of bugs that you might need to workaround. The proper solution would be to port the new VM built for iOS\nto Windows Phone, it was designed to be very portable so this should be relatively easy. It should also provide a\nnice performance boost, C# is pretty fast but the XMLVM layer on top isn’t as efficient as it should be due to language\ninconsistencies between C# and Java.\nIf you would like us to put more effort into Windows Phone support please signup as an enterprise account and\nmake your voice heard.\nWebsocket cn1lib \u0026amp; Chat Steve already released a\nsockets cn1lib a while back and\nhe just introduced a new websocket cn1lib\nyesterday!\nThe websockets standard is designed to provide the web generation of tools with the power/speed of socket\ncommunication without getting into some of the low level oddities of the TCP protocol. The really nice thing\nabout websockets, is that you can just program to it using a webserver with URL based notations which simplifies\na lot of the hassle you might have normally with socket programming.\nAs part of the release Steve also added a chat app that\ncommunicates between users. Its a really interesting approach and you might find it very useful if you want to\nintegrate chat functionality in your application.\nURLImage.createMaskAdapter Up until now the URLImage class only supported relatively simple adapters out of the box,\nspecifically scaling of various types. We now have a new API called URLImage.createMaskAdapter\nthat accepts a mask image. You can then apply this adapter to the URLImage creation and thus\napply a mask to the stored image. E.g. we use it in the chat app demo to create a circular image of the speaker.\nUtil Methods One of the most annoying pieces of code I write all the time is:\ntry { Thread.sleep(ms); } catch(InterruptedException e) {} I love checked exceptions but they are problematic when they are misused in cases where they make no sense at\nall (e.g. threads are never interrupted on iOS). So to reduce this pain we added two methods to Util:\nsleep(int) and wait(Object, int).\nThey do pretty much what you expect and don’t throw an exception with the added bonus in the case of wait where\nit implicitly declares the synchronized block for you removing the need for you to do that so you can\nconvert this:\ntry { syncronized(obj) { obj.wait(ms); } } catch(InterruptedException e) {} To:\nUtil.wait(obj, ms); Simplified Theme Initialization Up until now handcoded Codename One apps had a pretty standard set of boilerplate code:\ntry { theme = Resources.openLayered(\u0026quot;/theme\u0026quot;); UIManager.getInstance().setThemeProps(theme.getTheme(theme.getThemeResourceNames()[0])); } catch(IOException e){ e.printStackTrace(); } Its redundant since its rarely changed by users and when it is changed its usually with one purpose (setting\na specific theme). So rather than write all that code we now use:\ntheme = UIManager.initFirstTheme(\u0026quot;/theme\u0026quot;); Which is exactly the same block of code wrapped in a method.\nIf you want to explicitly specify the theme you can use\ntheme = UIManager.initNamedTheme(\u0026quot;/theme\u0026quot;, \u0026quot;MyTheme\u0026quot;); Which is still more concise and ignores the IOException which can’t be handled properly this\nearly in the app anyway.\nCaseInsensitiveOrder The String class in Java SE has a member comparator called String.CASE_INSENSITIVE_ORDER\nand that’s really useful when we want to do something like:\nContactData[] cnts = data.getContacts(); Arrays.sort(cnts, (ContactData o1, ContactData o2) -\u0026gt; { return String.CASE_INSENSITIVE_ORDER.compare(o1.name, o2.name); }); Which allows us to effectively sort an array or collection based on a string element very easily. However, having this\nin the String class is painful when we have to do it to multiple platforms. Furthermore this approach is\ninefficient since the object needs to be instantiated even when its unused so we’d rather not add something like\nthat to a mobile device platform where every KB counts.\nAs a result we decided to add the class CaseInsensitiveOrder which is effectively almost identical:\nContactData[] cnts = data.getContacts(); CaseInsensitiveOrder co = new CaseInsensitiveOrder(); Arrays.sort(cnts, (ContactData o1, ContactData o2) -\u0026gt; { return co.compare(o1.name, o2.name); }); Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFabrício Cabeça — August 3, 2015 at 4:52 pm (permalink) Fabrício Cabeça says:\nHi Shai, thanks for mentioning our efforts with the Windows port, we are working hard to make it fast, stable and feature complete. We do have an internal schedule for features like in-app purchase and facebook native integration and we plan to release some of our apps using this port in the near future. Any pro/enterprise user willing to help would be most welcome.\nftp27 — August 4, 2015 at 11:25 am (permalink) ftp27 says:\nThanks for WebSockets plugin!\nshannah78 — August 4, 2015 at 4:38 pm (permalink) shannah78 says:\nYour welcome 🙂 Your original comment mentioned that you were having trouble on iOS. Did you solve this?\nftp27 — August 5, 2015 at 8:17 am (permalink) ftp27 says:\nYes. This trouble has been associated with animate function in iOS. I replace this function to revalidate and all began worked fine. This was not associated with WebSockets.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/invite-friends-websockets-windows-phone-more/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/invite-friends-websockets-windows-phone-more/facebook-invite-friends.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve released a burst of small new features that piled up during the code freeze and release cycle, we also have a couple of interesting\u003cbr\u003e\n3rd party efforts such as an independent Windows Phone port and websockets implementation. But first lets start with\u003cbr\u003e\nFacebooks \u0026ldquo;invite friends\u0026rdquo; feature. Historically with the Facebook API you could just use the Graph API to query\u003cbr\u003e\nFacebook for the list of friends. This will return an empty list now and will only expose friends who are already using the\u003cbr\u003e\napp. You can use the standard share button or Facebook share both of which are great options to promote your app.\u003cbr\u003e\nHowever, Facebook also has a special native API allowing the user to invite his friends into the app…\u003c/p\u003e","title":"Invite Friends, WebSockets, Windows Phone \u0026 More"},{"content":"\nIn the previous section we went over the login with Google process, in this section we’ll go over the login with Facebook.\nAt this time we’ll skip the \u0026ldquo;invite friends\u0026rdquo; option since that is blog post all on its own and we can just add that functionality\nto the completed application.\nFacebook has a \u0026ldquo;get friends\u0026rdquo; API call that we can use, the downside of that is that it will only return our\nfriends that have already joined the app so we won’t be able to contact anyone on an arbitrary basis.\nGetting Started – Configuration Getting started with Facebook is pretty similar to the Google process and you can learn about it here.\nYou need to go to https://developers.facebook.com/apps/ and signup to create an application:\nYou need to repeat the process for web, Android \u0026amp; iOS (web is used by the simulator):\nFor the first platform you need to enter the app name:\nAnd provide some basic details:\nFor iOS we need the bundle ID which is the exact same thing we used in the Google+ login to identify the iOS app\nits effectively your package name:\nYou should end up with something that looks like this:\nThe Android process is pretty similar but in this case we need the activity name too.\nImportant: notice there is a mistake in the screenshot, the activity name should match the main class name followed\nby the word Stub (uppercase s). In this case it should be SocialChatStub.\nJust like on Google+ we need to generate a hash to verify that the app is indeed ours to Facebook and we do this\nusing the same keytool approach using the command line:\nkeytool -exportcert -alias (your_keystore_alias) -keystore (path_to_your_keystore) | openssl sha1 -binary | openssl base64 Lastly you need to publish the Facebook app by flipping the switch in the apps \u0026ldquo;Status \u0026amp; Review\u0026rdquo; page as such:\nProject Configuration We now need to set some important build hints in the project so it will work correctly. To set the build hints just right click the project\nselect project properties and in the Codename One section pick the second tab. Add these entries into the table:\nfacebook.appId=... The app ID will be visible in your Facebook app page in the top left position.\nThe Code So now that all of that is in place we would want it to work with our app…​\nAdd the event handling for logging in with Facebook as such:\nloginWithFacebook.addActionListener((e) -\u0026gt; { tokenPrefix = \u0026quot;facebook\u0026quot;; Login fb = FacebookConnect.getInstance(); fb.setClientId(\u0026quot;739727009469185\u0026quot;); fb.setRedirectURI(\u0026quot;http://www.codenameone.com/\u0026quot;); fb.setClientSecret(\u0026quot;-------\u0026quot;); doLogin(fb, new FacebookData(), false); }); Notice that the client ID, redirect, secret etc. are all relevant to the simulator login and won’t be used on Android/iOS\nwhere native Facebook login will kick into place.\nSimilarly to the Google+ implementation we’ll create a class to abstract the Facebook connection based on the interface\nwe defined the last time around:\nclass FacebookData implements UserData { String name; String id; @Override public String getName() { return name; } @Override public String getId() { return id; } @Override public String getImage() { return \u0026quot;http://graph.facebook.com/v2.4/\u0026quot; + id + \u0026quot;/picture\u0026quot;; } @Override public void fetchData(String token, Runnable callback) { ConnectionRequest req = new ConnectionRequest() { @Override protected void readResponse(InputStream input) throws IOException { JSONParser parser = new JSONParser(); Map\u0026lt;String, Object\u0026gt; parsed = parser.parseJSON(new InputStreamReader(input, \u0026quot;UTF-8\u0026quot;)); name = (String) parsed.get(\u0026quot;name\u0026quot;); id = (String) parsed.get(\u0026quot;id\u0026quot;); } @Override protected void postResponse() { callback.run(); } @Override protected void handleErrorResponseCode(int code, String message) { //access token not valid anymore if(code \u0026gt;= 400 \u0026amp;\u0026amp; code \u0026lt;= 410){ doLogin(FacebookConnect.getInstance(), FacebookData.this, true); return; } super.handleErrorResponseCode(code, message); } }; req.setPost(false); req.setUrl(\u0026quot;https://graph.facebook.com/v2.4/me\u0026quot;); req.addArgumentNoEncoding(\u0026quot;access_token\u0026quot;, token); NetworkManager.getInstance().addToQueue(req); } } This is really trivial code, we just connect to Facebooks Graph API and provide the token. From here on its\njust a matter of parsing the returned data which contains only two keys for the user name and the unique id\nwhich we can use later on when setting up a chat.\nThat’s it for Facebook login, next time we’ll get into accessing the contacts and showing the contacts form UI.\n__ | the original post discussed using the email address as the unique user ID which was the initial direction\nwe were going for. But we since decided to go in a different route with user ID’s (similar to the Facebook experience).\nWe also made some minor changes to error handling logic making the code more robust. Other Posts In This Series This is a multi-part series of posts including the following parts:\nPart 1 – Initial UI\nPart 2 – Login With Google\nPart 3 – Login With Facebook\nPart 4 – The Contacts Form\nPart 5 – The Chat Form\nPart 6 – Native Push \u0026amp; Finishing Up\nYou can check out the final source code of this tutorial here.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/building-a-chat-app-with-codename-one-part-3/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/building-a-chat-app-with-codename-one-part-3/facebook-login-blue.png\"\u003e\u003c/p\u003e\n\u003cp\u003eIn the previous section we went over the login with Google process, in this section we’ll go over the login with Facebook.\u003cbr\u003e\nAt this time we’ll skip the \u0026ldquo;invite friends\u0026rdquo; option since that is blog post all on its own and we can just add that functionality\u003cbr\u003e\nto the completed application.\u003c/p\u003e\n\u003cp\u003eFacebook has a \u0026ldquo;get friends\u0026rdquo; API call that we can use, the downside of that is that it will only return our\u003cbr\u003e\nfriends that have already joined the app so we won’t be able to contact anyone on an arbitrary basis.\u003c/p\u003e","title":"Building A Chat App With Codename One Part 3"},{"content":"Codename One 3.1 Release Notes Home 3.1 Release Notes Summary Version 3.1 is the first release in our fast pace release cycle of 4 releases per year. It brings stability, bug fixes and great new features to the table. The biggest highlights of this release are support for Java 8 and simplified certificate generation for iOS. Check out the list below for more details.\nHighlights - Click For Details Java 8 Language Features\nSupport for Java 8 features such as Lambdas, try with resources etc. This is a beta grade feature but is showing great promise so far.\nRead more about this work in this blog post.\niOS Certificate Wizard\nSimple generation of certificates and provisioning for itunes without a Mac using a wizard interface.\nRead more about this work in this blog post.\nAuthentication Framework\nProvides the ability to signin to various services in a generic way including builtin support for Google, Facebook and generic oAuth 2.0 services.\nRead more about this work in this blog post.\nFont Icons\nSupport for using icon fonts to represent images in the UI thus reducing the reliance on multi-images.\nRead more about this work in this blog post.\nBetter Crash Reporting\nAs part of migrating away from Google App Engine we shifted crash reports to use new servers which make them far more usable by embedding the logs directly into the email body. Read more about this work in this blog post.\nDetails Fixed issue #1460 - made methods of PurchaseCallback run on the EDT for Android Fixed issue #1465 - Error starting MyApplication5: Module \u0026lsquo;MyApplication5-10\u0026rsquo; has verification error 2924 at offset cac9 (codfile version 79) Fixed RFE #1477 - Added TextField password obfuscation on desktop builds Fixed issue #1457 - Validator is not re-enabling submit buttons Migrated the location of storage files to a new location Fixed issue #1479 - OAuth2 result access token processing causes StringIndexOutOfBoundsException Created native implementations for some of the heavier used String and StringBuilder methods for faster performance Fixed issue #1484 - IOS GLUImage.m Memory Leak Fixed issue #1410 - iOS: Animations still running while app is background Fixed RFE #1430 - Added support for instantly killing connections when kill() is called on them so that they don\u0026rsquo;t continue to block the queue. Fixed issue #1100 - FileSystemStorage.getLastModified() returns 0 on iOS Fixed issue #1424 - Failed to fetch address from contact on iOS Fixed String.indexOf() to allow for negative starting positions for the new VM Fixed issue #1231 - SQL errors now throw IOExceptions on iOS Fixed issue #1074 - virtual keyboard might scroll content behind statusbar on iOS7 Added arc() method to GeneralPath Fixed issue #1488 - OnOffSwitch for android not working Fixed problem with accessing static variables in the new VM Fixed GC issue with static objects such as arrays of strings or multi-dimension array Fixed issue #1470 - Auto-scrolling while dragging does not behave well Fixed String.toUpperCase()/toLowerCase() to work with non-ascii chars Fixed issue #1497 - Media Player Controls behavior on Android Fixed issue #1498 - null pointer exception when attach/detach bluetooth barcode scanner Fixed issue related to #1372 where NSString was failing silently on data with the wrong encoding Added macros CN1_YIELD_THREAD and CN1_RESUME_THREAD that an be used in native code that blocks and could potentially cause deadlocks with the GC thread Fix for issue #1505 - static final strings were removed from the GC but their internal char array was not Fix for issue #1481 - FlowLayout with setFillRows, true draws contained component (button) shifted to the right Added fireActionEvent to Calendar Deprecated cloud storage Fixed Socket available() always returning 0 on connectionEstablished() in iOS. Fixed issue #1513 removing attribute that might cause an issue with appstore submission Implemented Database.execute(String,Object[]) Fixed Database.execute to deal properly with null and blob parameters Fixed nullpointer exception on apps that support Push - but are built for a platform that does not support Push Fixed issue #1520 - admob shows black container Fixed the admob adview which stole the focus from the main view causing it to not paint properly Fixed issue #1425 - out of memory errors on iOS with large Multipart requests Made it possible to find the component matching a given command if applicable Fixed issue #1095 - Container.replace() with null transition does not update x, y, width and height of next component Fixed issue #1007 - position of back command wrong on first call to addCommand in SideMenuBar class Improved the general performance of String methods and HashMap elements. Fixed issue #1526 - Android port, recent updated build server, ConnectionRequest missing sent Content-Length while POST Fixed problem with arcs in the charts package on Android 4. Arcs were showing up distorted Changed the requestFocus to happen only when there are ads on the Form Fixed scrolling for forms with ChartComponent. Fixed label text size in charts. Fixed possible infinite loop in chart rendering Changed charts to use built-in arc function instead of using a path. Should improve performance on some platforms Fixed issue #1519 - Synchronized block deadlock after an exceptions on iOS Fixed catch all exception which wasn\u0026rsquo;t caught correctly using 0 instead of -1 class id Fixed exception pointer to point at the right location after an exception in a nested try/catch was thrown so if an exception was caught then rethrown it wasn\u0026rsquo;t caught in the correct catch statement and initially even caused a deadlock Removed deprecated maker package Simplified the java.util.Timer code on the iOS port to make it function more correctly Added a setChunkedStreamingMode API Fixed the infinite progress caching Fixed issue #1377 for regression with showing text fields in iPad on iOS 7 Fixed oauth2 to handle json token responses Fixed issue with fillArc in iOS Fix for issue with URLImage not working with ImageViewer Made force revalidate work more aggressively Fixed Issue #1540 - Network request is halted when the dialog cannot be shown up due to network problem. Made Container Iterable to allow for-each code such as for(Component cmp : cont) { \u0026hellip;. } Improved XML parser case sensitivity Fixed the app home path in the JavaSE port when the filesystem is exposed (desktop port) Fixed iOS drawArc to work for both negative and positive angles properly Added support for improved for each with XML element Modernized some XML processing code allowing for-each on entries Fixed issue with dup_x2 instruction not handling form 2 (where the \u0026lsquo;middle\u0026rsquo; word is a double or long) Updated facebook to version 4.4.0 and added inviteFriends ","permalink":"https://www.codenameone.com/codename-one-3-1-release-notes/","summary":"\u003ch1 id=\"codename-one-31-release-notes\"\u003eCodename One 3.1 Release Notes\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e3.1 Release Notes\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"summary\"\u003eSummary\u003c/h3\u003e\n\u003cp\u003eVersion 3.1 is the first release in our fast pace release cycle of 4 releases per year. It brings stability, bug fixes and great new features to the table. The biggest highlights of this release are support for Java 8 and simplified certificate generation for iOS. Check out the list below for more details.\u003c/p\u003e\n\u003ch3 id=\"highlights---click-for-details\"\u003eHighlights - Click For Details\u003c/h3\u003e\n\u003cp\u003eJava 8 Language Features\u003c/p\u003e","title":"Codename One 3.1 Release Notes"},{"content":"\nWe are thrilled to announce the immediate availability of Codename One 3.1!\nVersion 3.1 is the first release in our fast pace release cycle of 4 releases per year. It brings stability, bug\nfixes and great new features to the table. The biggest highlights of this release are support for Java 8 and simplified\ncertificate generation for iOS. Check out the list below for more details.\nHighlights Of The Release – Click For Details ____Java 8 Language Features\nSupport for Java 8 features such as Lambdas, try with resources etc. This is a beta\ngrade feature but is showing great promise so far.\nRead more about this work in this blog post.\n____iOS Certificate Wizard\nSimple generation of certificates and provisioning for itunes\nwithout a Mac using a wizard interface.\nRead more about this work in this blog post.\n____Authentication Framework\nProvides the ability to signin to various services in a generic way including builtin support for Google, Facebook and\ngeneric oAuth 2.0 services.\nRead more about this work in this blog post.\n____Font Icons\nSupport for using icon fonts to represent images in the UI thus reducing the reliance on multi-images.\nRead more about this work in this blog post.\n____Better Crash Reporting\nAs part of migrating away from Google App Engine we shifted crash reports to use new servers which make\nthem far more usable by embedding the logs directly into the email body.\nRead more about this work in this blog post.\nYou can also read the far more detailed list of release notes here. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — July 27, 2015 at 4:22 pm (permalink) Chidiebere Okwudire says:\nWell done guys!\nBTW, the ‘detailed list of release notes’ link is broken.\nShai Almog — July 27, 2015 at 4:30 pm (permalink) Shai Almog says:\nThanks, its updated now.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-3-1-now-live/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-3-1-now-live/CodenameOne-Horizontal.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are thrilled to announce the immediate availability of Codename One 3.1!\u003cbr\u003e\nVersion 3.1 is the first release in our fast pace release cycle of 4 releases per year. It brings stability, bug\u003cbr\u003e\nfixes and great new features to the table. The biggest highlights of this release are support for Java 8 and simplified\u003cbr\u003e\ncertificate generation for iOS. Check out the list below for more details.\u003c/p\u003e\n\u003ch3 id=\"highlights-of-the-release--click-for-details\"\u003eHighlights Of The Release – Click For Details\u003c/h3\u003e\n\u003cp\u003e____Java 8 Language Features\u003c/p\u003e","title":"Codename One 3.1 Now Live"},{"content":"\nIn the second part of this tutorial we will cover the login process for Google and getting a unique id. We’ll try to\nwrite generic code that we can later reuse for the Facebook login process. But first lets cover what \u0026ldquo;signing in\u0026rdquo;\nactually means…​\nWhen you handle your own user list and a user signs in thru registration, you can generally ask that user anything.\nHowever, when the user signs in thru Facebook, Google or any other service then you are at the mercy of that\nservice for user details…​ This is painfully clear with such services that don’t provide even an email address by\ndefault when logging in. It is sometimes accessible in Facebook but only for users who didn’t choose to hide it.\nWorse, one of the main reasons for using such a service is to access the contacts…​ However, Facebook no longer\nallows developers access to your Facebook friends. A Facebook app developer can only access the list of friends\nwho have the app installed and to accomplish that we will need to \u0026ldquo;invite\u0026rdquo; people to use/install the app.\nGetting Started – Configuration Pretty much everything discussed in this blog post is covered here.\nHowever, that is a rather general post so in this tutorial I’ll try to be more specific.\nStart by going to the the Google developer console: https://console.developers.google.com/\nCreate a new app by pressing the create button:\nJust enter the name of the app e.g. for this case its SocialChat and press \u0026ldquo;Create\u0026rdquo;:\nNow can select the API’s section where you should see the new project page:\nIn that project you should click the Google+ API in the \u0026ldquo;Social\u0026rdquo; section:\nIn the credentials section create a new client id, first we need to create one for a web application. This will be used by the simulator\nso we can debug the application on the desktop. It will also be used by ports for JavaScript, Desktop and effectively\neverything other than iOS \u0026amp; Android:\nThe consent screen is used to prompt users for permissions, you should normally fill it up properly for a \u0026ldquo;real world\u0026rdquo; application\nbut in this case we left it mostly empty for simplicities sake:\nWe now need to add Android/iOS native app bindings in much the same way as we did the web app\nTo build a native Android app make sure you setup the keystore correctly for your application. If you don’t have\nan Android certificate you can use our visual wizard or use the command line mentioned in our signing tutorial.\nNow that you have a certificate you need two values for your app, the first is the package name which must match\nthe package name of your main class (the one with the start, stop methods). It should be listed in the Codename One properties\nsection. Make sure to use a name that is 100% unique to you and using your own domain, don’t use the com.codename1 prefix or\nanything such as that…​\nYou also need the SHA1 value for your certificate, this is explained by Google here: https://developers.google.com/+/mobile/android/getting-started\nEffectively you need to run this command line:\n$ keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore -list -v This will prompt for a password then print several lines of data one of which should start with SHA1 that is the value\nthat you will need for the Android app.\nThe iOS app needs the same package name as the bundle id. It also needs the appstore id which you can get from\nitunes, it should appear as the prefix for your apps provisioning profile. If your app is correctly configured e.g.\nby using the Codename One certificate wizard, then you should see it in the project properties under the Codename One→iOS section.\nAfter everything is completed you should see something similar to this:\nProject Configuration We now need to set some important build hints in the project so it will work correctly. To set the build hints just right click the project\nselect project properties and in the Codename One section pick the second tab. Add these entries into the table:\nios.gplus.clientId=your ios client ID The Code So now that all of that is in place we would want it to work with our app…​\nFirst to make the code more generic we’ll define this interface that we can implement both for Facebook \u0026amp; Google\nthus generalizing the login code:\nstatic interface UserData { public String getName(); public String getId(); public String getImage(); public void fetchData(String token, Runnable callback); } The way this interface is meant to work, is that we would invoke fetchData after the login process completes to fetch\nthe data from Google/Facebook and then have name/id \u0026amp; image available to us.\nAlso notice that the fetchData is asynchronous and will invoke a callback when it completes. We could have made\nit synchronous and used invokeAndBlock.\nThe code that binds this to the button looks like this:\nloginWithGoogle.addActionListener((e) -\u0026gt; { tokenPrefix = \u0026quot;google\u0026quot;; Login gc = GoogleConnect.getInstance(); gc.setClientId(\u0026quot;1013232201263-lf4aib14r7g6mln58v1e36ibhktd79db.apps.googleusercontent.com\u0026quot;); gc.setRedirectURI(\u0026quot;https://www.codenameone.com/oauth2callback\u0026quot;); gc.setClientSecret(\u0026quot;-------------------\u0026quot;); doLogin(gc, new GoogleData(), false); }); Notice that we hid the client secrete and used the GoogleData class which is effectively the implementation of the\nUserData interface. The GoogleData class looks like this:\nclass GoogleData extends ConnectionRequest implements UserData { private Runnable callback; private Map\u0026lt;String, Object\u0026gt; parsedData; @Override public String getName() { return (String) parsedData.get(\u0026quot;displayName\u0026quot;); } @Override public String getId() { return parsedData.get(\u0026quot;id\u0026quot;).toString(); } @Override public String getImage() { Map\u0026lt;String, Object\u0026gt; imageMeta = ((Map\u0026lt;String, Object\u0026gt;) parsedData.get(\u0026quot;image\u0026quot;)); return (String)imageMeta.get(\u0026quot;url\u0026quot;); } @Override public void fetchData(String token, Runnable callback) { this.callback = callback; addRequestHeader(\u0026quot;Authorization\u0026quot;, \u0026quot;Bearer \u0026quot; + token); setUrl(\u0026quot;https://www.googleapis.com/plus/v1/people/me\u0026quot;); setPost(false); NetworkManager.getInstance().addToQueue(this); } @Override protected void handleErrorResponseCode(int code, String message) { //access token not valid anymore if(code \u0026gt;= 400 \u0026amp;\u0026amp; code \u0026lt;= 410){ doLogin(GoogleConnect.getInstance(), this, true); return; } super.handleErrorResponseCode(code, message); } @Override protected void readResponse(InputStream input) throws IOException { JSONParser parser = new JSONParser(); parsedData = parser.parseJSON(new InputStreamReader(input, \u0026quot;UTF-8\u0026quot;)); } @Override protected void postResponse() { callback.run(); } } Generally there isn’t all that much to the class. fetchData uses a connection request to connect to a URL in the\nGoogle+ API that returns details about the user when the token is set. These details are returned as a JSON string\nthat we then parse and set to the right variables.\nThe JSONParser class returns the JSON data as a tree of lists \u0026amp; maps that we can traverse thru to extract the data we need.\nOne value that might not be clear to the casual observer is the token, this is a string that contains a \u0026ldquo;key\u0026rdquo; to the users\naccount. Facebook/Google etc. keep the passwords for their users hashed in their database (effectively meaning\neven they don’t know the passwords), so to prove that we got permission from the user to access their data we\nget a unique token that looks like a long string of gibberish and we can use that when accessing their respective API’s\nthus validating ourselves. This is a very common practice…​ However, tokens expire occasionally and thus you might\nneed to \u0026ldquo;refresh\u0026rdquo; your token by logging in again as demonstrated in the next block of code.\nNow we can go to the actual login process which is generic for both Google \u0026amp; Facebook login thanks to the class above\nand the builtin abstractions in Codename One:\nprivate String fullName; private String uniqueId; private String imageURL; void doLogin(Login lg, UserData data, boolean forceLogin) { if(!forceLogin) { if(lg.isUserLoggedIn()) { showContactsForm(data); return; } // if the user already logged in previously and we have a token String t = Preferences.get(tokenPrefix + \u0026quot;token\u0026quot;, (String)null); if(t != null) { // we check the expiration of the token which we previously stored as System time long tokenExpires = Preferences.get(tokenPrefix + \u0026quot;tokenExpires\u0026quot;, (long)-1); if(tokenExpires \u0026lt; 0 || tokenExpires \u0026gt; System.currentTimeMillis()) { // we are still logged in showContactsForm(data); return; } } } lg.setCallback(new LoginCallback() { @Override public void loginFailed(String errorMessage) { Dialog.show(\u0026quot;Error Logging In\u0026quot;, \u0026quot;There was an error logging in: \u0026quot; + errorMessage, \u0026quot;OK\u0026quot;, null); } @Override public void loginSuccessful() { // when login is successful we fetch the full data data.fetchData(lg.getAccessToken().getToken(), ()-\u0026gt; { // we store the values of result into local variables uniqueId = data.getId(); fullName = data.getName(); imageURL = data.getImage(); // we then store the data into local cached storage so they will be around when we run the app next time Preferences.set(\u0026quot;fullName\u0026quot;, fullName); Preferences.set(\u0026quot;uniqueId\u0026quot;, uniqueId); Preferences.set(\u0026quot;imageURL\u0026quot;, imageURL); Preferences.set(tokenPrefix + \u0026quot;token\u0026quot;, lg.getAccessToken().getToken()); // token expiration is in seconds from the current time, we convert it to a System.currentTimeMillis value so we can // reference it in the future to check expiration Preferences.set(tokenPrefix + \u0026quot;tokenExpires\u0026quot;, tokenExpirationInMillis(lg.getAccessToken())); showContactsForm(data); }); } }); lg.doLogin(); } Now that’s a big block of code but it doesn’t really do that much. All it does is delegate to the UserData interface\nand validates the token. It also stores returned data and shows the next form (which we won’t cover right now).\nThe last piece of code for this section is a small utility method that we used for token expiration detection:\n/** * token expiration is in seconds from the current time, we convert it to a System.currentTimeMillis value so we can * reference it in the future to check expiration */ long tokenExpirationInMillis(AccessToken token) { String expires = token.getExpires(); if(expires != null \u0026amp;\u0026amp; expires.length() \u0026gt; 0) { try { // when it will expire in seconds long l = (long)(Float.parseFloat(expires) * 1000); return System.currentTimeMillis() + l; } catch(NumberFormatException err) { // ignore invalid input } } return -1; } This effectively allows us to detect if the token expired or not in a future execution of the app.\nNote: I’ve added the tokenPrefix variable which was missing in the original post, it allows differentiating between\na Google and Facebook login and the fact that it was missing caused some amusing bugs.\n__ | The original post discussed using the email address as the unique user ID which was the initial direction\nwe were going for. But we since decided to go in a different route with user ID’s (similar to the Facebook experience).\nWe also made some minor changes to error handling logic making the code more robust. We also changed the token expiration parsing logic to use a float value. __ Updated again to remove the gplay-service build hint which is no longer needed Other Posts In This Series This is a multi-part series of posts including the following parts:\nPart 1 – Initial UI\nPart 2 – Login With Google\nPart 3 – Login With Facebook\nPart 4 – The Contacts Form\nPart 5 – The Chat Form\nPart 6 – Native Push \u0026amp; Finishing Up\nYou can check out the final source code of this tutorial here. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nNigel Chomba — July 22, 2015 at 5:24 pm (permalink) i am following…..Great stuff co-founder\nFrancesco Galgani — February 4, 2018 at 2:32 pm (permalink) Are the information and code of this tutorial about Facebook login and Google login still valid?\nShai Almog — February 5, 2018 at 5:05 am (permalink) Should be. It’s a bit old so I’d like to refresh it eventually.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/building-a-chat-app-with-codename-one-part-2/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/building-a-chat-app-with-codename-one-part-2/google-sign-in.png\"\u003e\u003c/p\u003e\n\u003cp\u003eIn the second part of this tutorial we will cover the login process for Google and getting a unique id. We’ll try to\u003cbr\u003e\nwrite generic code that we can later reuse for the Facebook login process. But first lets cover what \u0026ldquo;signing in\u0026rdquo;\u003cbr\u003e\nactually means…​\u003c/p\u003e\n\u003cp\u003eWhen you handle your own user list and a user signs in thru registration, you can generally ask that user anything.\u003cbr\u003e\nHowever, when the user signs in thru Facebook, Google or any other service then you are at the mercy of that\u003cbr\u003e\nservice for user details…​ This is painfully clear with such services that don’t provide even an email address by\u003cbr\u003e\ndefault when logging in. It is sometimes accessible in Facebook but only for users who didn’t choose to hide it.\u003c/p\u003e","title":"Building A Chat App With Codename One Part 2"},{"content":"\nWe just entered code freeze preparing for the release of Codename One 3.1. This is a one week freeze that is scheduled to\nend on July 28th after the release of the new version. In the next week we will only be working on critical bugs for\nstability and won’t add new features.\nAfter the release of 3.1 we will start aiming for 3.2 currently scheduled for the end of October as part of our new 3 month\nrelease cycle.\nOur current stated plan for releases includes 3.1 for the 27th of July, 3.2 for the 27th of October and 3.3 for the 27th of January.\nAssuming this keeps working out nicely we will probably keep the 3 month release cycle going for the forseeable future. There is\none major feature we wanted to release in 3.1 but couldn’t get out the door in time. On the other hand the certificate\nwizard came in early and surprised us. This shows us that we can still deliver a substantive release within a 3 month cycle\nwithout compromising.\nOne of the big advantages of the short release cycle is that updating the developer guide becomes much easier.\nAs part of the 3.1 work we made quite a few updates to the developer guide and related documentation, it is now set to\n3.1 and includes sections covering many of the new features for Codename One have been updated.\nIn other news we updated the Facebook integration to include support for inviting friends which will enable some\ncommon use cases of interacting with Facebook friends. We fixed a rare crash with the new VM relating to an\nedge case usage of the dup2x bytecode. We’ll update the plugins for the various IDE’s later in the week in preparation\nfor the release.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codefreeze-for-3-1-news/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codefreeze-for-3-1-news/3.1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe just entered code freeze preparing for the release of Codename One 3.1. This is a one week freeze that is scheduled to\u003cbr\u003e\nend on July 28th after the release of the new version. In the next week we will only be working on critical bugs for\u003cbr\u003e\nstability and won’t add new features.\u003cbr\u003e\nAfter the release of 3.1 we will start aiming for 3.2 currently scheduled for the end of October as part of our new 3 month\u003cbr\u003e\nrelease cycle.\u003c/p\u003e","title":"Codefreeze For 3.1 \u0026 News"},{"content":"\nIn this tutorial we will cover the basics of building a good looking chat application with Codename One that\nwill work on all mobile OS’s. We will cover everything from design to social network login and the actual\nchat behavior. This tutorial is for a hand coded application mostly because GUI builder tutorials require video\nand are thus less searchable.\nThis project is created with the new Java 8 support to make the code simple and short.\nCreating The New Project We create a new Codename One project and select the new flat blue theme.\nOnce finish is clicked we have a new project in place, so we need some files to get started. First place the file\nfontello.ttf in the src directory. This font file contains image font icons which we will\nuse to provide icons in the UI.\nNext you will need to save this image to your hard drive for use in the first form.\nLogin UI Now that we have all the rest in order its time to launch the designer by double clicking the theme file. In the designer\nwe need to click the Images→Quick Add Multi Images option, then select the image you downloaded to the disk.\nWhen prompted leave the default of Very High, this will effectively create a multi image which stores the image\nin multiple different resolutions and deliver the properly sized image based on the device density at hand.\nNow we can just create the main form which is the entry point to the app, this will end up looking as such:\nTo achieve this we select the main theme and click the add button to add a new entry. We then type in MainForm\nin the top area and design the form:\nIn the first tab we uncheck ‘derive’ and select the type as IMAGE_SCALED_FILL. This effectively means we will\nuse an image as the background and scale it across the screen. We also make sure to select the multi image that\nwe just added.\nIn the Derive tab we uncheck derive (slightly confusing), then select Form in the combo box. This means that the\nMainForm style inherits the basic settings from the Form style.\nAdd another UIID called Padding so we can space the buttons away from the sides/bottoms of the form:\nIn the color tab uncheck the Derive Transparency and set the value to 0. This will make the container invisible.\nIn the padding section uncheck derive and enter 2 millimeters for all entries except for the bottom where we need 8 millimeters for extra spacing.\nThis will space out the various pieces, its important to use millimeters otherwise the result will be too different on various devices based\non their density.\nInitial Code In the code we open the main SocialChat class and replace the start method with this:\npublic void start() { if(current != null){ current.show(); return; } showLoginForm(); } private void showLoginForm() { Form loginForm = new Form(); // the blue theme styles the title area normally this is good but in this case we don't want the blue bar at the top loginForm.getTitleArea().setUIID(\u0026quot;Container\u0026quot;); loginForm.setLayout(new BorderLayout()); loginForm.setUIID(\u0026quot;MainForm\u0026quot;); Container cnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); cnt.setUIID(\u0026quot;Padding\u0026quot;); Button loginWithGoogle = new Button(\u0026quot;Signin with Google\u0026quot;); Button loginWithFacebook = new Button(\u0026quot;Signin with Facebook\u0026quot;); cnt.addComponent(loginWithGoogle); cnt.addComponent(loginWithFacebook); loginWithGoogle.addActionListener((e) -\u0026gt; { doLogin(GoogleConnect.getInstance()); }); loginWithFacebook.addActionListener((e) -\u0026gt; { doLogin(FacebookConnect.getInstance()); }); loginForm.addComponent(BorderLayout.SOUTH, cnt); loginForm.show(); } void doLogin(Login lg) { // TODO... } You will end up with something that looks like this:\nTo get the buttons to the right color we and add the icons we will need to go back to the designer…​.\nCustomizing The Buttons Lets start with the icons, since we use an icon font this is pretty easy…​ Just add a new style UIID to the theme called\nIconFont.\nIn the color section click Derive Foreground and type in ffffff to set the foreground to white, then click\nDerive Transparency and set it to zero.\nIn the Font tab uncheck the Derive flag and select the fontello.ttf font (make sure you downloaded it and placed it\nin the src directory as instructed earlier). Select the True Type Size as Large.\nTo get the buttons to work nicely we need to create an image border add 2 new UIID’s named LoginButtonGoogle \u0026amp;\nLoginButtonFacebook. Both should be identical with the exception of the color for the background…​\nIn the color tab set the foreground to ffffff and transparency to 0 (naturally uncheck derive in both cases).\nIn the Alignment tab uncheck derive and define the alignment as Center.\nIn the padding and margin tabs define all top/bottom/left/right paddings/margins to be 1 millimeter.\nIn the font tab define the system font to be large.\nIn the border section click the Image Border Wizard button. For the Facebook button enter 3B5999 to all the color fields\nfor the Google button enter DD4B39 to all the color fields. Increase the arc width/height to 15 and then move to the\nCut Image section. Enter 14 for the top/bottom/left \u0026amp; right values and press OK. This will effectively cut 9 multi images\nout of the given image and make a border out of them!\nIntegrating These Changes Now we can easily integrate the above changes in the code by just changing these lines:\nButton loginWithGoogle = new Button(\u0026quot;Signin with Google\u0026quot;); loginWithGoogle.setUIID(\u0026quot;LoginButtonGoogle\u0026quot;); Button loginWithFacebook = new Button(\u0026quot;Signin with Facebook\u0026quot;); loginWithFacebook.setUIID(\u0026quot;LoginButtonFacebook\u0026quot;); Style iconFontStyle = UIManager.getInstance().getComponentStyle(\u0026quot;IconFont\u0026quot;); loginWithFacebook.setIcon(FontImage.create(\u0026quot; ue96c \u0026quot;, iconFontStyle)); loginWithGoogle.setIcon(FontImage.create(\u0026quot; ue976 \u0026quot;, iconFontStyle)); These effectively assign the new UIID and create two icons with the given font defined within the icon font style!\nOther Posts In This Series This is a multi-part series of posts including the following parts:\nPart 1 – Initial UI\nPart 2 – Login With Google\nPart 3 – Login With Facebook\nPart 4 – The Contacts Form\nPart 5 – The Chat Form\nPart 6 – Native Push \u0026amp; Finishing Up\nYou can check out the final source code of this tutorial here. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nNigel Chomba — July 20, 2015 at 8:39 am (permalink) Lets move on Shai…..whats next?\nShai Almog — July 20, 2015 at 2:43 pm (permalink) We will post it when its ready.\nNigel Chomba — July 22, 2015 at 5:22 pm (permalink) Great sir\nMichael du Plessis — April 10, 2017 at 1:36 pm (permalink) I notice in the documentation that you recommend not using .getTitleArea().setUIID(\u0026ldquo;Container\u0026rdquo;); anymore because it allowed hacks.\nHow can we remove the TitleArea now?\nShai Almog — April 11, 2017 at 4:36 am (permalink) getTitleArea() is deprecated because it was used as getTitleArea().removeAll(); getTitleArea().addComponent(myCmp);\nThat was a hack we allowed in some cases but now that we have the toolbar it’s redundant \u0026amp; messy. Even when we allowed the hack it was discouraged because it relies too much on implementation details. However, setting the UIID doesn’t rely as much on the implementation details.\nYou can avoid this though by adding a UIID TitleArea and overriding the styling to make it transparent, without a border, padding or margin.\nMichael du Plessis — April 18, 2017 at 8:34 am (permalink) Ah I understand! Thank you for the explanation. I will also play around with the customisation of TitleArea within the Theme Editor.\nFrancesco Galgani — November 28, 2017 at 8:58 am (permalink) About \u0026ldquo;FontImage.create(\u0026rdquo; ue96c \u0026ldquo;, iconFontStyle)\u0026rdquo;, what is the meaning of \u0026quot; ue96c \u0026ldquo;? How is chosen or generated this string? Thank you.\nShai Almog — November 29, 2017 at 6:50 am (permalink) This tutorial was written before we had material design icons integrated into Codename One so I used the fontello fonts which include various icons. When you download a font from fontello you get an HTML with all the codes in the font. I explained this here: https://www.codenameone.com…\nFrancesco Galgani — December 1, 2017 at 6:21 pm (permalink) Francesco Galgani says:\nI’ve just seen that interesting tutorial, useful if I need custom icons not included in the material icons set. Thank you\nAhnaf Tahmeed — May 3, 2020 at 11:20 pm (permalink) Ahnaf Tahmeed says:\nDo I need to be a JAVA expert to go through this course …??\nShai Almog — May 4, 2020 at 6:03 am (permalink) Shai Almog says:\nNo. But you should know Java language syntax.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/building-a-chat-app-with-codename-one-part-1/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/building-a-chat-app-with-codename-one-part-1/chat-app-tutorial-part1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eIn this tutorial we will cover the basics of building a good looking chat application with Codename One that\u003cbr\u003e\nwill work on all mobile OS’s. We will cover everything from design to social network login and the actual\u003cbr\u003e\nchat behavior. This tutorial is for a hand coded application mostly because GUI builder tutorials require video\u003cbr\u003e\nand are thus less searchable.\u003c/p\u003e\n\u003cp\u003eThis project is created with the new Java 8 support to make the code simple and short.\u003c/p\u003e","title":"Tutorial: Building A Cross Platform Mobile Chat App for Android, iOS (iPhone) With Codename One Part I"},{"content":"\nIts been a busy month and getting busier by the moment, we are preparing for App Engines suspension of\nits blobstore service which will be coming around soon. This effectively means older crash report email\nfunctionality will be stopped for older apps (just rebuild the app for the emails to work again).\nWe are also getting ready for Codename One 3.1 which we have tentatively scheduled for July 27th. This\nrelease will include a weeks worth of code freeze and will be\nthe first of our new policy for faster release schedules.\nSome features we wanted to make it will have to go in to 3.2 but overall we are pretty thrilled with the shorter\nrelease cycle which makes a whole lot of sense in the mobile industry where things change so frequently.\nWe will release an updated plugin tomorrow morning which should include a lot of the newer features for 3.1.\nEasier Iteration on Containers I often write code that needs to iterate over the components of a container in the form:\nint count = cont.getComponentCount(); for(int iter = 0 ; iter \u0026lt; count ; iter++) { Component c = cont.getComponentAt(iter); // do something with c } This is tedious and annoying, so with the latest version of Codename One it implements the Iterable interface\nwhich allows this instead:\nfor(Component c : cont) { // do something with c } Which is obviously easier, its not necessarily as efficient but its easier to write. These are the sort of features\nwe should add into Codename One all over e.g. we just fixed Element from the XML parsing\ncode to allow iteration over its children in a similar way.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-3-1-easier-iteration/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-3-1-easier-iteration/3.1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIts been a busy month and getting busier by the moment, we are preparing for App Engines suspension of\u003cbr\u003e\nits blobstore service which will be coming around soon. This effectively means older crash report email\u003cbr\u003e\nfunctionality will be stopped for older apps (just rebuild the app for the emails to work again).\u003cbr\u003e\nWe are also getting ready for Codename One 3.1 which we have tentatively scheduled for July 27th. This\u003cbr\u003e\nrelease will include a weeks worth of code freeze and will be\u003cbr\u003e\nthe first of our new policy for faster release schedules.\u003c/p\u003e","title":"Codename One 3.1 \u0026 Easier Iteration"},{"content":"\nSo you have finished your app and tested it on the simulator. Everything looks good. You’re now ready to proceed with testing on your iPhone. You select the \u0026ldquo;Send iOS Debug Build\u0026rdquo; menu item and wait for the build server to work its magic, but then you’re faced with a notice that iOS builds require a valid certificate and provisioning profile. What a hassle!\nIf you’ve done any iOS development (not just Codename One) I’m sure you’ve hit this speed-bump before. You can’t just test your app on your iPhone. You have to jump through a series of hoops imposed by Apple before you get the privilege of testing your app on your phone. You need to create an App ID with the necessary permissions, generate a certificate signing request, download your certificates, generate mobile provisioning profiles to register your iPhone to be able to test your app. And finally, you have to export your certificates into a format that can be used in Codename One. If you have a Mac, this process is annoying at best. If you don’t, then this process might be your show-stopper.\nPersonally, I find the iOS certificate process to be the single most painful part of app development. That is why I’m happy to announce that the next version of the Codename One plugin will include a wizard that generates all of these things for you with just a few mouse clicks.\nHow it works To generate your certificates and profiles, simply open your project’s properties, and click on \u0026ldquo;iOS\u0026rdquo; in the left menu. This will show the \u0026ldquo;iOS Signing\u0026rdquo; panel that includes fields to select your certificates and mobile provisioning profiles.\nIf you already have valid certificates and profiles, you can just enter their locations here. If you don’t, then you can use the new wizard by clicking the \u0026ldquo;Generate\u0026rdquo; button in the lower part of the form.\nLogging into the Wizard After clicking \u0026ldquo;Generate\u0026rdquo; you’ll be shown a login form. Log into this form using your iTunes Connect user ID and password. NOT YOUR CODENAME ONE LOGIN.\nimage::/img/blog/ios-cert-wizard-2-login.png[Wizard login form]\nSelecting Devices Once you are logged in you will be shown a list of all of the devices that you currently have registered on your Apple developer account.\nSelect the ones that you want to include in your provisioning profile and click next.\nIf you don’t have any devices registered yet, you can click the \u0026ldquo;Add New Device\u0026rdquo; button, which will prompt you to enter the UDID for your device.\nDecisions \u0026amp; Edge Cases After you click \u0026ldquo;Next\u0026rdquo; on the device form, the wizard checks to see if you already have a valid certificate. If your project already has a valid certificate and it matches the one that is currently active in your apple developer account, then it will just use the same certificate. If the certificate doesn’t match the currently-active one, or you haven’t provided a certificate, you will be prompted to overwrite the old certificate with a new one.\nThe same \u0026ldquo;decisions\u0026rdquo; need to be made twice: Once for the development certificate, and once for the Apptore certificate.\nApp IDs and Provisioning Profiles The next form in the wizard asks for your app’s bundle ID. This should have been prefilled, but you can change the app ID to a wildcard ID if you prefer.\nInstalling Files Locally Once the wizard is finished generating your provisioning profiles, you should click \u0026ldquo;Install Locally\u0026rdquo;, which will open a file dialog for you to navigate to a folder in which to store the generated files.\nBuilding Your App After selecting your local install location, and closing the wizard, you should see the fields of the \u0026ldquo;iOS Signing\u0026rdquo; properties panel filled in correctly. You should now be able to send iOS debug or Appstore builds without the usual hassles.\nFuture Improvements This wizard is just the next step in our mission to simplify the app-development process. In the next while we’ll be rolling out more features like this. Some planned features include push certificate generation and Appstore uploads. If there are particular aspects of the app development and deployment process that you still find cumbersome, make sure to let us know so we can work on finding solutions.\nScreencast If you want to see the wizard in action, you can check out this 2 minute screencast. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — July 19, 2015 at 1:10 pm (permalink) Great work, guys! I’ll try this out in the coming weeks\nLukman Javalove Idealist Jaji — July 20, 2015 at 8:23 am (permalink) Why do we have to select devices? Is that for testing purposes only?\nShai Almog — July 20, 2015 at 2:43 pm (permalink) Yes. Apple allows running on up to 100 devices and you need to add them to your account as testers.\nClement Levallois — July 23, 2015 at 8:36 am (permalink) After selecting my device and clicking on Next I get an error saying that my session has expired and I should login again? See pic attached\nshannah78 — July 23, 2015 at 1:17 pm (permalink) Not sure yet what would cause that. If you log into your Apple developer account are there any pending agreements that you have to agree to? Are you able to access the \u0026ldquo;create certificate form\u0026rdquo; in your apple developer account? Also, does your account have multiple teams? (i.e. when you log into apple developer to you need to select a team?)\nshannah78 — July 23, 2015 at 3:38 pm (permalink) Actually I have just made some fixes to the wizard. Please try again and it should work.\nClement Levallois — July 23, 2015 at 7:20 pm (permalink) It wooorks! Amazing, takes just 2 seconds. Congrats on an amazing job for the community! 🙂\nsao — July 28, 2015 at 3:16 pm (permalink) This is a great achievement. Well done CodeNameOne team\nTom Arn — August 5, 2015 at 1:05 pm (permalink) That’s fantastic! Especially if you are developping on Windows, certificate creation was such a pain! Very well done!\nIf I could also do the appstore upload from the Codename One plugin as planned, then I could finally cease using MacInCloud again.\nThat would be an even better enhancement than the certificate wizard, because I do a lot more uploads than I need to create certificates!\nTom\nShai Almog — August 5, 2015 at 2:03 pm (permalink) It was something we wanted to add but the deployment complexity is far bigger.\nI want it too since that’s pretty much the only reason to own a Mac and we have at least the rudimentary understanding of how to do that.\nChidiebere Okwudire — August 13, 2015 at 3:54 am (permalink) Chidiebere Okwudire says:\nHi Steve,\nI tried the wizard and it works just fine. However, I have two test apps and I noticed that after using the wizard to generate certificates for the second app, the first one’s certificates are marked as ‘invalid’ and the app no longer runs on my device. Is this a restriction from Apple or from the wizard?\nShai Almog — August 13, 2015 at 4:23 am (permalink) Shai Almog says:\nThe wizard asks you if you already have P12 files otherwise it regenerates them for you and effectively invalidates the old ones.\nChidiebere Okwudire — August 13, 2015 at 7:24 am (permalink) Chidiebere Okwudire says:\nSo are you saying that I can use the p12 files generated for the first app in all others? I vaguely remember that the build failed when I tried that but I’ll have to recheck based on your answer.\nSanny Sanoff — August 14, 2015 at 8:50 am (permalink) Sanny Sanoff says:\nWizard button did not appear in the place described here. IDEA 14/15.\nInstalled Macos, Xcode and attached developer account to xcode, tested device build. Restarted IDEA. No luck.\nMoreover, in IDEA preferences, there are 2 instances of Codename One configuration nodes.\nShai Almog — August 14, 2015 at 1:14 pm (permalink) Shai Almog says:\nThat feature isn’t available yet in the IntelliJ version of the plugin.\nBarak — November 10, 2015 at 11:41 pm (permalink) Barak says:\nAfter pressing generate and logging in to my Itunes account\nI get this message(attached image)\nany idea how to fix it?\nThanks in advance.\nShai Almog — November 11, 2015 at 4:55 am (permalink) Shai Almog says:\nYou shouldn’t get that message so its definitely a bug. Is the page http://developer.apple.com/… reachable or do you see notices that you need to approve something?\nDismissing Apple notices is horribly unintuitive.\nBarak — November 11, 2015 at 6:35 am (permalink) Barak says:\nEverything seems fine in that page ,I suppose I didn’t ‘enroll’ and paid the 100$ fee.\nI hope that’s not the problem…\nis it?\nShai Almog — November 11, 2015 at 8:01 am (permalink) Shai Almog says:\nYou need to pay Apple and wait for approval which takes a couple of days.\nBarak — November 11, 2015 at 3:39 pm (permalink) Barak says:\nWell that’s unfortunate,thanks anyway!\nYngve Moe — November 14, 2015 at 5:58 pm (permalink) Yngve Moe says:\nI can’t see any login dialog. When i press Generate, I just get the message \u0026ldquo;This feature requires you to be logged in.\u0026rdquo; This happens on a fresh install of NetBeans with Codename One plugin, both on Mac and Windows. Am i doing something wrong?\nShai Almog — November 15, 2015 at 4:12 am (permalink) Shai Almog says:\nYes, I think its a mistake to require that. It was added to simplify the process of generating push certificates.\nYou login in the main Codename One section of the preferences at the bottom of the UI. That might be hidden if you have a small screen.\nYngve Moe — November 15, 2015 at 10:29 am (permalink) Yngve Moe says:\nYou’re right, that section was hidden. I found it myself after some googling. Apart from that, the wizard is very simple and smooth – saved me a lot of work!\nAndrey — December 21, 2015 at 1:24 pm (permalink) Andrey says:\nI used the free version Codename one and Intellij IDEA. Why is there no button generate? What should I do to make it come from?\nShai Almog — December 22, 2015 at 5:56 am (permalink) Shai Almog says:\nThe certificate wizard is available for free. The IntelliJ plugin is a bit out of date with many new features such as Java 8 support etc.\nWe are working on a complete overhaul of the plugin but get side tracked a lot. I hope we’ll be able to bring it into feature parity with the current NetBeans/Eclipse plugins for 3.3.\nAndrey — December 22, 2015 at 9:41 am (permalink) Andrey says:\nShai, thanks for answer. I will try to set up Eclipse or NetBeans.\nAndrey — December 23, 2015 at 3:12 pm (permalink) Andrey says:\nShai, can you answer me, in last version Eclipse for java developers (mars) is there this button? I don’t found that.\nShai Almog — December 24, 2015 at 10:21 am (permalink) Shai Almog says:\nThis is what I’m seeing, how did you install the plugin?\ntomm0 — January 19, 2016 at 3:47 pm (permalink) tomm0 says:\nDoes each app needs its own Certificate? I am confused by that aspect. I have just been testing things out, and whenever I choose to Overwrite the certificate I get an email from Apple saying my certificate has been revoked. What should the general process be? Should each app have its own p12 certificate?\nShai Almog — January 20, 2016 at 3:41 am (permalink) Shai Almog says:\nThat should indeed be clearer in the wizard, I’m not exactly sure how we can do that though…\nYou need one set of signing certificates for all your apps. You need to renew them once per year as they do expire.\nProvisioning profiles are done per-app so when you run the wizard on a new app just tell it NO when it asks to generate the certificates and point the UI to the P12 files you generated last!\nNow this is the point where it gets hard… When doing push you DO need new P12 files that are specific to the app, they are totally unrelated to signing/building and are only used for push. So if you check the \u0026ldquo;push\u0026rdquo; checkbox you will need to generate those. You will get an automatic email message with instructions when you check that flag.\nPaul Willworth — January 25, 2016 at 6:06 am (permalink) Paul Willworth says:\nThis is a great feature. The one thing I don’t understand is where it gets the certificate passwords from. I can complete the wizard process successfully, but when I’m done I find that it has used the value \u0026ldquo;password\u0026rdquo; for my certificate passwords. I don’t want it to use that, how do I specify what password the wizard should use for my certificates? I am using Eclipse. I saw some talk in another thread about setting some project level password but I don’t see that.\nShai Almog — January 26, 2016 at 3:16 am (permalink) Shai Almog says:\nI don’t think that’s configurable for the build p12 files. Notice that the security of those files isn’t crucial as they are stored on your local machine. Normally on a Mac when building locally the keys are just protected by your OS password.\nJames Mason — May 24, 2016 at 12:48 pm (permalink) James Mason says:\nWhen I run the iOS Certificate Wizard, a window pops up saying \u0026ldquo;Select Team\u0026rdquo;. But no teams are listed and there is no response to the Next button either. How do I get beyond this?\nShai Almog — May 25, 2016 at 5:57 am (permalink) Shai Almog says:\nIf you navigate to http://developer.apple.com/… do you see teams or something like that?\nDo you have the ability to create a new certificate/provisioning profile?\nIs there something \u0026ldquo;special\u0026rdquo; about your account? (Enterprise, University etc.)\nJames Mason — May 25, 2016 at 4:03 pm (permalink) James Mason says:\nThanks very much, Shai, for pointing me in the right direction. I think Codename One is great and have used it successfully with no problems to develop an Android app. Now, not being an Apple person, I just have to get by their hurdles to become a registered iOS developer.\n3lix — August 22, 2016 at 6:24 am (permalink) 3lix says:\nHello I am getting the following error \u0026ldquo;could not create development profile. No matching provisioning profile was found\u0026rdquo; when I try to generate the certificated.\nI do have a developer account which I use to login with. (this step is successful)\nSelecting device step is also successful as I see the newly added device on my developer’s account.\nI would appreciate any help.\nIan — August 22, 2016 at 9:35 am (permalink) Ian says:\nHi. I’m trying to use the wizard to generate a certificate. It worked fine previously but now, it isn’t working. It asks me for the devices, I select them, it asks if I want to overwrite existing iOS certificate and I say \u0026ldquo;Yes\u0026rdquo;.\nBut then it doesn’t generate any certificate. Any idea why? I don’t get any error message.\n3lix — August 22, 2016 at 3:08 pm (permalink) 3lix says:\nAlso I noticed that my \u0026ldquo;Certificates\u0026rdquo; screen shows up with \u0026ldquo;Enable Push Pro Feature only\u0026rdquo; at the bottom.\nI am not sure if this is causing any issues?\nShai Almog — August 24, 2016 at 8:03 am (permalink) Shai Almog says:\nThere was an issue with Apple changing it’s certificate process, we’ve deployed an update that should fix this.\nShai Almog — August 24, 2016 at 8:04 am (permalink) Shai Almog says:\nThere was an issue with Apple changing it’s certificate process, we’ve deployed an update that should fix this.\nThe enable push is unrelated.\n3lix — August 24, 2016 at 3:09 pm (permalink) 3lix says:\nThank you very much! Looks like its working now,\nhesham mohamed — October 20, 2016 at 9:09 pm (permalink) hesham mohamed says:\nHello, i am getting same Message (Select team ), and i checked my Apple account and i can’t see anything like teams, and don’t know what could be the reason behind !\nappreciate your help\nJacob Rachoene — October 27, 2016 at 10:42 pm (permalink) Jacob Rachoene says:\nHi James, have you actually figured out your way around this? Exactly what did you do? Any one has an idea?\nThanks…\nShai Almog — October 28, 2016 at 3:45 am (permalink) Shai Almog says:\nYou need to have a paid Apple account for this to work\nShubhanjan Medhi — January 26, 2017 at 10:22 am (permalink) Shubhanjan Medhi says:\nHi, i am unable to generate a certificate using the wizard, it asks me to select a team but there is no team listed. I tried logging into my apple account https://developer.apple.com… but even there i could not find any certificate for signing.\nHow do i do it?\nShai Almog — January 27, 2017 at 7:33 am (permalink) Shai Almog says:\nHi,\ndo you have a paid iOS developer account?\nCan you generate a CSR in your apple account?\nThat’s a requirement to generating the certificate.\nKai — February 3, 2017 at 10:16 am (permalink) Kai says:\nHi,\nI am using a university dev account, I know that I cannot create Appstore certificates.\nUsing the ios Signing wizard from Codenameone settings panel (NetBeans, latest Plug-in),\neverything works so far and the certificate + provisioning profile + appid get created.\nHowever the needed certificate password is not stored in the codenameone_settings.proper… file.\nIs there a bug? Otherwise I’m having troubles as I do not own a Mac for the CSR.\nAdditionally the created files (I downloaded them from the developer account website, as I couldn’t find them on my system) do not get added into the related fields.\nKai — February 3, 2017 at 3:21 pm (permalink) Kai says:\nI fixed it by creating the .p12 file on my own.\nShai Almog — February 4, 2017 at 8:34 am (permalink) Shai Almog says:\nHi,\nthis should work even with a university account\nKai — February 6, 2017 at 9:08 am (permalink) Kai says:\nHi, unfortunately it only creates a .cer file and not the needed .p12 file\nShai Almog — February 7, 2017 at 10:08 am (permalink) Shai Almog says:\nI’m assuming you downloaded the cer files from the apple site and didn’t generate them via the tool. Right?\nKai — February 7, 2017 at 10:44 am (permalink) Kai says:\nNo, I used the tool for the whole process. It shows that the AppStore certificate was not generated, after setting App Name (you should add validation that no special characters are allowed) \u0026amp; App ID, it runs into an error \u0026ldquo;Could not create appstore profile. No matching provisioning profile was found\u0026rdquo;. Then it returns to the view where App name and ID are set. Then I tried to download the files from developer.apple.com, because I couldn’t find any generated/downloaded file on my system, neither are any paths/settings set in the Codenameone ios signature settings.\nIn my case I managed to create the .p12 file and build iOS debug-app, but I could not use the wizard at all.\nShai Almog — February 8, 2017 at 9:05 am (permalink) Shai Almog says:\nThen you did download the cer file. P12 files aren’t generated by Apple they can only be generated thru the wizard. Unfortunately we can’t debug the university accounts since we aren’t an educational institute.\nTommy Mogaka — February 17, 2017 at 8:43 am (permalink) Tommy Mogaka says:\nHi Steve… great post and awesome work you guys doing. CN1 is one of the great enablers and equalizers out there.\nOne thing I would like to see is the App Store upload process especially for Apple. Right now I have a challenge as using the Application Loader 3.0 fails saying it is not available right now and that no suitable application records were found and that I should upload my bundle identifier…. What could be the cause of this? And how can I resolve this problem? My App name and App ID as written in netbeans initially didn’t match the one on the developer portal. I edited the portal to match Netbeans but no luck. Any ideas? Any pointers will be highly appreciated.\nTommy Mogaka — February 17, 2017 at 9:24 am (permalink) Tommy Mogaka says:\nGot the issue! I had not selected the correct Bundle ID under General information of the app in the developer portal. Now I am getting this error:\nERROR ITMS-90168: \u0026ldquo;The binary you uploaded was invalid\u0026rdquo;\nLooks like I have to start over… will clean out the portal of any id, certs and profiles and try again.\nShai Almog — February 18, 2017 at 10:47 am (permalink) Shai Almog says:\nIt’s a painful process the first time around. We’d like to add an upload to itunes wizard at some point but it’s not a trivial task.\nChris — June 16, 2017 at 5:51 pm (permalink) Chris says:\nHi Shai, I’m encountering same issue now. is there any fix needed on codename server. Through the wizard it says Developer Cert not Generated and Appstore cert not generated. When I complete the process, it creates profiles and certificates but the passwords showing empty. Build is getting failed.\nShai Almog — June 16, 2017 at 7:06 pm (permalink) Shai Almog says:\nIt’s a regression due to some server changes we made see https://groups.google.com/d…\nShould be fixed now\nbeck — September 6, 2017 at 5:57 pm (permalink) beck says:\n\u0026ldquo;I’m happy to announce that the next version of the Codename One plugin will include a wizard that generates all of these things for you with just a few mouse clicks.\u0026rdquo; Has it happened yet?\nShai Almog — September 7, 2017 at 8:17 am (permalink) Shai Almog says:\nThis is a post from 2015… It happened 2 years ago.\nJson — September 15, 2017 at 11:21 pm (permalink) Json says:\nI’m faced with the same problem.. I’m developing 2 apps, been test building on android with no problems and wanted to do test iOS builds, the howto above is great and I was able to send a debug build and install etc.. however when trying to do the same for the second app I’m stuck, I used the same wizard.. DID_NOT create a new signing cert (as I thought it would invalidate the original certs and it looks like I’m correct) and only got the provisioning profiles created. My question is how do we use the same certs for other apps when we dont know the password? I get build errors which I suspect may be caused by the fact that I dont know the password for the certificates in the first place =(\nShai Almog — September 16, 2017 at 5:19 am (permalink) Shai Almog says:\nYou need to copy the P12 files from the other project into your new project and update then in the iOS signing section with their passwords.\nJson — September 17, 2017 at 1:21 pm (permalink) Json says:\nthanks shai! ok I figured out the default password for the p12, certs.. its in the properties file of the other project (of course!), I was able to generate the ios build for the second project with the same cert but diff provisioning profile.\nmy hats off to you and your team! — from a 20 something year java veteran + 2 week CN1 dev =)\nZombieLover — March 18, 2018 at 4:27 pm (permalink) ZombieLover says:\nSo we can’t produce apple builds without having a paid Apple account then?\nShai Almog — March 19, 2018 at 5:33 am (permalink) Shai Almog says:\nThat’s an Apple restriction. When we launched we provided an option to sign with our own certificate but we removed that as we think it violates Apples terms of service. For that to work you had to have a jailbroken device and that’s not a practical requirement today.\nApple provides free certificates for educational institutes \u0026amp; non-profits so you might be able to obtain a certificate through one of those venues.\nZombieLover — March 19, 2018 at 6:03 am (permalink) ZombieLover says:\nThanks for the quick reply\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/ios-certificate-wizard/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/ios-certificate-wizard/ios-cert-wizard-blog-post-header.png\"\u003e\u003c/p\u003e\n\u003cp\u003eSo you have finished your app and tested it on the simulator. Everything looks good. You’re now ready to proceed with testing on your iPhone. You select the \u0026ldquo;Send iOS Debug Build\u0026rdquo; menu item and wait for the build server to work its magic, but then you’re faced with a notice that iOS builds require a valid certificate and provisioning profile. What a hassle!\u003c/p\u003e\n\u003cp\u003eIf you’ve done any iOS development (not just Codename One) I’m sure you’ve hit this speed-bump before. You can’t \u003cstrong\u003ejust\u003c/strong\u003e test your app on your iPhone. You have to jump through a series of hoops imposed by Apple before you get the privilege of testing your app on your phone. You need to create an App ID with the necessary permissions, generate a certificate signing request, download your certificates, generate mobile provisioning profiles to register your iPhone to be able to test your app. And finally, you have to export your certificates into a format that can be used in Codename One. If you have a Mac, this process is annoying at best. If you don’t, then this process might be your show-stopper.\u003c/p\u003e","title":"iOS Certificate Wizard"},{"content":"\nWhen we introduced Codename One initially we limited the API to CLDC level which is roughly a subset of Java 1.3, we then\nadded support for a subset of Java 5 and we are now adding Java 8 language features!\nThanks to some work from Steve and the great work done by the guys from the\nRetro Lambda project we were able to add compatibility\nto the major Java 8 features, most notably lambda expressions. This is highly experimental and some features\nmight not work but so far it seems things are functioning rather smoothly.\nNote that this feature will only be available with the next plugin update and isn’t online right now…\nThe main motivation for doing this is in reducing a lot of the boilerplate code you would normally get when writing\nCodename One code, e.g. currently we write something like:\nbutton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Dialog.show(\u0026quot;Event Happened\u0026quot;, \u0026quot;You pressed a button\u0026quot;, \u0026quot;OK\u0026quot;, null); } }); Whereas lambdas allow us to write this:\nbutton.addActionListener((e) -\u0026gt; { Dialog.show(\u0026quot;Event Happened\u0026quot;, \u0026quot;You pressed a button\u0026quot;, \u0026quot;OK\u0026quot;, null); }); Technically both are practically identical!\nThis can be applied across the board e.g.:\nDisplay.getInstance().callSerially(() -\u0026gt; { // this code executes on the EDT.... }); This won’t be the default until we are confident that this is stable enough, with an upcoming plugin update\nyou will have an option to create a Java 8 project instead of a Java 5 project. You could also convert existing\nprojects to Java 8 but that will require some effort:\nMake sure you have Java 8 installed and that your IDE is running under Java 8 Change all \u0026ldquo;source\u0026rdquo; and \u0026ldquo;target\u0026rdquo; values for Javac calls in build.xml from 1.5 to 1.8. Update the IDE build settings for the project (in the project properties menu) to use Java 8 source level Add the build hint java.version=8 Update CLDC11.jar to the latest version using the Update Client Libs button in the project preferences The post mostly covered lambdas but other newer Java features such as String based switch cases (from Java 7)\ntry with resources etc. should work just fine however we didn’t do enough tests for the various features on all the\nplatforms (hence the beta moniker).\nTry with resources is pretty cool e.g. you can do something like:\ntry(InputStream is = Display.getInstance().getResourceAsStream(getClass(), \u0026quot;/myFile\u0026quot;)) { // work with file } catch(IOException err) { Dialog.show(\u0026quot;Error\u0026quot;, \u0026quot;Exception accessing the resource\u0026quot;, \u0026quot;OK\u0026quot;, null); } Which doesn’t seem like much until you realize that this really replaced this code:\nInputStream is = null; try { is = Display.getInstance().getResourceAsStream(getClass(), \u0026quot;/myFile\u0026quot;); // work with file } catch(IOException err) { Dialog.show(\u0026quot;Error\u0026quot;, \u0026quot;Exception accessing the resource\u0026quot;, \u0026quot;OK\u0026quot;, null); } finally { if(is != null) { try { is.close(); } catch(IOException err) {} } } Just to be fair, this code can be slightly more concise in the finalizer block with Codename One’s Util.cleanup(is) method…\nOne feature of Java 8 that isn’t supported at the moment is streams.\nWhile they would be nice to have they probably won’t be as helpful as the other\nfeatures in a mobile environment and won’t provide performance benefits in these cases. We might add them\nat a future date if there is demand for that.\nNotice that Java 8 support was mostly tested with Android, iOS \u0026amp; the desktop port. It should work well with most modern ports but might have issues\nin platforms such as J2ME/RIM where even the Java 5 compatibility is flaky.\nThe image in the title of this post is from this Takipi blog which\nis pretty relevant to the subject of this post. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJames Hastings — July 6, 2015 at 5:19 pm (permalink) James Hastings says:\nThis is great news. What about the localdate class? I have a program I wrote that uses a bunch of localdate functionality that I wanted to port into a mobile app. Refactoring everything to Calendar and Date objects has kept this on the backburner for me.\nShai Almog — July 7, 2015 at 5:47 am (permalink) Shai Almog says:\nThanks.\nThat isn’t supported at the moment and probably won’t be around in the immediate future. The main hurdle is compatibility to existing platforms so we are walking on eggshells here trying to minimize the impact of the core libraries.\nI feel your pain, every Java developer who dealt with dates in any way hates Calendar/Date. I am looking forward to migrating to something decent, but that might be a while.\nCodrut Gusoi — July 7, 2015 at 6:39 pm (permalink) Codrut Gusoi says:\nYay lambdas!\nBrace yourselves, assertException() is coming… at least when I will have time for a pull request.\nSanny Sanoff — August 2, 2015 at 10:52 am (permalink) Sanny Sanoff says:\nWill they (lambdas) work on Android, too? How do you implement this feature if you just pass user java to dalvik?\nShai Almog — August 4, 2015 at 4:27 am (permalink) Shai Almog says:\nYes.\nIt works on all platforms even J2ME since it uses retrolambda on the server before the main processing of the bytecode.\nMartin Grajcar — November 27, 2019 at 2:21 pm (permalink) Martin Grajcar says:\nUnlike inner classes, lambdas don’t capture the enclosing class…. I just find out that I’m storing quite a few lambdas generated in forms, which must not retain the reference to the enclosing form.\nDo retrolambdas retain the reference to the enclosing class?\nShai Almog — November 28, 2019 at 2:25 am (permalink) Shai Almog says:\nRetrolambda translates Java 8 lambdas to inner classes internally. Lambdas use this as a reference to their surrounding class so they have a reference to their parent just like non-static inner classes.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/java-8-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/java-8-support/java-8-lambada.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen we introduced Codename One initially we limited the API to CLDC level which is roughly a subset of Java 1.3, we then\u003cbr\u003e\nadded support for a subset of Java 5 and we are now adding Java 8 language features!\u003cbr\u003e\nThanks to some work from Steve and the great work done by the guys from the\u003cbr\u003e\n\u003ca href=\"https://github.com/orfjackal/retrolambda/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eRetro Lambda\u003c/a\u003e project we were able to add compatibility\u003cbr\u003e\nto the major Java 8 features, most notably lambda expressions. This is highly experimental and some features\u003cbr\u003e\nmight not work but so far it seems things are functioning rather smoothly.\u003c/p\u003e","title":"Java 8 Support"},{"content":"The content of this page was out of date. Please check out up to date content in the developer guide here.\n","permalink":"https://www.codenameone.com/google-login/","summary":"\u003cp\u003eThe content of this page was out of date. Please check out up to date content in the developer guide \u003ca href=\"/developer-guide\"\u003ehere.\u003c/a\u003e\u003c/p\u003e","title":"Google+ Login"},{"content":"\nFacebook \u0026amp; Google login have been a source of a bit of pain mostly because of the obtuse and confusing\ndocumentation from both companies. Chen spent some time writing up tutorials for both\nFacebook Login \u0026amp; Google Login\nthat should help you get started with applications that use such login options.\nFuture Of Windows Phone I’ve been holding back on writing this before we have further information and can properly asses the situation. However… since\nMS is taking its time we’d rather discuss the future of Windows Phone once rather than all over the different forums/social and support channels.\nAs you know we wrote roughly 3 different Windows Phone ports, the first targeted Windows Phone 7.5 (mango) which\nrelied on functionality introduced in that version and immediately killed in 8.0!\nWe should have taken the hint that MS isn’t serious about Windows Phone back then but we made a second attempt\nfor support with a port to Windows Phone 8. This port used the official API’s but they weren’t very suitable for a tool\nlike Codename One and this performed really badly, it had horrible bugs to boot.\nThe third attempt which is now live uses Sun’s Pisces framework to abstract graphics which is a real hack, it\n\u0026ldquo;works\u0026rdquo; but is pretty limited and still performs poorly.\nWe were thinking about a complete rewrite on top of DirectX for quite some time, however such an effort would require\na huge expense in time and resources on something that none of our enterprise customers considered crucial.\nA few pro users asked for that (less than 4 if I recall correctly) but that can’t justify what is effectively close to a 100K USD\nexpense in time and effort.\nFor quite a while there were rumors that Windows will feature Android compatibility and MS recently announced\njust that.\nWe don’t yet know if it will work with Codename One but it should be relatively easy to support Windows devices\nusing a compatibility layer such as this and effectively skip a lot of the complexity.\nSince this technology isn’t out yet and we don’t know what will be required from us to be compatible we can’t\nmake any guarantees or even assumptions on how/whether this will work. However, this does look like the best\nway to support Windows Phone and make the port far more maintainable/performant/feature complete.\nThe only downside to this is that this will probably only work on Windows 10 and newer devices. With the\nJavaScript port you would still be able to target older devices if needed. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nHitesh Rawtani — July 10, 2015 at 4:22 am (permalink) Hitesh Rawtani says:\nHi Shai, first of all thank you for this wonderful framework. I used to use LWUIT for cross platform java mobile apps and CodenameOne looks fantastic for the different range of mobile platforms we have today.\nI was trying to integrate google login in one of my apps but didn’t see the GoogleConnect class to be available. Does that part of code go into the native implementation for each platform?\nShai Almog — July 10, 2015 at 2:05 pm (permalink) Shai Almog says:\nWe need to update the plugin version to include these new features. It should be out next week.\nHitesh Rawtani — July 11, 2015 at 6:42 am (permalink) Hitesh Rawtani says:\nGreat. I look forward to the update.\nJ.C — July 23, 2015 at 11:36 am (permalink) J.C says:\nIt looks like MS is only supporting Web Apps and Xamarin for cross platform compatibility and not native Android Java Apps in Visual Studio 2015 which is a let down. This means CodenameOne will not be able to run properly on newer Win10 devices or even older devices. Not sure how good is the JavaScript version, but I think native is much better. Too bad really.\nFabrício Cabeça — July 30, 2015 at 11:33 am (permalink) Fabrício Cabeça says:\nI agree, that’s why I decided to write a windows port myself, it is still under heavy development but I can’t see anything that can’t be accomplished right now and uses WinRT which means it will work with the universal apps model. I don’t blame the cn1 team, Microsoft really didn’t help constantly changing frameworks and not giving basic graphics support.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/login-tutorials-future-of-windows-phone/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/login-tutorials-future-of-windows-phone/google-sign-in.png\"\u003e\u003c/p\u003e\n\u003cp\u003eFacebook \u0026amp; Google login have been a source of a bit of pain mostly because of the obtuse and confusing\u003cbr\u003e\ndocumentation from both companies. Chen spent some time writing up tutorials for both\u003cbr\u003e\n\u003ca href=\"/how-to-integrate-facebook-login-with-codename-one/\"\u003eFacebook Login\u003c/a\u003e \u0026amp; \u003ca href=\"/google-login.html\"\u003eGoogle Login\u003c/a\u003e\u003cbr\u003e\nthat should help you get started with applications that use such login options.\u003c/p\u003e\n\u003ch4 id=\"future-of-windows-phone\"\u003eFuture Of Windows Phone\u003c/h4\u003e\n\u003cp\u003eI’ve been holding back on writing this before we have further information and can properly asses the situation. However… since\u003cbr\u003e\nMS is taking its time we’d rather discuss the future of Windows Phone once rather than all over the different forums/social and support channels.\u003cbr\u003e\nAs you know we wrote roughly 3 different Windows Phone ports, the first targeted Windows Phone 7.5 (mango) which\u003cbr\u003e\nrelied on functionality introduced in that version and immediately killed in 8.0!\u003c/p\u003e","title":"Login Tutorials \u0026 Future Of Windows Phone"},{"content":"\nEric Dodji Gbofu has been working on a Codename One book in French for\nthe past year and it finally came out!\nI’m still waiting on my copy mostly to show to French speakers we meet (I have a very hard time picking languages), I’m\npretty sure its a cool book. Chen and I wrote the forward for the book, I trust Eric did a great job in it just like he has done with\nCodename One Fr.\nYou can order the book either directly thru the publishers site\n(which is apprently the preferred way) or thru Amazon.\nWe hope many of you purchase this book, if there is interest in it then it might prompt further updates and additional publishers.\nApp Engine Migration Part III This is going to be a long and winding saga covering the migration process of our backend servers from App Engine\nto a more \u0026ldquo;hands on\u0026rdquo; architecture. The build servers storage aspect already migrated to S3 and seem to be functioning\nreasonably well. We are now setting our focus on several different features, the first of which is\ncrash reporting.\nAn important feature within crash reporting is the feature that allows sending an email with your log file from the device,\nwith new builds this will use our new webservice that no longer uses app engine. It will also switch to using sendgrid\nfor the actual email delivery…\nThis should improve the functionality considerably since unlike app engine the log will now be embedded into the body\nof the email thus allowing you to use email filters etc. It will also solve the issue of log files no longer being available.\nWe will now also quota emails so no more than 1 email per minute can be sent (per user) and no more than 200\nper 48 hours. This will prevent some cases we had in the past from recurring where a wayward app update\ndecimated users inboxes.\nThis is yet another step in an ongoing process, we intend to shift device registration/push to the new servers as soon\nas possible which should open up a whole set of possibilities.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/book-continued-migration/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/book-continued-migration/codenameone-fr-book.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://www.codenameonefr.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eEric Dodji Gbofu\u003c/a\u003e has been working on a Codename One book in French for\u003cbr\u003e\nthe past year and \u003ca href=\"http://www.d-booker.fr/cn1/214-codename-one.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eit finally came out\u003c/a\u003e!\u003cbr\u003e\nI’m still waiting on my copy mostly to show to French speakers we meet (I have a very hard time picking languages), I’m\u003cbr\u003e\npretty sure its a cool book. Chen and I wrote the forward for the book, I trust Eric did a great job in it just like he has done with\u003cbr\u003e\n\u003ca href=\"http://www.codenameonefr.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCodename One Fr\u003c/a\u003e.\u003cbr\u003e\nYou can order the book either directly thru the \u003ca href=\"http://www.d-booker.fr/cn1/214-codename-one.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003epublishers site\u003c/a\u003e\u003cbr\u003e\n(which is apprently the preferred way) or thru \u003ca href=\"http://www.amazon.fr/Codename-One-D%C3%A9velopper-Android-Blackberry/dp/2822703485\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eAmazon\u003c/a\u003e.\u003c/p\u003e","title":"Book \u0026 Continued Migration"},{"content":"Facebook Login This tutorial covers how to add facebook connect to your CN1 app\nHome Developers Facebook Login Codename One supports facebook Oauth2 login and facebook single sign on for iOS and Android\nTo get started first you will need to create a facebook app on the facebook developer portal Here: https://developers.facebook.com/apps/\nYour facebook app should have 3 platforms added on the Settings tab:Website, iOS and Android\nAndroid Settings:\nEnter app package name in the \u0026ldquo;Google Play Package Name\u0026rdquo;. Enter the CN1 activity name in the class name, which is: full class name + \u0026ldquo;Stub\u0026rdquo;. Enter your app key hash: use your app release certificate and do the following in your command tool: keytool -exportcert -alias (your_keystore_alias) -keystore (path_to_your_keystore) | openssl sha1 -binary | openssl base64 This will print out the key hash of your app, copy it and place it in the facebook settings for android. iOS Settings:\nEnter app package name in the \u0026ldquo;Bundle ID\u0026rdquo;. Enter the iPhone Store ID, once you know it. The settings page should look like this:\nIn your CodenameOne app do the following: Add facebook.appId build hint to your project properties and in your code do the following:\n//use your own facebook app identifiers here //These are used for the Oauth2 web login process on the Simulator. String clientId = \u0026#34;1171134366245722\u0026#34;; String redirectURI = \u0026#34;http://www.codenameone.com/\u0026#34;; String clientSecret = \u0026#34;XXXXXXXXXXXXXXXXXXXXXXXXXX\u0026#34;; Login fb = FacebookConnect.getInstance(); fb.setClientId(clientId); fb.setRedirectURI(redirectURI); fb.setClientSecret(clientSecret); //Sets a LoginCallback listener fb.setCallback(...); //trigger the login if not already logged in if(!fb.isUserLoggedIn()){ fb.doLogin(); }else{ //get the token and now you can query the facebook API String token = fb.getAccessToken().getToken(); ... } ","permalink":"https://www.codenameone.com/how-to-integrate-facebook-login-with-codename-one/","summary":"\u003ch1 id=\"facebook-login\"\u003eFacebook Login\u003c/h1\u003e\n\u003cp\u003eThis tutorial covers how to add facebook connect to your CN1 app\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"https://beta.codenameone.com/getting-started.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://beta.codenameone.com/getting-started.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDevelopers\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eFacebook Login\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eCodename One supports facebook Oauth2 login and facebook single sign on for iOS and Android\u003c/p\u003e\n\u003cp\u003eTo get started first you will need to create a facebook app on the facebook developer portal Here: \u003ca href=\"https://developers.facebook.com/apps/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttps://developers.facebook.com/apps/\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eYour facebook app should have 3 platforms added on the Settings tab:Website, iOS and Android\u003c/p\u003e\n\u003cp\u003eAndroid Settings:\u003c/p\u003e","title":"How to Integrate Facebook Login with Codename One"},{"content":"\nWhile multi-image’s go a long way in making your app scalable to various devices, scalable images can be even\nmore convenient. The SVG standard never took off though, its too complex to support in an efficient way on\nthe devices and so its relegated to web applications and even those don’t make heavy use of it due to its complexity.\nHowever, icon fonts have gained a lot of popularity in recent years and we used them in the past in Codename One\ne.g. in the photo demo.\nThat usage was awkward, we had to define a special font for the tab area and use letters in a way that didn’t communicate\nwhat would actually appear on the screen. It worked because we only used an icon without text, had we tried to use\nboth it wouldn’t have worked…\nSo we now have support for icon fonts via the new FontImage class. This class encapsulates a character\nor string from the icon font and presents it as an image. You can even scale and rotate such as image and you can convert\nit to an EncodedImage or regular Image if necessary.\nThis allows very smooth graphics that adapt based on the platform e.g. here we use the fontello font to show a rotating\nprogress wheel, thanks to the smoothness of the font the progress looks far more refined:\nInfiniteProgress ip = new InfiniteProgress(); int size = Display.getInstance().convertToPixels(20, true); Font fnt = Font.createTrueTypeFont(\u0026quot;fontello\u0026quot;, \u0026quot;fontello.ttf\u0026quot;); FontImage fm = FontImage.createFixed(\u0026quot;ue800\u0026quot;, fnt, 0xffffff, size, size); ip.setAnimation(fm); ip.showInifiniteBlocking(); We can create such an image using two methods, a fixed size/color image which you can use to assign a pixel\nsize for such an image and a more \u0026ldquo;generic\u0026rdquo; method that will accept a style and adapt the icon for that style.\nAs we move forward we would like to integrate icon fonts far deeper into the Codename One stack, this would\ninclude integration with the designer tools etc.\nRetiring The Old VM Apple is pretty quick with with moving forward, they pushed everyone to 64 bit very fast and it seems they are\npoised to do the same with some new iOS 9 changes. This usually takes the form of requiring an xcode upgrade\nwhich is pretty easy for us to do since we just need to login to all the servers and update xcode on those machines.\nThis does pose a problem though, the newer versions of xcode require a newer version of Mac OS (Yosemite or even newer),\nunfortunately the older versions of xcode that still run the old VM don’t work on Yosemite anymore and aren’t\nmaintained by Apple. We will try to wait until the last minute to upgrade in order to allow those of you who\nare still building with the old VM (e.g. in the enterprise setting) some time to migrate. However, you must migrate…\nEven versioned builds won’t work with the old VM once the OS is updated so you can no longer rely on the old\nXMLVM builds to still work in the future!\nUnfortunately some of our enterprise users just don’t read the blog, social media posts or our repeated mailings on the subject…\nWhich is why we will be retiring the ios.newVM build hint so those guys who just added it and forgot\nabout it will be forced to re-evaluate its necessity.\nWe will expose a new flag: ios.deprecatedDontUseThisFlagSeriouslyOldVM which you can set to true\nto force the old vm. But seriously…\nDon’t use it.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/icon-fonts-oldvm-swan-song/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/icon-fonts-oldvm-swan-song/font-awesome.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhile multi-image’s go a long way in making your app scalable to various devices, scalable images can be even\u003cbr\u003e\nmore convenient. The SVG standard never took off though, its too complex to support in an efficient way on\u003cbr\u003e\nthe devices and so its relegated to web applications and even those don’t make heavy use of it due to its complexity.\u003cbr\u003e\nHowever, icon fonts have gained a lot of popularity in recent years and we used them in the past in Codename One\u003cbr\u003e\ne.g. in the \u003ca href=\"http://udemy.com/build-mobile-ios-apps-in-java-using-codename-one/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ephoto demo\u003c/a\u003e.\u003c/p\u003e","title":"Icon Fonts \u0026 Old VM Swan Song"},{"content":"\nChen recently published a major refactoring of our connection framework which up until now only supported\nFacebook login. With this recent refactoring the code to connect to various authentication services becomes\nfar simpler and various services should become more pluggable. The default implementation centers\naround the Login and LoginCallback classes that use oAuth by default to\nperform the login.\nFacebookConnect keeps working just like it always did but now it extends the Login class to\nprovide generic login functionality which means we can seamlessly provide additional login targets either via\noAuth or even via native integration with 3rd party SDK’s. One of the first integrations here is the\nGoogleConnect support which allows logging into a Google account to sign in. This is especially\ngreat on Android devices where the process to sign in is seamless!\nWorking with the GoogleConnect class requires a corresponding Google cloud project. To\nenable this you need to follow the instructions here\nto allow web login. The web login option is essential for simulator login thus crucial for debugging. You would also\nneed to follow the instructions for Android\nand iOS respectively.\nThe login framework should serve as the basis can can be extended easily via cn1lib’s, we hope to provide such\nlogin frameworks for various services out there and also to migrate some of the existing oAuth usages by cn1lib’s to\nuse this framework instead of the mix and match options we have right now. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChris Smith — April 28, 2017 at 4:45 am (permalink) Chris Smith says:\nI have this working, but I’m hoping to post a document to Google drive – is this supported with this login?\nShai Almog — April 29, 2017 at 6:12 am (permalink) Shai Almog says:\nI think this guy on stackoverflow was trying to do the same thing with Codename One: http://stackoverflow.com/qu…\nI have no idea if he succeeded or not\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/sign-in-with/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/sign-in-with/google-sign-in.png\"\u003e\u003c/p\u003e\n\u003cp\u003eChen recently published a major refactoring of our connection framework which up until now only supported\u003cbr\u003e\nFacebook login. With this recent refactoring the code to connect to various authentication services becomes\u003cbr\u003e\nfar simpler and various services should become more pluggable. The default implementation centers\u003cbr\u003e\naround the \u003ccode\u003eLogin\u003c/code\u003e and \u003ccode\u003eLoginCallback\u003c/code\u003e classes that use oAuth by default to\u003cbr\u003e\nperform the login.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eFacebookConnect\u003c/code\u003e keeps working just like it always did but now it extends the Login class to\u003cbr\u003e\nprovide generic login functionality which means we can seamlessly provide additional login targets either via\u003cbr\u003e\noAuth or even via native integration with 3rd party SDK’s. One of the first integrations here is the\u003cbr\u003e\n\u003ccode\u003eGoogleConnect\u003c/code\u003e support which allows logging into a Google account to sign in. This is especially\u003cbr\u003e\ngreat on Android devices where the process to sign in is seamless!\u003c/p\u003e","title":"Sign In With…"},{"content":"\nUp until now when building with include sources for iOS we also included a btres directory which was necessary for the\nold VM but no longer necessary in the new VM. This increased the distribution size considerably and we are now\nremoving it to speed up the builds and reduce server costs. When we were in the process of reviewing the sizes of\napps we noticed quite a few apps with resources weighing well over 5mb which would probably cause performance\nissues for your application, we suggest reviewing such apps and optimizing them.\nOn a separate issue the Timer class seems to have been leaking threads for some reason on iOS.\nAs we looked into it the code for the class was very complex so we simplified it considerably. If you are using\njava.util.Timer please pay attention to changes in behavior that might have occurred because of this\nchange and let us know if you run into such issues.\nWe also made a big change to the way exception handling works in the new VM last week, it solved some hidden issues\nthat might have occurred with exceptions thrown within a synchronized block. If you had some hard to track issues\nthat might be related we suggest you try again with a fresh build. Other than that we made some fixes to the charts\ncode and performance improvements on devices for that code.\nJavaDoc Index A while back I was sitting with a developer whose been programming with Java and Codename One for quite some time,\nyet didn’t find a feature that he was searching for in the JavaDoc. This brought to my attention\nthe fact that quite a few people forget about the existence of the JavaDoc index file\n(just click the index link on the top right).\nYou can just use the search function of the browser to find methods or documentation of interest regardless of the classes\nin which the method is defined. This is useful when you are looking for a specific API and don’t have much to go on. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nYaakov Gesher — June 23, 2015 at 8:23 am (permalink) Yaakov Gesher says:\nI think another important feature to help developers get better access to documentation would be a search box in the blog. The blog entries contain so much invaluable information, and yet there doesn’t seem to be a way to search the blog.\nShai Almog — June 23, 2015 at 2:17 pm (permalink) Shai Almog says:\nWe’d love to have a site wide search feature that would ideally include the javadocs, developer guide etc. unfortunately this is none trivial.\nNotice that you can easily search codenameone.com by typing site:codenameone.com your query into google e.g.: https://www.google.com/sear…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/smaller-ios-source-builds-time-index/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/smaller-ios-source-builds-time-index/iOS.png\"\u003e\u003c/p\u003e\n\u003cp\u003eUp until now when building with include sources for iOS we also included a btres directory which was necessary for the\u003cbr\u003e\nold VM but no longer necessary in the new VM. This increased the distribution size considerably and we are now\u003cbr\u003e\nremoving it to speed up the builds and reduce server costs. When we were in the process of reviewing the sizes of\u003cbr\u003e\napps we noticed quite a few apps with resources weighing well over 5mb which would probably cause performance\u003cbr\u003e\nissues for your application, we suggest reviewing such apps and \u003ca href=\"/blog/shrinking-sizes-optimizing.html\"\u003eoptimizing them\u003c/a\u003e.\u003c/p\u003e","title":"Smaller iOS Source Builds, Timer \u0026 Index"},{"content":"\nLet’s face it, your app is probably a commodity. As noted by Wikipedia,\n\u0026ldquo;a commodity has full or partial fungibility;\nthat is, the market treats its instances as equivalent or nearly so with no regard to who produced them.\u0026rdquo; In basic English\nit means that your product can be easily replaced in part or completely by another to satisfy the needs of the market.\nFor 99% of apps out there this means that if a user doesn’t find your app, they’ll pick another one that they think fills\nthe need they’re looking to satisfy. This the same whether your app is a game, a productivity app or any other category.\nAs the app ecosystem has evolved the challenge of reaching consumers for app developers has grown more and more difficult.\nFrom a technical perspective the promise of reduced fragmentation hasn’t panned out even with so many OSs\nalready sitting in the graveyard and others staring the grim reaper straight in the eyes. Any app discovery gains\nwon as a result of consumers migrating to two primary OSs have been swamped by the sheer volume of apps\ndeveloped and now available in the main app stores. Imagine walking into Walmart and there being 1 million items stocked on the shelves. How would anyone find your product?\nWhy the Walmart strategy fails In the world of physical products, unless a manufacturer has an established brand or a ton of resources, they don’t\nlaunch their product in Walmart yet every publisher rushes to get their app into iTunes and Google Play. Since\ngetting on the shelf is the easy part, it’s much more important to get people using your quality app wherever it is they\nchoose to shop than it is to drive people into the iTunes or Google Play stores. Getting on their shelves is a basic requirement but far from sufficient for success. Remember, your app is a commodity – if it’s not available when and where users are shopping then it’s a missed opportunity. We often hear the question \u0026ldquo;why does anyone use anything other than Google Play?\u0026rdquo;. In reality that’s precisely the wrong question to ask. The correct question is \u0026ldquo;Do you want your app to miss out on the 100s of millions of downloads that are taking place outside of Google Play?\u0026rdquo;\nEven with a quality app, like any startup business, your odds of being successful aren’t very good. The One Platform Foundation’s\nAndroid AppStore Market Overview noted that alternative app stores significantly improve the chances of your app being discovered by consumers. \u0026ldquo;Submitting your app to alternative appstores will increase your chances of being featured by more than 20 times.\u0026rdquo; The job of any small business owners is to give their business the best chance to be successful in a highly competitive marketplace. This has never been more important than for app publishers today.\nDon’t ignore the global audience Being everywhere really means \u0026ldquo;Think global – act local\u0026rdquo;. Do not forget about language localization and the importance of this.\nCase studies from online gaming has shown\nthat bounce rates can drop significantly and conversion and revenue drastically. For instance, 5% of the apps in Russia are localized, yet generate\n70% of the revenue.\nFinally, alternative app stores are here to stay. Why, you might ask, with Google and Apple holding such a monopoly? App stores are a key piece of the strategic plan for companies like Amazon, Nokia, Yandex, Samsung, Baidu and the list goes on. They’re investing in app stores for the long run.\nSo what should you be doing? You probably can’t ignore paid promotion at some point, but the truth here is that\ncosts are rising exponentially.\nAnother way out is to make sure your app is in as many stores as possible.\nCodeNgo helps you with that.\nFor less than $1 store you’ll have shelf space in the 7’11 of app stores – or the Safeway, perhaps even\n\u0026ldquo;near the cash register\u0026rdquo; (i.e. front page). That is a huge improvement from the back of the warehouse in Google Play.\nApple and Google aren’t going anywhere soon but their grip on the consumer will lessen over time.\nIt’s about the consumer, not the store. Be where the consumers are.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/alternative-app-stores/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/alternative-app-stores/alternative-app-stores.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eLet’s face it, your app is probably a commodity. As noted by \u003ca href=\"http://en.wikipedia.org/wiki/Commodity\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eWikipedia\u003c/a\u003e,\u003cbr\u003e\n\u0026ldquo;a commodity has full or partial fungibility;\u003cbr\u003e\nthat is, the market treats its instances as equivalent or nearly so with no regard to who produced them.\u0026rdquo; In basic English\u003cbr\u003e\nit means that your product can be easily replaced in part or completely by another to satisfy the needs of the market.\u003cbr\u003e\nFor 99% of apps out there this means that if a user doesn’t find your app, they’ll pick another one that they think fills\u003cbr\u003e\nthe need they’re looking to satisfy. This the same whether your app is a game, a productivity app or any other category.\u003c/p\u003e","title":"Alternative App Stores"},{"content":"\nWe’ve been spending a lot of times looking at performance for one of our enterprise customers. As part of the investigation\nhe came up with an interesting and very important find… He found that hashMap.get(\u0026quot;String\u0026quot;) was much\nslower under the new VM than under the old VM. Its these sort of \u0026ldquo;simple\u0026rdquo; finds that help narrow down bigger issues\nin performance that might impact a lot of things in Codename One, since HashMap is so ubiquitous the implications\nof improving it can be huge.\nOne of the advantages of the new VM is in the fact that we now also control the full API including the HashMap API and\ncan rewrite large portions of it natively for full performance advantage. But it seems that a lot of the things that were\nreally affecting performance were in the more \u0026ldquo;subtle\u0026rdquo; pieces touched by the String class and\nget method…\nWe moved many small bottlenecks into native code e.g. toString(), String.equals(),\nString.hashCode(), etc…\nBut one of the bigger performance improvements came from improving the behavior of the finalizer methods\nwhich reduces CPU usage and potential stuttering.\nJavaScript Native We’ve made some updates to the developer guide specifically a lot of details related to the\nJavaScript section and information on the native interfaces\nfor JavaScript. This is important if you want to access the JavaScript code directly which means you need to\nregenerate native interfaces for older cn1libs to be compatible. If you don’t do that compilation with such\nlibraries can result in a compilation error.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/map-string-performance-javascript-native/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/map-string-performance-javascript-native/performance.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve been spending a lot of times looking at performance for one of our enterprise customers. As part of the investigation\u003cbr\u003e\nhe came up with an interesting and very important find… He found that \u003ccode\u003ehashMap.get(\u0026quot;String\u0026quot;)\u003c/code\u003e was much\u003cbr\u003e\nslower under the new VM than under the old VM. Its these sort of \u0026ldquo;simple\u0026rdquo; finds that help narrow down bigger issues\u003cbr\u003e\nin performance that might impact a lot of things in Codename One, since HashMap is so ubiquitous the implications\u003cbr\u003e\nof improving it can be huge.\u003c/p\u003e","title":"Map, String Performance \u0026 JavaScript Native"},{"content":"\nThe JavaScript port is nearing beta stage which will start next week its already added support for most API’s\nincluding SQL support and many other features. Once the JavaScript port is in beta it will become an enterprise\nonly feature so if you haven’t tried it yet you have one week to try your app.\nInteraction Dialog Popup One often requested feature of the InteractionDialog is support for popup dialog semantics\nwhere the dialog can point at the originating component. You can now use the showPopup\nmethod also on an InteractionDialog to provide pretty elaborate UI’s.\nOne of the main use cases for such a dialog is to point at a component within the title area, e.g. with the Toolbar\nAPI this can be very simple and intuitive. However, because we abstract components within the menu thru commands\nits problematic to point the showPopup call at the right location, to solve this we added a new\nmethod to both the MenuBar and Toolbar API’s: findCommandButton(Command)\nNotice that this API isn’t guranteed to return anything, e.g. if you use the native menus which are the default\non Android you will get null as the result of that method. The same is probably true if you use overflow or other such API’s.\nHowever, this API can also be useful for many edge cases such as manipulating the appearance of a command\ndynamically which is currently pretty awkward.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/javascript-beta-interactiondialog-popup/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/javascript-beta-interactiondialog-popup/html5-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe JavaScript port is nearing beta stage which will start next week its already added support for most API’s\u003cbr\u003e\nincluding SQL support and many other features. Once the JavaScript port is in beta it will become an enterprise\u003cbr\u003e\nonly feature so if you haven’t tried it yet you have one week to try your app.\u003c/p\u003e\n\u003ch4 id=\"interaction-dialog-popup\"\u003eInteraction Dialog Popup\u003c/h4\u003e\n\u003cp\u003eOne often requested feature of the \u003ccode\u003eInteractionDialog\u003c/code\u003e is support for popup dialog semantics\u003cbr\u003e\nwhere the dialog can point at the originating component. You can now use the \u003ccode\u003eshowPopup\u003c/code\u003e\u003cbr\u003e\nmethod also on an \u003ccode\u003eInteractionDialog\u003c/code\u003e to provide pretty elaborate UI’s.\u003c/p\u003e","title":"JavaScript Beta \u0026 InteractionDialog Popup"},{"content":"\nWe are in the process of migrating the storage implementation from App Engine to Amazons S3 storage as part\nof our bigger migration away from App Engine. If\nyou experience issues related to build results please let us know so we can iron out potential regressions.\nWe are deploying this change in a way that makes it very easy to toggle this on/off and in case S3 builds prove to\nbe an issue we will be able to revert them quickly.\nOne of the big benefits in this migration is that S3 has very good uptime, of the few cases where we had App Engine\ndowntime issues the toughest were the ones that related to the blobstore API which we are now leaving. Next on\nour agenda would be the migration of most cloud functionality such as push, logs etc.\nOne nice feature in S3 is the ability to define object expiration which allows us to keep costs down and prevent\nthe bucket from filling up too much. We defined it to 3 days which means that after 3 days an install/preview will\nno longer work, in the past this expired when you sent additional builds which is something we might also apply\nin the future based on storage usage.\nNetBeans Plugin Update It seems the NetBeans verification process which is normally pretty quick has taken a dive. We are waiting for a plugin\nto be approved since the beginning of the week and its still not online with the new fixes. Hopefully it will be out\nsooner rather than later.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/migrations-new-plugin/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/migrations-new-plugin/s3-logo.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are in the process of migrating the storage implementation from App Engine to Amazons S3 storage as part\u003cbr\u003e\nof our bigger \u003ca href=\"/blog/migrating-away-from-app-engine.html\"\u003emigration away from App Engine\u003c/a\u003e. If\u003cbr\u003e\nyou experience issues related to build results please let us know so we can iron out potential regressions.\u003cbr\u003e\nWe are deploying this change in a way that makes it very easy to toggle this on/off and in case S3 builds prove to\u003cbr\u003e\nbe an issue we will be able to revert them quickly.\u003c/p\u003e","title":"Migrations \u0026 New Plugin"},{"content":"\nOur website deployment has become even more complex thanks to the demos section.\nThe crux of it is in updating the demos with every small update to the JavaScript build process which is why\nwe implemented a build option based on the work we did for our CI (Jenkins) integration.\nThis work essentially allows to build a Codename One app synchronously which is useful when you want\nto do things such as continuous integration or release engineering.\nNotice that the synchronous build feature is an enterprise only feature since its overuse can have a very heavy toll on our servers.\nEssentially we copied the existing build.xml to a separate file to prevent updates from overriding it. We then added\ntargets such as this for the kitchen sink:\n\u0026lt;target name=\u0026quot;build-for-javascript-sync\u0026quot; depends=\u0026quot;clean,copy-javascript-override,copy-libs,jar,clean-override\u0026quot;\u0026gt; \u0026lt;codeNameOne jarFile=\u0026quot;${dist.jar}\u0026quot; displayName=\u0026quot;${codename1.displayName}\u0026quot; packageName = \u0026quot;${codename1.packageName}\u0026quot; mainClassName = \u0026quot;${codename1.mainName}\u0026quot; version=\u0026quot;${codename1.version}\u0026quot; icon=\u0026quot;${codename1.icon}\u0026quot; vendor=\u0026quot;${codename1.vendor}\u0026quot; subtitle=\u0026quot;${codename1.secondaryTitle}\u0026quot; automated=\u0026quot;true\u0026quot; targetType=\u0026quot;javascript\u0026quot; /\u0026gt; \u0026lt;/target\u0026gt; This is effectively a copy and paste of the build-for-javascript target where we added the line\nautomated=\u0026quot;true\u0026quot; to indicate that this build works in a singular process.\nAfter the build completes we are left with a result.zip file in the dist folder. Which\nwe unzip to find all the files from the build server:\n\u0026lt;mkdir dir=\u0026quot;build/demoTmp/unzipped\u0026quot; /\u0026gt; \u0026lt;unzip src=\u0026quot;build/demoTmp/${demoname}-1.0.zip\u0026quot; dest=\u0026quot;build/demoTmp/unzipped\u0026quot; /\u0026gt; \u0026lt;delete file=\u0026quot;build/demoTmp/unzipped/index.html\u0026quot; /\u0026gt; \u0026lt;copy todir=\u0026quot;demos/${demoname}\u0026quot;\u0026gt; \u0026lt;fileset dir=\u0026quot;build/demoTmp/unzipped\u0026quot;/\u0026gt; \u0026lt;/copy\u0026gt; While the sample above shows the JavaScript build target it can be applied to any of the Codename One build\ntargets and is remarkably useful for a release engineering process. When you need to release one version for all platforms\non a frequent basis even a minute automation like this makes a big difference. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nBlessing Mahlalela — February 9, 2017 at 4:35 pm (permalink) Blessing Mahlalela says:\nHi during development I noticed that if I try to send multiple builds ie Send Android, Send iOS.. on Netbeans etc. I would receive a compile error if I send them too quickly (simultaneously), I think CN1 deletes some files during the send build process. In any case the reason why I saying that is, I have Jenkins setup and would like to return a result.zip containing multiple platform result files ie Android, iOS, Web, Desktop. How can I go about doing this on Jenkins build.xml? I am currently able to set ANT targets on Jenkins pre and post build.\nShai Almog — February 9, 2017 at 6:32 pm (permalink) Shai Almog says:\nYes, you can send concurrent builds but not at once. If you use automation to do this your user can’t send a build at that exact time. It’s just a limitation in the way the system was designed as the code that allocates a build needs to reserve a spot.\nBlessing Mahlalela — February 9, 2017 at 6:43 pm (permalink) Blessing Mahlalela says:\nOk, I have now managed to call an ANT \u0026ldquo;build-for-javascript\u0026rdquo; target from the build xml. Thanks a lot for this, no more sitting and waiting for builds, secondly the automated test recorder will become a great resource to small dev organisations that just don’t have budget for dedicated test teams!\nBlessing Mahlalela — February 9, 2017 at 6:46 pm (permalink) Blessing Mahlalela says:\nOne more question. How can I add multiple ANT arguments on Jenkins? I would like to automate the building of Android, iOS \u0026amp; web on every successful CI build.\nBlessing Mahlalela — February 9, 2017 at 8:21 pm (permalink) Blessing Mahlalela says:\nManaged to do multiple builds by adding additional ANT build steps. Had to configure signing certificates also.\nShai Almog — February 9, 2017 at 8:49 pm (permalink) Shai Almog says:\nYes we do them one by one since they are synchronous. I hope to write a more detailed blog on doing this in a future update just didn’t get around to doing it.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/automating-releases/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/automating-releases/continuous-integration-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOur website deployment has become even more complex thanks to the \u003ca href=\"/demos.html\"\u003edemos section\u003c/a\u003e.\u003cbr\u003e\nThe crux of it is in updating the demos with every small update to the JavaScript build process which is why\u003cbr\u003e\nwe implemented a build option based on the work we did for our \u003ca href=\"/blog/continuous-integration.html\"\u003eCI (Jenkins) integration\u003c/a\u003e.\u003cbr\u003e\nThis work essentially allows to build a Codename One app synchronously which is useful when you want\u003cbr\u003e\nto do things such as continuous integration or release engineering.\u003cbr\u003e\nNotice that the synchronous build feature is an enterprise only feature since its overuse can have a very heavy toll on our servers.\u003c/p\u003e","title":"Automating Releases"},{"content":"\nAs the JavaScript port has matured we started adding new demos specifically for\nthe clock demo,\ncharts \u0026amp; GeoViz. You can now\nsee all of them live on the web and also try the Android or desktop versions of these demos to get a better grasp of\nwhat Codename One can do and how far has the JavaScript build advanced since our 3.0 release.\nPlugin Update We wanted to release the plugin update this week but we ended up postponing to June 1st. As a reminder June\n1st would also be past the deadline for our annual subscription\nrebate promotion as well as the price change for basic subscriptions.\nMake sure to take advantage of existing prices/promotions before that date.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/updated-demo-section-plugin-update/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/updated-demo-section-plugin-update/picture.png\"\u003e\u003c/p\u003e\n\u003cp\u003eAs the JavaScript port has matured we started adding new \u003ca href=\"/demos.html\"\u003edemos\u003c/a\u003e specifically for\u003cbr\u003e\nthe \u003ca href=\"/clock-demo/\"\u003eclock demo\u003c/a\u003e,\u003cbr\u003e\n\u003ca href=\"/charts-demo/\"\u003echarts\u003c/a\u003e \u0026amp; \u003ca href=\"/geoviz-demo/\"\u003eGeoViz\u003c/a\u003e. You can now\u003cbr\u003e\nsee all of them live on the web and also try the Android or desktop versions of these demos to get a better grasp of\u003cbr\u003e\nwhat Codename One can do and how far has the JavaScript build advanced since our 3.0 release.\u003c/p\u003e\n\u003ch4 id=\"plugin-update\"\u003ePlugin Update\u003c/h4\u003e\n\u003cp\u003eWe wanted to release the plugin update this week but we ended up postponing to June 1st. As a reminder June\u003cbr\u003e\n1st would also be past the deadline for our \u003ca href=\"/blog/codename-one-3-0-now-live.html\"\u003eannual subscription\u003cbr\u003e\nrebate promotion\u003c/a\u003e as well as the \u003ca href=\"/blog/aligning-prices.html\"\u003eprice change for basic subscriptions\u003c/a\u003e.\u003cbr\u003e\nMake sure to take advantage of existing prices/promotions before that date.\u003c/p\u003e","title":"Updated Demo Section \u0026 Plugin Update"},{"content":"\nGoogle has just announced that it is deprecating cloud storage and effectively a major part of App Engine that\nwe are relying on. To make matters worse the window of time to its removal is quite short so we don’t have enough\ntime to rewrite and adapt all the various API’s and tools that rely on this API.\nWe have already started the process of migrating off App Engine completely both due to rising costs and Googles\nhorrible service/support. This will also allow us to finally support many long standing user requests such as more powerful\npush API’s etc. since we will no longer be held back by App Engines limitations.\nIn fact our choice to leave App Engine completely was sealed last month as our App Engine expenses skyrocketed…\nThe App Engine console simply stated a cryptic \u0026ldquo;datastore reads\u0026rdquo; number that was very high/expensive. We normally cache\neverything in memcache but still it seems that the number was really high. Unfortunately, this was the only number we had!\nGoogle doesn’t provide any way of knowing which of our queries was responsible for the large number and to this day we have\nno idea what is the actual trigger for this. When we opened a service call they decided that this was a \u0026ldquo;justified\u0026rdquo; charge without\nproviding us with any itemized listing detailing what we are charged for.\nDue to all of that we decided to start a migration process even before the last announcement, this means a lot\nwill change in the backend for Codename One but most of these changes will be seamless and will be made in\npieces that won’t be noticeable. However we have 2 big features that would be very hard to migrate off App Engine:\nCloudStorage and CloudFile.\nWe already worked with the big users of these API’s to help them migrate away as we started planning.\nHowever, we might have missed some smaller users. If you rely on one of these API’s and\nhaven’t been in contact with us please let us know ASAP.\nNotice that as we migrate some services might require that you build a new version of the app, e.g. sending\na log from the device (part of crash protection feature) would migrate seamlessly (and probably improve)\nhowever, you would need to upgrade your users to a new version of the app in order to keep using the feature…\nWe will also need you to update URL’s for services such as push notification etc. as new URL’s become available. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJames David Low — May 26, 2015 at 7:39 am (permalink) James David Low says:\nIsn’t is just the Files API for Google Cloud Storage and the Blobstore that is deprecated? I know this may still effect things, but just clarifying before people get the idea that Google Cloud Storage is going away. A solution I was thinking of doing was calling blobstoreService.createUploadUrl server side and uploading files server side, abstracting away that side of thing from the client.\n\u0026ldquo;The Files API feature used here to write files to Blobstore has been deprecated and is going to be removed at some time in the future, in favor of writing files to Google Cloud Storage and using Blobstore to serve them.\u0026rdquo; – https://cloud.google.com/ap…\nShai Almog — May 26, 2015 at 2:59 pm (permalink) Shai Almog says:\nIts not 100% clear. In my last \u0026ldquo;civil\u0026rdquo; talk with guys from Google they stressed that we should migrate away from Blobstore (naturally pushing for cloud storage which is even worse).\nWe had a few regressions with it in the past which demonstrate that Google doesn’t really do much QA for that API. The basic blobstore API is pretty opaque and we had some issues that we had no way of debugging. Because there is quite literally, no one to talk to at Google the safe thing to do is migrate away ASAP. We can’t take any risks with this since a failure in this API will cause builds to fail.\nYoussef — May 31, 2015 at 6:51 pm (permalink) Youssef says:\nI was about to use APP ENGINE for my new project. Now that i read this, i’m looking for some good alternatives.\nDo you have any suggestions ?\nShai Almog — June 1, 2015 at 9:30 am (permalink) Shai Almog says:\nFor storage we will probably migrate to Amazon S3, it seems pretty simple and ubiquitous. For everything else we will probably use self hosted servers on digital ocean. We played a bit with Jelastic which seems nice but I’m not sure if we are the target demographic for that since our deployment is rather complex.\nWe are moving to a microservices architecture which should make these decisions much simpler and easier to fix in the future.\nchachan — June 30, 2015 at 8:29 pm (permalink) chachan says:\nWe started a project with App Engine but the more we want to add features, the more we find obstacles. In fact, we’re going to code a few more features and we’ll start the migration soon to Digital Ocean. Sad but needed\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/migrating-away-from-app-engine/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/migrating-away-from-app-engine/gaeburn.png\"\u003e\u003c/p\u003e\n\u003cp\u003eGoogle has just announced that it is deprecating cloud storage and effectively a major part of App Engine that\u003cbr\u003e\nwe are relying on. To make matters worse the window of time to its removal is quite short so we don’t have enough\u003cbr\u003e\ntime to rewrite and adapt all the various API’s and tools that rely on this API.\u003cbr\u003e\nWe have already started the process of migrating off App Engine completely both due to rising costs and Googles\u003cbr\u003e\nhorrible service/support. This will also allow us to finally support many long standing user requests such as more powerful\u003cbr\u003e\npush API’s etc. since we will no longer be held back by App Engines limitations.\u003c/p\u003e","title":"Migrating Away From Google App Engine"},{"content":"\nOur build servers are really fast, even if your laptop is relatively slow our iOS build servers are powerful machines\nequipped with fast SSD’s and they generate a full clean build of a typical app (with screenshots etc.) in a couple of minutes!\nSo the real source of delay when building an app is size, it both slows the build but most of all it slows your upload\nprocess (upload is typically much slower than download). Reducing the size of your app will make it faster in runtime\nas well, e.g. if you have too many redundant resources you might be running into too many GC cycles slowing\ndown execution. In this post we provide some tips to shrink your app size.\nCompress JAR When we released Codename One’s beta we released a version that didn’t compress the built JAR. This wasn’t\na big deal for small projects but it became an issue as Codename One applications grew. Make sure that the JAR\noutput is compressed, so that server builds would be significantly smaller. This is crucial since it reduces upload\ntime in the client side which is a huge contributor to the total build time.\nNotice that apps created in the past year should have this on by default but its always important to check.\nInspect the Sent JAR When optimizing the jar size its often hard to see where to begin. After you send a build if you open your dist folder\n(or bin folder for Eclipse) you will see what seems to be the jar of your application. However, in this case its the jar\nthat was sent to the server including the native bits that need to be compiled on the server side.\nYou can use a zip utility such as 7-zip to inspect the content of the jar and see what takes up space and how\nwell are files compressed. Its possible that a specific file within the zip isn’t supposed to be there and its possible\nthat things can be shrunk further.\nShrinking Resources The most likely case for a large file is the resource file and here there are two distinct tasks: finding out what is taking up\nthe space and reducing the size. For the former we have Image-\u0026gt;Image Sizes, in the designer\ntool. It returns the list of images ordered by the space they take up in the resource file, since images can’t be further\ncompressed they are the biggest space hog in the resource file.\nUnless you found a specific image that takes up most of the space its probable that space is taken up by many\nmulti-images. Multi-images are essentially a single image in multiple resolutions for different device densities,\nthese images can grow to a very large size as we store a lot of resolutions for every such image. If there are densities\nyou don’t need such as LOW \u0026amp;amp VERY_LOW (both of which don’t exist in smart devices) you can just delete\nall of these images from existing multi-image’s thru the menu item: Image-\u0026gt;Advanced-\u0026gt;Remove DPI.\nImage-\u0026gt;Delete Unused Images presents you with a dialog containing the images that are unused.\nIt allows you to select the images you wish to delete (all are selected by default). Notice that this method was designed for\nGUI builder applications and doesn’t scan the code for image usage. It will also miss images from code although it tries\nto scan the state machine class intelligently. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJeff Brower — October 18, 2015 at 1:22 pm (permalink) Jeff Brower says:\nI am impressed that I received an email from you directing me to this link when my build went over size. Anyone else would just consider a great opportunity to upsell me and not be so helpful. I was disappointed that I ran over my maximum size by just doing a straight compile of one of the sample CodenameOne programs in Netbeans (even though it was Kitchen Sink), but now I know why and how to fix it!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/shrinking-sizes-optimizing/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/shrinking-sizes-optimizing/compress-jar-netbeans.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOur build servers are really fast, even if your laptop is relatively slow our iOS build servers are powerful machines\u003cbr\u003e\nequipped with fast SSD’s and they generate a full clean build of a typical app (with screenshots etc.) in a couple of minutes!\u003cbr\u003e\nSo the real source of delay when building an app is size, it both slows the build but most of all it slows your upload\u003cbr\u003e\nprocess (upload is typically much slower than download). Reducing the size of your app will make it faster in runtime\u003cbr\u003e\nas well, e.g. if you have too many redundant resources you might be running into too many GC cycles slowing\u003cbr\u003e\ndown execution. In this post we provide some tips to shrink your app size.\u003c/p\u003e","title":"Shrinking Sizes \u0026 Optimizing"},{"content":"\nWith the release of 3.0 we were overwhelmed with a lot of last minute features and improvements. It seems\nthat we neglected to mention a lot of features that made it into the final 3.0 product.\nOne of the nicest new features is a set of new flat themes with various colors in the designer and the project\nwizard. We found that a lot of developers prefer themes with more control over the look, themes that look\nmore similar across platform yet have a more modern \u0026ldquo;flat\u0026rdquo; feel.\nA long time request has been to add the additional DPI resolutions we added for higher density devices into\nthe designer tool. We now support these additional densities in the designer tool both in the multi image import\nand when editing a specific resolution.\nOn a different subject, we noticed a couple of developers had one of those hard to track down bugs that boiled\ndown to using the FileSystemStorage API from static context. E.g. this:\npublic static final String MY_HOME_DIR = FileSystemStorage.getInstance().getAppHomePath(); This seems like code that should work and annoyingly enough it works on the simulator. However, because of the\nway classloaders work this code will probably fail on devices. Static context can be initialized at any time and since\nthe initialization of the implementation code might occur after the initialization of static context the static variable\nmight not work well…\nYou should pay attention to such code where you invoke implementation classes from static context and try to avoid\nit, ideally we’d make this fail on the simulator but that is a bit tricky. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nrhg1968 — May 13, 2015 at 6:48 pm (permalink) rhg1968 says:\nI see the new templates in NetBeans but not in IntelliJ 14.1.3\nShai Almog — May 14, 2015 at 6:52 pm (permalink) Shai Almog says:\nCan you file an issue on that?\nWe’ll need to add them there too. As a workaround you can just create a new project with a native theme. Open the designer tool, delete the \u0026ldquo;Theme\u0026rdquo; entry and create a new theme, you should have these options there assuming you are using the latest plugin.\nrhg1968 — May 14, 2015 at 7:01 pm (permalink) rhg1968 says:\nThanks for the reply. I just put the issue on GitHub. I am using plugin 3.0.2 and I don’t have any updates so I believe I am using the latest. I also refreshed the libraries but I don’t see the theme in the GUI builder if I try to add a new theme to an existing project.\nShai Almog — May 15, 2015 at 9:48 am (permalink) Shai Almog says:\nIts possible the IDEA plugin doesn’t update the designer to the latest version too. We’ll look into it as part of the bug.\nJ.C — May 15, 2015 at 3:04 pm (permalink) J.C says:\nShai, to clarify about static initializers for some people, it would be clearer to enclose the statement you illustrated inside static {}.\nFor example, is this what you mean?\nAvoid:\npublic static final String MY_HOME_DIR;\nstatic {\nMY_HOME_DIR = FileSystemStorage.getInstance().getAppHomePath();\n}\nIf not, please clarify and include an example that says: Don’t {….} and Do{…} etc..if its not too much trouble :).\nShai Almog — May 15, 2015 at 4:24 pm (permalink) Shai Almog says:\nThat would be a problem. Use a getter that invokes that method. Don’t store it in that static context.\nJ.C — May 15, 2015 at 5:45 pm (permalink) J.C says:\nHmm, so what you are saying is, in general, avoid storing values returned by methods that is initializing underlying platform implementations into static variables when a class is created?\nShai Almog — May 16, 2015 at 8:51 am (permalink) Shai Almog says:\nNo. Avoid access to Codename One API’s from static context since it might get initialized before the Codename One API gets initialized.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/flat-themes-dpis-static-initializers/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/flat-themes-dpis-static-initializers/flat-blue-theme.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWith the release of 3.0 we were overwhelmed with a lot of last minute features and improvements. It seems\u003cbr\u003e\nthat we neglected to mention a lot of features that made it into the final 3.0 product.\u003cbr\u003e\nOne of the nicest new features is a set of new flat themes with various colors in the designer and the project\u003cbr\u003e\nwizard. We found that a lot of developers prefer themes with more control over the look, themes that look\u003cbr\u003e\nmore similar across platform yet have a more modern \u0026ldquo;flat\u0026rdquo; feel.\u003c/p\u003e","title":"Flat Themes, DPI's \u0026 Static Initializers"},{"content":"\nOur pricing has been inconsistent with the rest of the industry for quite some time specifically the price of the\nbasic subscription which is a losing tier. Based on Industry norms the basic subscription should be far more\nexpensive and doesn’t come close to covering the costs of running Codename One’s extensive cloud\ninfrastructure. So on June 1st we will raise the price of the basic subscription to 19USD which is still very\naffordable. Notice that if you are a current subscriber or sign up before June 1st you can keep paying\nat the 9USD rate!\nHowever, if you let your subscription lapse we will not be able to recover it and you would need to switch to the 19USD\nlevel…\nThis is an important step for the health of the company as the costs of hosting our infrastructure are growing fast\nand basic subscriptions just aren’t carrying the weight.\nAs part of this move we also analyzed our build server usage and noticed many developers in the free tier who\nplace a very heavy toll on the build servers with long builds that eventually cost in service degradation to everyone.\nThat is one of the reasons we originally made the iOS build quota so limiting…\nSo we are now reducing the credits for iOS builds to 8 credits per build (from 20) but also placing a size quotas on\nbuilds from free users to reduce both our storage costs and build times (upload/download and server instance costs).\nWe are sure this step will improve performance for everyone involved and help people try Codename One before\ncommitting to a paid account. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMaaike Z — May 12, 2015 at 7:43 pm (permalink) Maaike Z says:\nI understand the price change, but I’m not happy with it (I do this as a hobby). For a company this is ‘nothing’ of course. But why don’t you make offline building easier? Then you don’t need the expensive infrastructure (or at least users place less toll on the build servers).\nShai Almog — May 13, 2015 at 4:27 am (permalink) Shai Almog says:\nThat’s why we increased the free quota for iOS builds to make it easier on the hobbyist crowd to work without a subscription at all.\nSome people seem to think we have an ability to build offline, we send builds to the build servers just like everyone else… Offline building is technically impractical since the build process is so complex, fluid and has so many dependencies.\nAnd don’t get me started on manpower costs… Offering things for free doesn’t keep the lights on in any company.\nFabrício Cabeça — May 13, 2015 at 7:39 pm (permalink) Fabrício Cabeça says:\nHi Maaike, I think you may be understimating the offline building\ncosts, and you should add to it your own time to keep your offline build\nserver(s) up to date with all SDKs. I have a pro account and I have the\nknowledge and a minimal infrastructure that could be used to create\noffline build servers, but I prefer to focus in the development itself, that’s what codenameone is all about.\nMaaike Z — May 15, 2015 at 1:52 pm (permalink) Maaike Z says:\n@codenameone:disqus : I totally understand that you can’t offer everything for free. It’s impossible for a company to do everything for free. That doesn’t wipe away my wish to have a good product for less :).\n@fabriciocabeca:disqus I wish I could choose. I have time to make a build server and if everything is set up well once, I only have to keep everything up to date. Sometimes I prefer to have my own server to be not dependent of Codename One (that’s actually one of the drawbacks for me, the dependence of the company).\nJ.C — May 15, 2015 at 3:09 pm (permalink) J.C says:\nSo, just to clarify, if I pay 9USD before end of this month, how much will I pay at end of June? 19USD or still 9USD? Also, why don’t you also include an option for annual or 6 month subscriptions for Basic users to help us save cost for monthly transactions fees?\nShai Almog — May 15, 2015 at 4:26 pm (permalink) Shai Almog says:\nYes.\nWe didn’t provide annual subscriptions because they won’t save much on the basic level (19 is still pretty low) you do have a point though, its something we should add.\nJ.C — May 15, 2015 at 5:49 pm (permalink) J.C says:\nSorry you didn’t answer my question, 19USD or 9USD?\nChen Fishbein — May 16, 2015 at 6:07 am (permalink) Chen Fishbein says:\nif you are a current subscriber or sign up before June 1st you can keep paying at the 9USD\nMaaike Z — May 21, 2015 at 9:15 pm (permalink) Maaike Z says:\nWhat about the 1mb quota for not subscribed users? Is it de jar sent to the server with a max quota of 1 mb or the final app or … ?\nShai Almog — May 22, 2015 at 3:44 am (permalink) Shai Almog says:\nThat email was poorly worded IMO. It was sent without my review.\nThe limit applies to the built JAR before sending otherwise it would be meaningless since the servers would have had to do all the work (and wasted the paid quotas we are spending) so there would have been no saving.\nTo be clear we didn’t just pull out that number, we reviewed the sizes of free user builds coming in and concluded that well over 90% would fit under this limit right now or with very small modifications. The goal is to stop the outliers so we can provide essentially more quota (e.g. increased iOS build credits). Things like the kitchen sink demo which is really wasteful (several huge themes, a video etc.) will not fit, but its not a common app.\nEric — May 22, 2015 at 9:31 am (permalink) Eric says:\nThe resource file can only have the theme which can be bigger than 1Mb. This resource file is always added to the jar file before sending so the problem persist because a very simple app with a custom theme will not fit too because of the size of the theme file. How can you resolve that?\nShai Almog — May 22, 2015 at 10:14 am (permalink) Shai Almog says:\nYou can dynamically download a theme on the device to workaround that but yest that is something that won’t work as well…\nMost themes should be optimizable see: http://codenameone.com/blog…\nUnfortunately more elaborate themes won’t make it in. The main problem is that we can’t really tell how large your code is and how large the theme is (before doing all the work) and even if we could it would still cost us quite a bit more to build/host larger files. We tried to draw a line that makes sense for most and would allow us the leverage to increase build quotas which we felt were lacking.\nhuwab0 — May 22, 2015 at 10:15 am (permalink) huwab0 says:\nThis effectively kills my project.\nOur project is much larger than 1MB because we suppy a chinese font and several word and character lists.\nI rarely build on the server, so I wouldn’t mind if big jars cost more build credits!?\nEric — May 22, 2015 at 10:32 am (permalink) Eric says:\nShai, you must make a poll to users to know if they want more ios buid quotas or more app size. It’s not good to decide for users. If you cannot know the size of the code in the jar file so your first answer is not the right answer. You can not limit us if you cannot just track the size of our code without the resource file. This a serious problem that you create for developers\nChen Fishbein — May 22, 2015 at 10:56 am (permalink) Chen Fishbein says:\nResource files when packaged to the jar are reduced by size, besides plenty of complex themes are in the 400-500k range uncompressed.\nThis should be sufficient for a user to properly evaluate the product before he/she commits to a paid account.\nThis is a crucial step for the health of the company we need the heavy users to start and help us pay the bills $9 or even $19 is pretty valuable for the product and service we provide.\nChen Fishbein — May 22, 2015 at 10:58 am (permalink) Chen Fishbein says:\nI hope paying $9 or even $19 for our service shouldn’t be the mortal point to your project\nhuwab0 — May 22, 2015 at 1:00 pm (permalink) huwab0 says:\nActually, we try to make our project break even, but since there is hardly any money in our kind of applications, actually all costs need to be avoided.\nrhg1968 — May 22, 2015 at 1:04 pm (permalink) rhg1968 says:\nI for one totally support this change and understand why it is necessary. Codename one has been more than generous allowing you to build production applications for free for years. A company can’t go on this way forever and afford to stay in business and improve the system. I think it’s great that the free tier will still give people a lot so that they can truly evaluate the platform. I also think it’s more than generous to offer us the 9 price before raising the price. I have subscribed to the basic level now and look forward to developing with Codename one.\nBenjamin Vander Stichelen — May 23, 2015 at 2:35 am (permalink) Benjamin Vander Stichelen says:\nThis will kill the project i’m working on, when creating the app every 2-3 updates creates a bug and time to investigate what went wrong.\nI understand that every company needs adjustments. Buth why don’t do it like google.\nThe existing accounts don’t get changes the new accounts get limitations.\nWhen google decides to remove the project it’s removed buth meanwhile it’s on you got it like it was from the beginning for you.\nI’m surious to need to say that when they ask me would you do it again with codenameone the answer is no.\nThat’s my opinion, now you are forcing us to do it from now on with the existing proyect.\nGreeting,s\nChen Fishbein — May 23, 2015 at 5:37 am (permalink) Chen Fishbein says:\nI understand the frustration, but in order to keep on providing the product and service in high quality the heavy accounts needs to start and pay.\nI hope we do become google one day, but even google when they change their terms or cancel projects it will effect all their users.\nWe might consider exceptions in special cases, feel free to reach out to me.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/aligning-prices/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/aligning-prices/pricing-change.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOur pricing has been inconsistent with the rest of the industry for quite some time specifically the price of the\u003cbr\u003e\nbasic subscription which is a losing tier. Based on Industry norms the basic subscription should be far more\u003cbr\u003e\nexpensive and doesn’t come close to covering the costs of running Codename One’s extensive cloud\u003cbr\u003e\ninfrastructure. So on June 1st we will raise the price of the basic subscription to 19USD which is still very\u003cbr\u003e\naffordable. Notice that \u003cstrong\u003eif you are a current subscriber or sign up before June 1st you can keep paying\u003cbr\u003e\nat the 9USD rate!\u003c/strong\u003e\u003cbr\u003e\nHowever, if you let your subscription lapse we will not be able to recover it and you would need to switch to the 19USD\u003cbr\u003e\nlevel…\u003c/p\u003e","title":"Aligning Prices"},{"content":"\nOur iOS port has some pieces that are pretty old and haven’t been touched since we started, one of those things\nis the IO code which mostly works as we wrote it when we started Codename One. Unfortunately it seems that\nStorage in iOS is mapped to the iOS caches directory, this directory can be wiped by the iOS device if space\non the device is running low. That’s a very rare occurrence which is why we didn’t pick that up until a\nbug report was filed on it this week…\nUnfortunately fixing Storage to point at the right directory would mean breaking compatibility and your app\nlosing all the data it kept in storage… So we decided to go about this in a rather creative way.\nWe defined a new build argument which will be on by default for all new projects: ios.newStorageLocation\nThis build argument effectively means that we should use the documents directory as storage and the app is ready\nto deal with it. Its useful for apps that aren’t already in users hands. If you don’t define that flag we will automatically\nmigrate the app to the documents directory on the first usage of Storage, we will detect if our\nstorage directory exists under documents and if not we will move all files to that directory. This should maintain\ncompatibility with a small performance overhead on the first activation for new installs and possibly the first\ntime this code occurs in a pre-existing app. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMaaike Z — May 6, 2015 at 5:58 pm (permalink) Maaike Z says:\nIs it a boolean? So ios.newStorageLocation = true when I want to use the new location?\nShai Almog — May 7, 2015 at 4:09 am (permalink) Shai Almog says:\nYes it should be true/false (notice its not yet on the servers and will be there before the weekend).\nWe already documented it in the manual section: http://www.codenameone.com/…\nkazza186 — August 2, 2016 at 9:59 am (permalink) kazza186 says:\nHas there been a change with this? I’ve just found this because I’m having the exact problem where data is being wiped on iPhones with low storage space, but I never defined this hint so shouldn’t it be using Documents directory? My files are being stored in Library/caches when I use the codename one file storage. Is that correct? How do I switch it to use the Documents? Thanks.\nShai Almog — August 3, 2016 at 4:54 am (permalink) Shai Almog says:\nNo. The build hint should be defined there by default. Which IDE are you using?\nWhen did you create the project and which project type did you select?\nCheck the FileSystemStorage.getRoots values on the device. Print them to a dialog or log. They should be arranged as documents first and caches second. If not then the build hint isn’t turned on for some reason.\nkazza186 — August 4, 2016 at 4:21 am (permalink) kazza186 says:\nPrinted it to a Dialog without the build hint added. Cache was first, then Documents. Have added the build hint now and it’s using Documents instad of Cache which is good.\nI’m using Eclipse, created the project in January 2016. I can’t remember which project type I used sorry.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/storage-migration/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/storage-migration/iOS.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOur iOS port has some pieces that are pretty old and haven’t been touched since we started, one of those things\u003cbr\u003e\nis the IO code which mostly works as we wrote it when we started Codename One. Unfortunately it seems that\u003cbr\u003e\nStorage in iOS is mapped to the iOS caches directory, this directory can be wiped by the iOS device if space\u003cbr\u003e\non the device is running low. That’s a very rare occurrence which is why we didn’t pick that up until a\u003cbr\u003e\n\u003ca href=\"https://github.com/codenameone/CodenameOne/issues/1480\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ebug report was filed on it this week\u003c/a\u003e…\u003c/p\u003e","title":"Storage Migration"},{"content":"\nWhen building to the JavaScript target there are many build options and configurations. More importantly\nissues like cross origin need server side code that would be able to proxy such requests to make the\nclient side code seamless…\nSteve wrote a rather detailed appendix to the developer guide\ncovering all of those options from startup splash screen configuration to servlet proxy logic. The build also generates\na ready to deploy WAR file which should make setting this up on any Java servlet container a nobrainer.\nDuring our work on the developer guide for 3.0 we updated the\nbuild hints section with many\npreviously undocumented hints and also updated the\ntheme constants section in a similar way.\nHopefully, this will allow us to keep them up to date more easily as we add them in the future. This week\nwe also updated the Codename One Designer constants combo box with all the documented constants.\nIssues with the current release The current plugin has two annoying bugs, the first of which is a regression in test execution which should be\nresolved and will be a part of the next update. However, the second is slightly more annoying….\nIt seems that our code for packaging the demos into the plugin had a bug where it didn’t override the build.xml\nwith the latest/current build XML and it got a debug version of that file from my local version of the kitchen sink.\nIf you create the kitchen sink demo using the current plugin keep in mind that this won’t work for sending an Android\nbuild. This should be fixed for the next plugin update and shouldn’t affect other plugins. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nKL — May 8, 2015 at 12:38 pm (permalink) KL says:\nHi,\nI tried this Javascript port, it is excellence, you cannot imagine 95% of my android apps runnable without any modification.\nThe current problem is the ConnectionRequest cannot do POST request. I have to adjust all my ConnectionRequest to GET.\nSecond issue is, the \u0026ldquo;KeyListener\u0026rdquo; not working. The compiled JS apps just dont listen to the key pressed.\n`\nf.addKeyListener(‘a’, new ActionListener() {\npublic void actionPerformed(ActionEvent evt) {\nString strChar = getChar(evt.getKeyEvent());\nSystem.out.println(\u0026ldquo;Key \u0026quot; + evt.getKeyEvent() + \u0026quot; pressed,getChar() = \u0026quot; + strChar);\nevt.consume();\n}\n});\n`\nWhich is working in android/iphone emulator properly.\nHope this issues makes help for those fantastic JS port developer.\nshannah78 — May 8, 2015 at 4:55 pm (permalink) shannah78 says:\nAre you running your app through the single-file preview on the build server, the ZIP distribution, or the WAR distribution. The \u0026ldquo;single-file\u0026rdquo; preview uses a simplified proxy script for use on App Engine that may have trouble with some requests… I haven’t tested it with POST yet. If you use the WAR distribution, it comes bundled with a better proxy that should handle POST (though haven’t actually tested that either — but it is based on a well-established Proxy servlet that claims to handle POST).\nI haven’t implemented key listeners on the form yet. Please post both of these issues (separately) into the issue tracker so I don’t forget to look into them when the time comes.\nKL — May 9, 2015 at 10:11 am (permalink) KL says:\nI am using zip file, and unzip them to my origin server root, and browse directly to my server.\nI have posted to issue tracker, separately.\nBy the way, how soon this javascript port will be in BETA?\nThank you shannah.\nshannah78 — May 9, 2015 at 3:31 pm (permalink) shannah78 says:\nAre the POST requests being sent to the same host as the index.html file is being served on, or a different server? If a different server, you’ll need to set a proxy servlet as described here https://www.codenameone.com…\nThe Javascript port will be in beta by July.\nKL — May 10, 2015 at 12:56 pm (permalink) KL says:\nShannah, may I know which component that you already implement key listener? I try to use TextField to handle the key event, but it just fell not so direct as Form. Possible with Label?\nShai Almog — May 10, 2015 at 2:11 pm (permalink) Shai Almog says:\nKey events aren’t sent on Android (unless the Android device has a physical keyboard) or iOS since they are restricted to physical keys and not virtual keyboards.\nTo follow input in text fields you can use DataChangeListener.\nKL — May 10, 2015 at 3:09 pm (permalink) KL says:\nYes you are right, I try to use hardware keyboard to do data entry, which allow user additional option for data entry. It is working fine in android, but not in JS port, yet.\nDatachanger listener cannot detect ‘Enter’ key, I use with actionListener to detect enter key. But the problem is, I have to press \u0026ldquo;Enter\u0026rdquo; twice (first to end edit mode, second enter only trigger actionListener) then only can grab the \u0026ldquo;enter\u0026rdquo; key. This is confusing user. Somemore, after the first enter, the textfield cursor ‘drop’ to newline, even I set true to singleline edit, this make the entered words ‘disapear’..\nCan you advice any trick to overcome this issue? Or any other component can have keylistener, before shanna implement the keylistener on the form?\nYour advice is much appreciated.\nshannah78 — May 11, 2015 at 5:01 am (permalink) shannah78 says:\nI haven’t implemented key listeners at all yet. DataChangeListener should work, and is tested to work with a soft keyboard on android, on desktop, on iOS with both a soft keyboard and a hardware keyboard. I haven’t tested android with a hardware keyboard yet. There may be a bug there. Please file an issue on this in the issue tracker and post a minimal test case.\nKL — May 11, 2015 at 8:05 am (permalink) KL says:\nCan you please advice where should I file yhe issue tracker? Any ETA of the BETA of this JS port?\nThanks!\nShai Almog — May 11, 2015 at 2:35 pm (permalink) Shai Almog says:\nBeta should be ready by June. See https://github.com/codename…\nKL — May 28, 2015 at 9:17 am (permalink) KL says:\nHi, Shai, I understand the javascript port will be updated on 1/JUN, may I know is the keylistener implemented currently? Can I try now?\nShai Almog — May 28, 2015 at 6:53 pm (permalink) Shai Almog says:\nWe update the JavaScript port a few times a week. If an issue exists and was marked fixed it will take less than a week for it to reach production. I suggest you follow up in the issue tracker on github.\nKL — May 29, 2015 at 7:09 am (permalink) KL says:\nLook like I wrongly post this issue to googlecode previously. Thats why this issue still there.\nI just post to github with the title \u0026ldquo;Javascipr port, form not support keylistener #1516\u0026rdquo;\nJust hope this issue can be fixed.\nThank you.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/javascript-port-cross-origin-hints-bugs/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/javascript-port-cross-origin-hints-bugs/html5-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen building to the JavaScript target there are many build options and configurations. More importantly\u003cbr\u003e\nissues like cross origin need server side code that would be able to proxy such requests to make the\u003cbr\u003e\nclient side code seamless…\u003c/p\u003e\n\u003cp\u003eSteve wrote a rather detailed \u003ca href=\"/manual/appendix-javascript.html\"\u003eappendix to the developer guide\u003c/a\u003e\u003cbr\u003e\ncovering all of those options from startup splash screen configuration to servlet proxy logic. The build also generates\u003cbr\u003e\na ready to deploy WAR file which should make setting this up on any Java servlet container a nobrainer.\u003c/p\u003e","title":"JavaScript Port Cross Origin, Hints \u0026 Bugs"},{"content":"\nWe are working on a new demos section for the website that will highlight the demos for\nCodename One more thoroughly. Thanks to the new JavaScript port we can actually show the demos live in\naction but that creates a bit of a problem since people often jump to the conclusion that Codename One\nuses web technologies which it does not.\nCurrently the demos section is pretty bare mostly because the JavaScript port still has a lot of bugs and missing\nfeatures. It is moving in leaps and bounds though and we are pretty confident that we will have all the major\ndemos up in the demo section within a short while. However, if you are familiar with the existing demos checking\nout their JavaScript counterpart (and the desktop builds as well) will show you what we can accomplish with these\nports.\nDeveloper Guide Translation A comment on our developer guide announcement\ncaught us a bit by surprise. It seems a community member\ntranslated the guide to Russian\nwhich is pretty cool!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/demo-section-russian-guide/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/demo-section-russian-guide/picture.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are working on a new \u003ca href=\"/demos.html\"\u003edemos\u003c/a\u003e section for the website that will highlight the demos for\u003cbr\u003e\nCodename One more thoroughly. Thanks to the new JavaScript port we can actually show the demos live in\u003cbr\u003e\naction but that creates a bit of a problem since people often jump to the conclusion that Codename One\u003cbr\u003e\nuses web technologies which it does not.\u003c/p\u003e\n\u003cp\u003eCurrently the demos section is pretty bare mostly because the JavaScript port still has a lot of bugs and missing\u003cbr\u003e\nfeatures. It is moving in leaps and bounds though and we are pretty confident that we will have all the major\u003cbr\u003e\ndemos up in the demo section within a short while. However, if you are familiar with the existing demos checking\u003cbr\u003e\nout their JavaScript counterpart (and the desktop builds as well) will show you what we can accomplish with these\u003cbr\u003e\nports.\u003c/p\u003e","title":"Demo Section \u0026 Russian Guide"},{"content":"Codename One 3.0 Release Notes Home 3.0 Release Notes Summary Version 3.0 is a major leap in Codename One\u0026rsquo;s mission of mobile write once run anywhere, its highlights include a completely rewritten VM for iOS advanced API\u0026rsquo;s and a new JavaScript target that officially makes Codename One the most ubiquitous WORA (Write Once Run Anywhere) platform in the market today.\nHighlights - Click For Details New iOS VM\nWhen Codename One debuted we used XMLVM as the underlying iOS virtual machine abstraction. XMLVM is an excellent product but its unmaintained and its goals are too different from the goals of Codename One. The new VM includes some features that would be remarkably hard to achieve with XMLVM such as: proper stack traces, faster builds (2x overall!), smaller code size, concurrent GC, deep OS binding (String - NSString relationship) etc. Read more about this work on the announcement blog.\nJavaScript build target (technology preview)\nAllows compiling Codename One applications to JavaScript client side webapps without server side code. Notice that this support includes threading support. Notice that this feature will be restricted to enterprise developers once it enters beta. The Java VM work is based on TeaVM an OSS Java-JavaScript VM.\nRead more about this work in this blog post.\nCharts API\nThe charts API supports drawing a wide range of charts such as bar, pie, line etc. It supports animating charts and is based on the aChartEngine Android API. Read more about this work on Steve\u0026rsquo;s blog post.\nNew Demos\nProperty Cross - Browse properties for sale in the UK using a JSON webservice. Shows off JSON webservices, InfiniteScroll, URLImage etc. Dr Sbaitso - Demonstrates an AI bubble chat interface, includes text to speech using native interface and more. Photoshare - A simple social networking app that allows sharing photos Charts - Demonstrates all chart types Geoviz - Performs statistic analysis over US population based on locale specific data Flickr - Demo for the Toolbar class showing special title area effects New Themes\nNew beautiful and functional themes are now available through the plugins and the designer tool.\nToolbar API\nMore advanced and highly customizable API for handling the title area. It allows adding search to the title, animating its appearance/folding, placing commands arbitrarily and using the side menu. Read more about this work on this blog post.\nURLImage\nSimplified image download to an icon or preview, that allows to implicitly apply special effects to said image (e.g. round corners, scaling etc.). Read more about this work on this blog post.\nBuilt demos into the Eclipse/NetBeans Plugins\nThe main Codename One demos are now built-into the plugin so you can try them immediately without fixing classpaths and without downloading additional software.\nNew Android graphics pipeline\nWe rewrote the graphics pipeline on Android to work better in Android 4.x+ and use hardware acceleration where applicable. This new pipeline also includes support for the Shape \u0026amp; transform API\u0026rsquo;s. Read more about this work on this blog post.\nRegular expression and validation support\nWe added a new regular expression package and a new validation framework that simplifies error highlighting for input. As part of that work we also presented a rudimentary masked input UI. Read more about this work on this blog post.\nHigh DPI Image Support\nThere are 3 new DPI levels in Codename One all of which are now supported by the designer: DENSITY_560, DENSITY_2HD \u0026amp; DENSITY_4K.\nSupport for opening HTML files with hierarchies \u0026amp; Tar support\nThe builtin HTML support was improved by providing a way to open a hierarchy of files and not just a self contained HTML file. As part of this improvement we also added support to the tar file format. Read more about this work on this blog post.\nNew Morph \u0026amp; Flip Transitions\nThe morph transition was inspired by the Material design UI, converting a component on one form to a component on another form. The flip transition provides an impressive 3d effect thats trivial to apply to any form or transition.\nInteractionDialog\nA new \u0026ldquo;modless\u0026rdquo; dialog that can \u0026ldquo;float\u0026rdquo; on top of the UI using the layered pane capability of the parent form Read more about this work on this blog post.\nSignificantly enhanced developer guide\nWe redid the developer guide from the ground up converting it to asciidoc and integrating it into the website in a more fluent way. We increased its breadth by over 50%. Check it our here or download the pdf.\niOS Beta Test Support (testflight)\nApple introduced a new way to test mobile applications for up to 1000 beta testers based on the testflight framework (but not to be confused with the old testflightapp.com product). We now support distributing apps via this process for pro users. Read more about this work on this blog post.\nMiG layout support\nMiG layout is one of the popular cross platform Java layout managers that works across FX, Swing, AWT and now on Codename One as well\u0026hellip; Read more about this work on this blog post.\nFacebook improvements such as publish support \u0026amp; version 2.0 API\nFacebook made a lot of changes to its API such as requiring a special publish permission and migrating graph calls to version 2.0. Both are now integrated into Codename One.\nAdded webservice wizard to simplify client-server calls\nThe webservice wizard allows us to generate RPC calls to the server including servlet and client stubs. Read more about this work on this blog post.\nSupport for badging the native OS icon on iOS\nWe now support updating and setting a badge on an app icons in iOS devices. Read more about this work on this blog post.\nTCP socket support\nWe finally added support for TCP sockets into Codename One. Read more about this work on this blog post.\nAdvanced keyboard input in iOS that doesn\u0026rsquo;t fold implicitly\nThis is an implementation of a feature that was requested quite a while back. Historically, when moving from one text field to the next the VKB would fold and reopen. We now allow you to seamlessly move between input fields.\nDetails Memory issue with downloading large files caused by native downloading overwhelming the gc. Fixed issue with picker type strings not remembering selected value. https://github.com/codenameone/CodenameOne/issues/1433 Fixed double toString precision issue. https://github.com/codenameone/CodenameOne/issues/1432 Fix for potential memory leak when downloading. Allowed separating the version number from the build number Made some improvements for issue 1272: SwipeBackSupport not working properly But this seems to be an inherent problem that\u0026rsquo;s not easy to fix. Minor improvements to test util Fix for null pointer press argument in generated test case Merged pull request #1441 from sdwolf/feature/add_cntest_methods Added different assertion methods to AbstractTest and TestUtils Fix for issue #228: ComboBox setCommandList() has no effect. Fix for issue #253: An option to reset location of optipng Added new themes templates Fix for issue 1032: Switch of OnOffSwitch disappears after double-click while in \u0026ldquo;on\u0026rdquo; state. Added the assertion methods to AbstractTest and TestUtils Fix for issue 1031: on-off switch had ends with 3 points enabled Implemented RFE 1060 InfiniteScrollAdapter doesn\u0026rsquo;t provide a removeComponent method Fixed picker to localize the strings Fixed changing SpanLabel style via code issue 1101 Fix for RFE 1123: Add short function key (f1,f2,f3..) to screen capture on the simulator Fix for RFE: optimization in Display class issue 1127 Updated themes templates in the designer Fix for #1420 - Relative file paths should throw an exception in the simulator Fix for #1436 - Android Date Picker \u0026ldquo;Cancel\u0026rdquo; button click disabled the component Fixed issue #1230 - Network monitor in simulator shows HTTP method as \u0026ldquo;GET\u0026rdquo; when method actually used was \u0026ldquo;HEAD\u0026rdquo; Fix for #1418 - Wrong ComboBox height in Android after screen keyboard hiding Wrong ComboBox height in Android after screen keyboard hiding #1418 Better scrolling while dragging #1412 Tar and html hierarchy support New package to support tar Support for opening HTML files with hierarchies Fix for issue #1403 - Tensile Drag - in X+Y direction Fix for #1295 - On DateTimeSpinner can localize only the month, not the day. Fix for #1417 - Scrolling container locks into visible region at either end of container, with 2 quick scroll/drag gestures Scrolling container locks into visible region at either end of container, with 2 quick scroll/drag gestures. #1417 Added flat Orange theme Fixes for the VM mostly around issue 1426 Fix for issue 1426 which was triggered by removing the 1D array when only the 2D array exists Fixed a compilation issue regression due to changes in the project hierarchy. Fixed issue with iOS not being able to delete cookies. Issue https://github.com/codenameone/CodenameOne/issues/1422 Fix for fillRect transparency issue. https://github.com/codenameone/CodenameOne/issues/1419 Added flat red theme High DPI Image Support Added flat blue theme Fix for issue #1421 - Android Date/ Time Picker \u0026ldquo;Cancel\u0026rdquo; button click disabled the component Attempted fix for issue 1423, small refactoring to classes so they will pass thru the Blackberry translation code Fix for issue 1416 memory leak after prior GC fix for very short lived objects Reduced overhead per component by removing an event dispatcher on focus that might not be necessary Major performance bottleneck improvement. Creating image arrays on every getPreferredSize() call! Improved removing of references and logging Improved removing of references to prevent GC race conditions Fixed issue with drawArc/fillArc in iOS. Fixed issues with Purchase.getProducts() hanging if there is a network error or if a product name comes back as null. Issue https://github.com/codenameone/CodenameOne/issues/1408 Added docs for wasPurchased(). Issue https://github.com/codenameone/CodenameOne/issues/1409 Fix for iPad splash screen problem in iOS8. Issue https://github.com/codenameone/CodenameOne/issues/1381 Missed some UIManager code in the previous commit Initial commit of a simple validation framework and the old regex API that Steve ported from the Apache project Fixes for Issue 1414: Spanning columns of Table component does not work properly Fix for landscape mode corrupted view. Issue 1412 Fixed in-app purchase problems with wasPurchased and getProducts. Issues 1409 and 1410. Fixed iOS video pause behaviour. Improved performance for gallery on desktops with very large files. Fix for nullpointer when drawing empty shapes. Fixed the preserveAspectRatio to take effect once selected Added property cross demo Added a check that the play store is installed when choosing a location implementation Fixed regression that caused framebuffer to not be resized when device is rotated. Removed call to delete framebuffer when layoutSubviews is called. It caused problems with screen redraw when the video component is in use, and it seems to be a performance killer in general. improved file copy to use nio for better performance Slightly improved tree expansion animation. Changed use of retainCN1 and releaseCN1 calls on strings to just use toNSString before the dispatch_async calls. There are still some instances of releaseCN1/retainCN1 on more complex objects, e.g. arrays that will be more involved to refactor\u0026hellip; will do that when I get more time. Replaced all instances of CN1_THREAD_STATE_XXX with CN1_THREAD_GET_STATE_XXX inside dispatch_sync and dispatch_async methods. Fix for ommission in Long object Fixed possible race conditions with GC when Java object parameters are used inside dispatch_async calls. Created retainCN1() and releaseCN1() functions that can be used to do reference counting on java objects that may live outside the purview of the GC. Fix for crash in iOS8.2 when purchasing product with IAP. Fix for Issue 1398: LocationManager stop send updates when lock screen Added ability to jump to the top of the scroll when tapping the status bar area. Made form back behave more sensibly for an empty title which will allow people to more easily track down the issue with the back in the toolbar area Added ability to show a label (or button) even if its value is blank which is necessary for the scroll to the top ability Fixed issue 1399: Dragging com.codename1.ui.list.ContainerList smaller than scrollable area fires action on Android Fixed issue 1401: Dragging a Button should not fire its ActionListeners when Display.dragStartPercentage between tap and release Added reset skins from menu and from cmd args - Issue 1396: Allow simulator skin to be reset to default Fixed a sizechanged event issue - which is caused due the the javafx panel mix Prevented a runtime exception from a client code to crash the backgroundThread Added support for image gallery to show videos, images, or both. Issue 1377. Note: This change adds the CoreMobileServices.framework as a dependency. Factored out some core features into the CN1GeoViz library to encourage reuse. Fix for Issue 1366: Dodgy tensile scrolling Fixed a regression caused by my recent commits. Threads weren\u0026rsquo;t deleted correctly. fix for Issue 1365: Dodgy click recognition after drag operation Made the GC suspend itself when the app is minimized so it won\u0026rsquo;t crash due to background GC activity, it will resume implicitly on 100k allocations even when in the background. Fixes for issue 1389: Timer.cancel() causes crash on new iOS vm Made thread destruction go thru the standard GC channels instead of going around it. Removed some code that isn\u0026rsquo;t exactly clear from Timer.java Fixes for issue 1389: Timer.cancel() causes crash on new iOS vm Made thread destruction go thru the standard GC channels instead of going around it. fix for Issue 1392: openImageGallery does not return path on android 5 for images synced with G+ Updated charts demo to use new setXXXTextFont() methods for text sizing so that the labels will be sized more appropriately for the display resolution. Added support for setting chart text sizes using CN1 fonts so that they will be sized appropriately for the device resolution. German Umlauts by string literal constructor don\u0026rsquo;t work in the new VM issue 1292 Added support for openGallery to for video selection Removed a redundant scheduleBackgroundTask which caused the command to not get called in some use cases Fix for issue 1386 on new iOS vm String.equalsIgnoreCase(null) throws NullPointerException Fix for class cast issue in tree Fix an issue where interfaces aren\u0026rsquo;t allocated enough space. Which happened for the NavigatableMap interface where 29 instead of 36 elements were allocated. It now allocates 71 which is too much but that\u0026rsquo;s probably better than too little since its still not that much. Implemented calcPreferredSize() on ChartComponent. Fixed issue with classes that are used in native code being stripped out if they are not also linked directly by Java source. Better fix for hiding keyboard when datepicker appears. Fixed sub-pixel positioning inconsistencies between device and simulator for drawing primitives. Related to Issue 1223. Fix for SpanLabel breaking lines incorrectly Keyboard now closes when datepicker is opened. Fixed issue with alpha not being respected by DrawLine in iOS. Fix for exceptions in the designer mentioned in issue 1370: Designer freezes on loading res file Fix for Orientation listener not called when menu is open Fixed keyboard height calculation for non-builtin iOS keyboards (e.g. swift key). https://code.google.com/p/codenameone/issues/detail?id=1368 Added some customizability to the flip transition Toggled HTML flags on the package htmls Made callSeriallyAndWait throw an exception when invoked on the EDT since this is a common mistake people make. Fix for issue with the picker dialog Fixed the missing public class in BigDecimal Better fix for issue 1362: ConnectionRequest looping with new iOS VM Fix for issue 1362: ConnectionRequest looping with new iOS VM Added video capture to the camera demo Fix for Issue 1360: buggy emoji management in TextField an TextArea with iOS newVM=true Changed DrawRect to accommodate differences between device OpenGL and simulator\u0026rsquo;s emulation of OpenGL. Fix for issue https://code.google.com/p/codenameone/issues/detail?id=1223 Optimized String \u0026lt;-\u0026gt; NSString conversion Fixed issue 1348: Switching databases can crash new iOS VM Updated PieChart demo to demonstrate pinch zoom, panning, and seriesReleased() methods for creating more interactivity. Added improved interactivity support for charts. Also added arcTo() method in GeneralPath that approximates an arc using bezier paths. Reduced garbage in some image handling code, this relies on the fact that all image stuff will happen on the EDT so we might as well reuse the object and reduce GC. Made the weak references use a hashtable for thread safety Fixed play services location binding Fixed clipping issue on iOS ES2. This may require some more investigation as to why the clipping and drawing of rects is slightly different between ES1 and ES2 pipelines. This fixes issue https://code.google.com/p/codenameone/issues/detail?id=1223 Added clock demo. Improved both quality and performance of drawing arcs and circles in charts. Used to use 36 line segments in path. Now just use 8 cubic beziers to approximate full circle. Also fixed issue with line segment showing up at degree zero. Fixed accidental typo from last commit. Fixed issue with datepicker not resizing when device rotated. Also removed extra white border at bottom of datepicker. Issues https://code.google.com/p/codenameone/issues/detail?id=1356 and https://code.google.com/p/codenameone/issues/detail?id=1356 Fixed GC regressions due to recent changes. Deleting the latest generation deleted newly created objects which was a problem. Fixed issue with cdatepicker crash on iPad. https://code.google.com/p/codenameone/issues/detail?id=1353 Fix for issue 1354: Designer stores Theme.res which cannot be loaded Fixed a bug in synchronized (monitor enter) that unlocked a critical section that wasn\u0026rsquo;t held\u0026hellip; Fix for Issue 1352: String with emoji chars make build fail with iOS newVM=true It seems String.replace doesn\u0026rsquo;t work very well with emoji and this really failed badly with the recursion. Fixed bug in bytecode store calls which triggered GC issues due to incorrectly marked types Changed GC to increment mark value on mark now that we no longer use the reference counting approach. The previous way triggered GC issues in odd cases where the VM would premark an object and if it was the only way to reach a different object (e.g. in a Hashmap) we would have an old object \u0026ldquo;hidden\u0026rdquo; by a new object. In the past this wasn\u0026rsquo;t a problem since we always cleaned the old generation (again policy that was necessary for the refcounting approach). Fixed VM crash for some special cases, not sure why this value would trigger that. Fix for issue 1345 in codenameone: URI objects return null for all getter calls, except getScheme() Added support for perspective transform in flip transition. Fixed major regression with new VM. The allocations of stringToUTF8 were leaking so this was fixed by allocating in the thread object. However, this means the same pointer is recycled over again causing bugs if the method is invoked twice. This broke everything from getResourceAsStream onwards\u0026hellip; As part of the fix I also converted a lot of code that used stringToUTF8 to get to NSString to use toNSString directly. This is FAR more efficient in the new VM and might result in a HUGE speed boost for that VM since the NSString is cached in String. Added a FlipTransition (based on Steve\u0026rsquo;s work from the card flip demo) Fixed issue with Object.wait(timeout) not waiting long enough. Fixed interaction dialog to not pass events down the hierarchy. Improved memory utilization for image rotation of the infinite progress implementation Changed the default of the text area to use initial caps which makes more sense Added a WeakHashMap implementation for easier caching Fixed potential thread issue with UTF-8 conversion Fixed a potential race condition with NSString deletion, the GC might collect java.lang.String while we are still pending on async native code that relies on the NSString that is bound to it. So we release the NSString in the native iOS thread thus making sure that all async operations already launched will complete successfully. Fix for Issue 1335: ImageIO didn\u0026rsquo;t save objects in the new VM because the GC is less eager so it didn\u0026rsquo;t collect the input stream immediately thus didn\u0026rsquo;t invoke close for a stream. This is an old bug of a missing close() call that the new VM exposed. Removed some static usage to improve performance on the new VM Fixed a bug in the web browser component with error code tracking Removed some unused code and a fix for issue 1339: Sample program that crashes the new iOS VM, Part 2 Added lastPurchaseData property Optimized String generation for the new VM Fix for issue with threads that might finish and still have allocations that aren\u0026rsquo;t in the memory pool Added aggressive thread detection code that doesn\u0026rsquo;t release the thread until after the sweep completes. This prevents one thread that keeps allocating non-stop from chocking the GC and destroying RAM while the GC is sweeping Removed implicit mark of objects added from a thread heap. These are young gen objects and very likely to be garbage by now so this doesn\u0026rsquo;t make much sense Added an improved way of viewing memory data by viewing statistics on the recent sweep operation Fixed issue with share button on iOS 8.1, 64-bit, iPad Made object deletion more synchronous and removed a redundant stage that made sense only when the reference counter was around. Fixed a compilation issue with the old VM Fixed a couple of bugs in the previous optimization Fixed minor compiler issue with no return value for ES1 pipeline Fixed major problem in bytecode translator that optimized away finalizers thus creating huge memory leaks in native code that were impossible to detect Improved array memory allocation to work as one allocation instead of two. Fixed a bug where a dead thread was still marked as active so the GC would get stuck waiting for a dead thread to sleep. Added demos build to the plugin Fixed issue 1340: Display.getInstance().execute() causes iOS app to crash to the home screen This was triggered due to a hard to reproduce race condition where the String object was apparently GC\u0026rsquo;d before the asynchronous call was performed. Made minor improvements for String method calls to make it slightly faster Made System.gc() run two cycles of GC to also clean up the younger generation Fixed memory leak in iOS splash screens Added logging capabilities to track memory usage and fixed a few insignificant memory leaks. Old commit that I missed, some changes for the Good work and a couple of bug fixes with wrong thread calls Fixed crash when pressing share button on iPad/iOS8/64-bit. Added parameter to Display.share() to specify source rect, which is used by iPad to position the popover dialog. https://code.google.com/p/codenameone/issues/detail?id=1338 Performance improvements for iOS and JavaSE graphics. Tried to make transforms that are *almost* the identity, automatically snap to the identity for the purposes of not having to do extra work later on. Moved matrix multiplication into native code on iOS. The chartEngine demo now runs correctly on JavaSE and iOS. Was already working on Android, but still need to test that it didn\u0026rsquo;t have the same performance issues as iOS did. Fixed Math.floor implementation for negative numbers. https://code.google.com/p/codenameone/issues/detail?id=1334 Fix for issue 1333: iOS app crashes when accessing a NULL field in the SQLITE database Optimized the previous fix to search in a far more efficient way Fixed a memory leak in the GC which always increased the pool of available objects until running out of memory rather than trying to find the best place Fixed a race condition if garbage collection is already running and is needed again urgently Fixed null pointer exception in Desktop apps for media playback Initial implementation of PropertyCross demo based on http://www.propertycross.com/ Fix for issue 1267: Ability to specify how many pixel a text should shift in Label tickering Fix for issue 1328: NewVM App Crashes after sitting idle for 10 minutes Probably also fixes 1304 as well. Made the thread allocator block when a thread starts allocating too much and made it force a GC for such a case. Fixed issue 1332: Build server failed with iOS AppStore build Fields were inconsistently named with the $ notation or _ notation which caused a warning on debug builds but failure on release builds. Implemented single arg constructor for IOException. https://code.google.com/p/codenameone/issues/detail?id=1300 Fixed picker size issue on larger screens. Also fixed screen going black after clicking cancel or ok in datepicker. https://code.google.com/p/codenameone/issues/detail?id=1330 Added google play location services Fixed Issue 1290: Strings appended after £ disappear on iPhone4 using new iOS VM Fixed the GC to be more efficient with static marking Reverted an optimization that places the strings into the constant pool. This creates a conflict with the String\u0026rsquo;s static initializer since its too early in the VM initialization process\u0026hellip; Removed dangling if statements in POP_MANY_AND_PUSH_XXX macros that were left from the latest changes. added InfiniteContainer API which simplifies the infinite adapter usage Added a missing check from the last commit Added finalizer to String thus allowing it to cleanup dangling NSString references. Added the builtin string into the interned string pool which might improve memory utilization. Added cleanup method to String that allows removing the NSString associated with a String and fix a memory leak. Fix for Issue 1317: Problems storing accented characters in database with new iOS VM which is really a problem in reading said characters. Improved GC behavior in low memory situations Updated the zbar support for 64 bit which we already did in the past and somehow got lost Optimized the common case of getBytes() with ASCII data. Also made the getBytes method respect the additional ISO encodings added earlier. Made the garbage collector more robust for cases where memory runs low Made System.gc() sleep a bit to give the GC time to wakeup Fix for Issue 1287, lack of String comparator causes TreeMap to fail Fix for Issue 1196: textfields on iOS only w/ constraint TextArea.ANY behave as if they are effectively set to TextArea.INITIAL_CAPS_SENTENCE by default. Fix for issue 1322 \\u notation broke in case of nesting a \\u. Switched the notation to differ from Java as ~~u Fixed a GC issue that triggered stalling Fixed issue with transforms not being applied during transitions on iOS https://code.google.com/p/codenameone/issues/detail?id=1315. Also added better for support for comparing transforms. Previously Transform.equals() didn\u0026rsquo;t work properly. Android, JavaSE, and iOS all updated to support this new functionality. Fixed charts to work with J2ME builds Small performance improvement (garbage reduction) for layout managers toArray() now throws exception if it receives an array smaller than the size of the collection. This makes it easier to debug. https://code.google.com/p/codenameone/issues/detail?id=1314 Fixed translation bug with class literals for primitive arrays Fixes to GC covering both crashes and performance improvements by removing redundant checks. Made GC cycles shorter to correspond to the removal of the reference counting Missing commit on an input stream fix and a class forName fix for inner class semantics Fixed most of the charts in the chart demo on the new VM Fixed parseDouble for large numbers and more decimal places on NewVM. https://code.google.com/p/codenameone/issues/detail?id=1283 Fixed AutoCompleteTextField to paint correctly when ios keyboard opens/closes Fixed issue with getResourceAsStream() not handling files with multiple extensions on iOS. https://code.google.com/p/codenameone/issues/detail?id=1318 Fixed issue with nullpointerexception when calling editTextImpl on newVM. This fix may be masking another problem with the VM as the null check shouldn\u0026rsquo;t be necessary as far as I can tell. https://code.google.com/p/codenameone/issues/detail?id=1279 Fixed issue with Double.toString() returning different result than simulator. https://code.google.com/p/codenameone/issues/detail?id=1251 Fixed instances of Collections.toArray[0] that caused nullpointer exceptions in the new vm. Parts of charts demo are now working in new vm, but there are still some deadlocks to deal with in some charts. Fixed issue with collections of boxed numbers causing EXC_BAD_ACCESS on new VM. https://code.google.com/p/codenameone/issues/detail?id=1305 Added support for ISO-8859-1/2 encodings Fixed memory corruption issues with print stack trace Fixed incorrect parsing of doubles for multiples of 10. https://code.google.com/p/codenameone/issues/detail?id=1313 Fixed swap instruction. https://code.google.com/p/codenameone/issues/detail?id=1311 Added DENSITY_560 Updated the FaceBookAccess to use version 2.0 Removed reference to Object.finalize(). https://code.google.com/p/codenameone/issues/detail?id=1307 Fixed landscape/portrait images for the iphone6+ device Issue 1302: Some launch image problems with the new IOS vm Fix for variation of Issue 1271: New iOS VM causes build failure with data mapper Arrays weren\u0026rsquo;t registered correctly for some bytecodes and were optimized out. Fixed multiple issues Fixed issues with transforms on Android port. Fixed issue with lock-ups on with async editing on iOS Added Charts demo app. Disabled pan and zoom by default on the chartcomponent. Added copyright notices to new files in charts package. Added charts package. Updated CLDC11.jar to latest with fix for missing Class.getResourceAsStream() Fixed push to work again on android 5 Fixed the text to speech to work on Android. Fixed a duplicate title issue Fixed arrayindex out of bounds exception when transforming point on JavaSE. Fixed the text to speech to work on Android. Fixed nullpointer exception in Font.getHeight(), getAscent(), and getDescent() that caused problems on build server. Workaround for recent build regression Fixed bug with rotate() that caused rotation around the wrong axis, and angle to be interpreted incorrectly . Added convenience 2D transformation functions. Performing 2D rotations using a 3D transform is not intuitive, so this is meant to make it easier to use the api in 2D contexts. Added support for basline vertical alignment with flow layout. Also implemented a getBaseline method in Label that can be used by flow layout. This allows you to layout multiple buttons and labels and have them vertically aligned on their baseline. Fixed font ascent and height to make more consistent. Changed baseline text to use a separate method (drawStringBaseline) instead of using a parameter. Added some javadocs for new baseline text support. Added support for drawing strings on baseline to simulator. Added support for drawing text on the baseline. Fix for iOS text input. async editing mode with form bottom padding. Fixed issue 1266 DateTimeSpinner not setting current date. https://code.google.com/p/codenameone/issues/detail?id=1266 Forgot to commit debugging line for location manager in ios8. Fixed GC infinite loop issue Fixed synchronization on static methods Improved the performance of character encoding Text input improvements for iOS that allow using padding instead of increased scrolling Updated NetBeans plugin and library Fixed issue with missing AppIcon120x120 when submitting app to app store. Fixed a regression in the SideMenuBar Fix for Issue 1248: Calendar.getInstance().getTime().getTime() does not provide correct time in ms in newVM=true Workaround for null pointer exception in the side menu bar due to recent commits Made stopEditing public to allow a use case of automatically transitioning from one text input to the next Fixed double parsing on iOS Made input on iOS more robust Fixed issues with the new VM Fixed regression when building with newVM related to the datePicker localization patch. Also Included source fix for location manager access in iOS8. https://code.google.com/p/codenameone/issues/detail?id=1256 . This needs to be accompanied by inclusion of the NSLocationWhenInUseUsageDescription key in the Info.plist file, which will be automatically added by the build server (patch to come). Localized Cancel and OK buttons of datepicker. Also fixed issue with selected date not being returned if the user click OK on the current date. Changed DatePicker to be modal in iOS. Fixed issue with datepicker not returning null when the cancel button is selected. Removed ios7-specific datepicker code so that ios7 now just uses ios8 code. This should also fix ios7 specific issues with transparency in the date picker. Fix for android drawShape stroke ignoring stroke. https://code.google.com/p/codenameone/issues/detail?id=1257 Fix for Issue 1255: Bug in JSONParser: always parse numbers as double even if long is expected Fixed an issue with poping stacks containing longs/doubles. Missing commits from the native VM Fixed possible regression introduced by recent fix to issue 1156 which could affect clipping of non-convex polygon shapes. Changed so that pixels sufficiently transparent are just discarded rather than pained\u0026hellip; Haven\u0026rsquo;t done performance testing but this may also give better performance. Fixed regression introduced by last fix for issue 1260. Needed to add notion of padding for texture masks to account for the difference in the path bounds and the texture bounds - as the texture bounds could exceed the path bounds if the stroke is non-null. Fix for issue 1260: Graphics.drawShape() has horizontal / vertical artefacts for wide stroke https://code.google.com/p/codenameone/issues/detail?id=1260 Fixed issue with white border on iOS fillShape. https://code.google.com/p/codenameone/issues/detail?id=1156 Added a faded Toolbar demo Adding the ability to place the Toolbar on top of the content Updated demo to scroll Toolbar off screen Added a ScrollListener API Added pointer events to Component Added hide/show functionality to the Toolbar Missing commit of the before swipe back fix Added error handling to setTitle Fixed some toolbar edge cases Fixed a bad format on facebook share - https://groups.google.com/forum/#!topic/codenameone-discussions/pRJ5loqJ6ug Changed default Toolbar menu transition to fade Added a new Demo (Flickr tags demo)- features the Toolbar Fixed a collision between the native action bar and the new Toolbar Some related fixes to the Toolbar Fixed an issue with Toolbar to init the menu bar Added Toolbar feature to the core API Workaround a bug where the async view came back black from a background run Fixed back command to not show on the Title area if the hideBackCommandBool is true Fixed a couple of the AndroidBrowserComponent methods to be called on the android ui thread Reverted lollipop support which caused issues Attempt at conditioning the previous lollipop support changes Minor reference counting and GC improvements Added ability to detect whether SMS will trigger a UI or be sent in the background and the ability to request the behavior when applicable. Added ability to set the UIID for a specific command in the side menu bar and possibly in other UI\u0026rsquo;s Made table work better with the native input when moving from one cell to the next Added lollipop ActionBar support Fixed a NPE bug in getComponentAt Implemented missing API call. Fixed dates and improved GC performance. Added a help menu to the simulator Many fixes to the mark sweep GC to make it more aggressive and fixes to the static variable mark process to prevent threading issues from breaking global static variable marking. Delayed GCing of elements to prevent them from being collected due to a race condition with the GC thread. Fixed some alignment issues in the AutoCompleteTextField Fixed List pointer selection to take into account the padding in some use cases Some fixes to the SwipeableContainer Added onNewIntent to the main Activity Made a few bug fixes to the AutoCompleteTextField Added new SwipeableContainer class New morph transition effect Initial commit of the new iOS Java VM into the public repository Fixed an issue in AutoCompleteTextField where the List got the event too soon before it was displayed Fixed NetworkEvent to return responseCode if available Fix for potential threading issue in event dispatcher. Added IAP v3 support Fix for NPE with null dialog titles Added ability to tabs to work with Components and not just radio buttons, this allows a tab that is a composite component type. Added version support to the facebook api Fix for landscape keyboard issues in iOS 8 Added flag to block tab images from being installed implicitly in iOS. Improved touch scrolling in ContainerList Improved playback and desktop platform overrides Fixed issues with push notification on iOS 8 due to API changes from Apple. Worked around the issues with the picker due to API changes in the new iOS 8 Fixed an issue with actionPerformed not being invoked in the async mode when switching directly between text fields Worked around an issue with local video file playback Fix for issue 1210 GPS speed on J2ME all the time zero Added a constructor to Oauth2 that doesn\u0026rsquo;t mandate scope param Fixed sizes of the AutoCompleteTextField popup Fix for an endless loop in the Contacts implementation Fix for Issue 1169: URI scheme and AppArg on Android Experimental autoplay and loop functionality for the media player class Ability for cloud emails to fail silently Fix for slider min value issues Added ability to disable tab animations Improved pickers behavior on setType Plugin fix for older IDE\u0026rsquo;s Small fixes to the AutoCompleteTextField Fixed a painting issue in Slider Added a PullToRefresh uiid Fixes for compiling with XCode 6 and running on iPhone 6+. There were some assumptions in the code that retina == 2 Fixed a desktop build issue in the eclipse plugin Added missing methods to the ContactsManager New iPhone 6 and 6+ skins for OTA install New get all contacts API that should make contact retrieval in bulk faster on Android Added cookie callbacks to the connection request allowing simpler cookie parsing Fixed regression in connection request from the last commit Added minor fixes for SimpleDateFormat Fixed spacing in the AutoCompleteTextField Fixed too spacing in the browser component Fixed a deadlock on iOS with the auto complete text field (fix in Component.java) this occurred since revalidate (triggered by auto complete) modified the setY value essentially making the new virtual keyboard switch to the scroll mode while the user is still typing Fixed designer exception in the localization editor Fixed very high density Android devices Fixed exception in peer component for some transitions Fixed the disabling of GPS on J2ME Fixed date formatting on JavaSE Fixed a couple of test recorder bugs Fixed user agent issues with iOS \u0026amp; some input bugs added canExecute and fixed some issues in video New get all contacts API that should make contact retrieval in bulk faster on Android Added cookie callbacks to the connection request allowing simpler cookie parsing Fixed regression in connection request from the last commit Added minor fixes for SimpleDateFormat Fixed spacing in the AutoCompleteTextField Fixed too much spacing in the browser component Fixed a deadlock on iOS with the auto complete text field (fix in Component.java) this occurred since revalidate (triggered by auto complete) modified the setY value essentially making the new virtual keyboard switch to the scroll mode while the user is still typing Fixed designer exception in the localization editor Fixed very high density Android devices Fixed exception in peer component for some transitions Fixed the disabling of GPS on J2ME Fixed date formatting on JavaSE Fixed a couple of test recorder bugs Fixed user agent issues with iOS \u0026amp; some input bugs added canExecute and fixed some issues in video Added some painting optimizations. Fixed paintBackground to draw the backgrounds of the parents when one of the Components contained is performing repaint Fixed video play/pause Patched a strange issue on some new Android devices (4.4) - https://code.google.com/p/codenameone/issues/detail?id=1173 Fixed issue with split-second black screen between splash screen and first form. This was caused by the transform matrix not being set yet. Initial commit of the new PhotoShare demo which is part of the new Codename One crash workshop https://www.udemy.com/build-mobile-ios-apps-in-java-using-codename-one/ Added initial work to support animations to the image viewer. Fixed connection request to support killing and resubmitting a connection better. Minor improvement to simple date format to allow millisecond formatting Fixed position events of the map component Fixed events in the AutoCompleteTextField and an exception with the margin Added support for higher device densities which aren\u0026rsquo;t yet mapped in the tools Fixed an exception in URLImage Fix for picker and app home Fixed a performance issue Added an icon indication for the ui resources (Container, Form, Dialog) Added animation to the Tabs navigation Improved ImageViewer IMAGE_FILL javadocs Fixed pan/zoom when ImageViewer is in IMAGE_FILL Added fill \u0026amp; fit options to the ImageViewer Added ability to customize the tint color of the infinite progress dialog Fixes for title command removal Added ability to get the internal list of the DefaultListModel for various filtering algorithm usage. Fixed bug in datetime spinner caused by integer overflow Committing the todo demo Added support for RestoreCallbacks so that we can get feedback when restores of IAP are complete. Fix for regression in facebook impl Added canExecute API Fixed some regressions due to the mig layout Fixed issue with replacing the arrow in pull to refresh Improved Spinner localization Added simplified big decimal/integer support Renamed the t() method to getTransformMatrix() to make it more descriptive. Removed unused imports added while debugging. Implemented perspective transform for Android port. Updated the MiG packages and deprecated it Fixed text editing on iOS to stop in some cases Added ability to set the multipart boundary string Fixed recursion in sameWidth/Height Modernized the GroupLayout logic a bit Fixed text area alignment regression Added ability for back gesture for the UIBuilder Added a few methods to the MathUtil class Added proper perspective scaling when transforming coordinates. Only affects perspective transformations. Fixed issue with concatenate that caused it to fail for special transforms like scales and translations. Experimental MiG layout support Fixed NPE when concatenating a scale or translate transform with another transform. Fixed typo in setTransform() that overwrote scaleX with scaleZ. Added sameWidth/Height API to component allowing us to set the preferred size for components Added SwipeBackSupport allowing iOS7 like back swipe functionality as an option Added LazyValue interface that allows accepting values that would be generated on the fly Fix for image locking in labels which triggered issues with URLImage Made shouldSendPointerReleaseToOtherForm protected for the back swipe API Added eagerSwipeMode to tabs to make it easier to swiping Added the ability to lazily create a motion object for the transition which is used by the back swipe functionality Made some minor fixes to pull to refresh trying to track an elusive issue Added rendering prototype to picker Fixed exception in table editing fixed and.facebook_permissions in the Android port New interaction dialog component Fixed exception in image viewer Improved EncodedImage behavior in scaling Fixed a bug when replacing the image in pull to refresh Fixed a couple of table refresh bugs Fix for Issue 1141: Alpha transparency ignored on polygon and lines with asyncPaint=true Initial work for the Android new graphics Fix for issue 1136: Support for nextAfter and ulp is missing from mailxzel23 Fix for Issue 1108: MathUtil.atn2(x,y) function producing wrong results from mailxzel23 Fix for ..cn1 lib directory issue Specified that rotate angles in Transform should be in radians. Fixed regression in iOS ES2 pipeline for transforms and for shapes. Also fixed ArrayOutOfBounds exeception in GeneralPath.curveTo(). Also added support for zoomLevels when setting transforms in the JavaSE port. Hints for push notification and scaling algorithm improvements Fixed long pointer pressed events for lead components Added API to set the Tab UIID Added a getter for border for future enhancement Fix for compilation issue in xcode 5.1 A fix for some android painting issues in asyncPaint mode Fix for Issue 1107: Simulator in Designer Looks in Wrong Folder for Font in \u0026ldquo;src\u0026rdquo; Directory Fix for performance issue of sqlite Fix for issue 1129: little bug on source code for facebook Photo object Improved performance on iOS ES2 pipeline by changing each executable op to use its own custom shader program. Also changed so that the transform is only applied when it is changed. Still a lot of low-hanging fruit for improving performance. A fix for the fixAttachmentPath - https://groups.google.com/forum/?hl=en#!topic/codenameone-discussions/hj1m98R30EQ Patched a rare race conditions between the EDT and the Android thread Initial support for shapes and transforms. Still some issues during transitions and transforming components. Also not thoroughly tested yet. Changed return type of popClip to void. Returning the clip isn\u0026rsquo;t all that helpful and it makes porting to different platforms just a bit more difficult. Changed license in header of Transform. Accidentally copied wrong one originally. A few fixes to the Facebook login Removed Shape import from image class that was accidentally added in last commit. Also added copyright notices to the FillPolygon executable ops. Moved Matrix class inside IOS implementation. Replaced with Transform class that is a thin wrapper around the implementation. This gives more control to the platform on how to implement transforms. Also added convex polygon drawing support in iOS. Currently this is only used for generating non-rectangular clip regions but will eventually be expanded to handle all drawing of shapes that qualify as convex polygons. Added api to open native navigation app A fix for CustomFont An attempt to fix fixAttachmentPath - https://groups.google.com/forum/?hl=en#!topic/codenameone-discussions/hj1m98R30EQ Some fixes to the graphics code, specifically a compilation error due to usage of unavailable classes and compilation issues with the new VM Fixes for some cases when killing an existing network connection Added an ability to block the auto complete from poping up unless the text is past a minimum length Fixed a listener leak in SideMenuBar that caused repeated event triggers Fixed some edge cases with the Android 4 blue glow Added Facebook publish capabilities to iOS Removed ununsed alpha mask methods in CodenameOneImplementation. Commented out a popClip() call as this api isn\u0026rsquo;t finished yet. Re-added change that had been lost in ES2 update. Re-added some changes that had been accidentally reverted in the ES2 patch. Re-added setBrowserUserAgent() method to iOSNative. It was inadvertently deleted in ES2 update. Changed pushClip() and popClip() to be empty instead of abstract temporarily so as not to break builds of non-ios targets. New 2D drawing API and ES2 support for iOS. To enable ES2 you need to change NO_USE_ES2 in CN1ES2Compat.h to USE_ES2. Removed classes that were just committed for history sake. We are currently going with the WebServiceProxyCall as the official direction. New webservice proxy API support with some additional classes that would be removed soon. Another fix for array arguments in ConnectionRequest on XMLVM. Fix for potential regression in Display Added ability to customize the pull to refresh image Fixed a bug in ConnectionRequest on XMLVM that didn\u0026rsquo;t work properly with the String arrays. Added ability to handle errors properly in ImageDownloadService Added ability to commands so they won\u0026rsquo;t dispose the dialogs Added facebook libs to the project Added the Facebook implementation class Added implementation for the GPS detection API Added publish permissions request api for the native FB integration Added API to detect if GPS is enabled Badging support native code and fix for conflict between native mapping and push. Also minor fix for the headphones detection support. Fix for a potential web browser component exception in the designer Fix for code scanner to return null on a device without a camera Another attempt to fix the spinner issue with different time zones Additional ImageIO API\u0026rsquo;s for image scaling Fix for the persist option in android notifications Made location simulation persistent across executions Added badging support for iOS Fixed video positioning New badge number API for iOS Fix for remove TitleCommands Added the ability to override the SideMenuBar Menu button Support for proper stack traces under the new iOS VM Couple of bug fixes for the new VM Added flags to indicate whether the current platform is a desktop and whether the dial method is supported on this device. Another fix for vserv ads allowing for HTML ads to also pop correctly. The new JSONParser will now use LinkedHashMap instead of HashMap which will preserve the order of the elements from within the JSON Enabled duplicates to image download service, this is problematic conceptually but the alternative is that if we submit two duplicates only one will be received which isn\u0026rsquo;t good\u0026hellip; Fix for an exception in FilterProxyListModel Fixed timezone issues with the DateTimeSpinner Fixed an issue in XML import in the designer, it should default to UTF-8 Fixed unicode CJK characters in the simulator and in the desktop apps for Windows machines. Fixed scrollwheel not to click the components we are scrolling over in the JavaSE port Support for proper stack traces under the new iOS VM adding the ability to custom the uiid of the TitleCommand a workaround for a EOF exception in some android versions adding support for left Title Commands in SideMenuBar Fix for \u0026ldquo;jump\u0026rdquo; when going back and forth in list views Fix for parser to generate long values as well as double values Fix for vserv ads when they are tapped an incorrect URL open logic is triggered. They can now only be tapped via the button. Fix for glass pane drawing on a Container which is important for table line drawing when a cell has focus Fix for multi-list placeholders with URLImage Fixes to support the new changes to the Codename One JVM. This allows passing a thread context on the stack saving expensive thread lookup and allowing very efficient concurrent GC. Another fix for the sort algorithm Fixed a small nokia back command bug Fixed exit app Added ability to disable cookies in the connection request Made the auto complete text field non-predictive by default which is pretty important for iOS Fixed a recursion issue in lead component which was triggered when disabling the lead Fixed a potential null pointer for side menu that can occur when a title command is added to a dialog Fixed a potential exception in Windows Phone with gridbag layout Exposed the fire data changed event due to request in the forum A few fixes for timezone issues with the spinners Fixed the style dialog when opened from the GUI builder Fixed some edge cases with loading XML UI\u0026rsquo;s in the designer Fixed a socket exception in the Android implementation Fixed location manager to throw the right exception when the native location manager throws an exception Added a workaround that allows placing a comma character in the Android native numeric text field which is useful for German locale In MIDP an exception was thrown when a user denied access to the address book. We now return null. Fixed some device density bugs in the desktop builds Fixed Java SE sockets support Fixed video playing in RIM Added potential ARC support and prepared the code for the new VM Added a check before adding to the playing vector A fix for the media volume control Added location simulation Adding the option to share text and image, although some apps don\u0026rsquo;t respect sharing both A small batch of fixes before VM change Fixed a regression in audio oncomplete Fix for issue 1097: Wrong separator in file://home path on PC Simulator Fixes for issue 1099: Reading from closed socket Fixes for issue 1098: readUTF bug Fixed setLeadComponent to accept null as a value thus disable the lead component mode Added private constructor to preferences to prevent people mistakenly initializing the class Fixed exception in server sockets Made a small improvement to auto complete text field Fixed regression in the processing package Added disposeOnComplete flag Implemented a workaround to the async paint issues Added a \u0026ldquo;Clean Storage\u0026rdquo; for the simulator Added \u0026ldquo;Remove All\u0026rdquo; to the NetworkMonitor Implemented getSelectedRect to ContainerList Fixed potential exception in PeerComponent Fixed NPE in iOS startup when dragging the finger on the splash screen Fix for showing the auto complete list for text field Made the SideMenuBars speed configurable Fixed NPE in generic list cell renderer Added support for setting the user agent of the browser explicitly Fixed a simulator bug in the socket implementation Added multi images to the share icon Fixed push types Fixed android peer image Fixed fullscreen native video on iOS Improved button release functionality which made buttons a bit less sensitive on iOS touch devices Improvement to canceling connection requests in progress, this happened for cases where a connection was retried then canceled. It got stuck in an infinite loop. Fixed map event functionality Fixed image scaling functionality on Windows Phone which doesn\u0026rsquo;t support PNG image IO Made some functionality/performance improvements to the side menu bar as part of chasing the responsiveness issue mentioned Added some improvements to the peer component behavior on Android to enable Google maps functionality Fixed fullscreen native video on iOS Fixed mailto: links within the Android browser component to do what\u0026rsquo;s expected of them Fixed the processing package to use Map/List instead of Vector/Hashtable so it will work with the new JSON parsing code Added cloud file storage API\u0026rsquo;s to purge old files Fixed a layout issue with ImageDownloadService Added ability to open a popup dialog based on screen location which is important for native component integration Added a more refined version of encoded image that allows creating encoded images more efficiently Added ability for native code to receive Android lifecycle event callbacks Fixed a bug in Display execute in Android where mailto:\u0026hellip; didn\u0026rsquo;t work as it previously did Caught a potential exception in Android surface view Added ability for JavaSE apps to store their state into a different folder from .cn1 Fixed some file access bugs in the iOS port and made a small peer component improvement Allowed facebook on older iOS devices to fallback to the lightweight login method Added map listener API that provides updates on map changes e.g. zoom, pan etc. Fixed potential infinite loop in component drag events Fixed J2ME null pointer exception regression with Encoded images Improved peer component creation logic allowing native layers to return null for a peer component Another client properties persistence bug fix Fixed exception with client properties Added a rendering prototype to the DateSpinner An improvement for popup display logic Fixed sidemenu button click to show the animation Made drag sensitivity play nicely with buttons so the behavior of drag events is more fine tuned to specific component requirements. Fixed issue 1072: NullPointerException: Attempt to invoke virtual method \u0026lsquo;boolean com.codename1.ui.Component.isVisible()\u0026rsquo; Added getPendingPush Another set of fixes for URLImage coupled with a new feature to scale to fill Added new URLImage support to replace the ImageDownloadService class, this works both standalone and as part of the GenericListCellRenderer Fixes for file upload in the cloud storage API Added a callback option for the new download file API Fixed an autocomplete bug that onu shows the text on iOS after the keypad was closed Added a flag to disable paintlock manually, this is used in the tabs component and contributes to some performance degradation. Added ability to explicitly scale to EncodedImage Another fix for JSONParser Fixed tensile highlight regression Fixed exception in new JSON parser logic Updated javadoc with latest features/corrections Placing renderers first in ui xml Fixed bottom glow to paint in the right position Added Java 5 support for the JSONParser class Fixed auto complete text field to not popup when the list is empty for some use cases Fixed a text input bug on iOS for some edge cases Fixed a null pointer exception issue on Tree Added a warning to the UI builder regarding inheritance limitations Minor improvement for contact API to simplify access to email address Implemented support for client properties in XML syntax and runtime of designer Fixed scrolling with scroll wheel in a page with text fields or while editing Fixed the Java SE port to return mac or win for the platforms when running on the desktop Fixing the connection timeout Made edge highlighting in Android behave closer to the way it does in the native Android 4 OS Fixed a skipping in the side menu slidein animation on iOS Fixed a potential bug in cloud storage file upload Added a feature to generic list cell renderer allowing a component to have a different UIID based on model data Allowed developers to customize back command behavior in the UI builder Fixed a class cast exception in the JavaSEPort Fixed the menu bar for iOS 7 Fixed switch look and feel on iOS 7 Added simplified file download support API\u0026rsquo;s Additional API\u0026rsquo;s for L10NManager localization and parsing, these aren\u0026rsquo;t incorportated in the ports yet Fixed a visibility issue in the popup of the auto complete text field Fixed a regression caused by a change that invoked setScrollX/Y at a crucial point, this effectively broke the Spinner component for some edge cases Added a shouldLocalize flag to label allowing users to block localization Added maxElementHeight property to list to constrain its preferred size Added constants to side menu bar for convenience, hid an empty back command from the side menu bar Made a fix for date time spinner to take the timezone offset into consideration, otherwise the day was offset in countries such as Canada where the distance from the GMT baseline is too great Fixed a bug with streams to files in the JavaSE port Made the location manager in the simulator fire its events on the EDT only Fixed device density on the ipad retina which seems to be incorrect Committing local changes to avoid more conflicts changed the view to the surfaceview by default fixed flickering text input on android 4.4 Fix for issue 1062: audio capture not working on iOS device Fix for issue with image capture that caused a crash due to a memory warning that arrived while the device was rendering something else. Minor regression with facebook missing a comment Added a read timeout Fixed the native re-layout to listen to sizeChanged events Added a sizeChangedListener Fix for issue 1059: ArrayIndexOutOfBounds exception on Picker for date type from Nirmal Fix for issue 1060: Missing setUIID() in TextField constructor Improved bar code scanning in j2me Workaround for potential crash in iPhone camera Fixes for iOS 7 status bar height Fix for ads on some devices Improvements to the picker functionality Better facebook integration Fixed a regression in push new eclipse version Small performance improvement to clipping on iOS by using a more efficient clip rect Added preserve aspect ratio and ability to describe percentage scale of multi-image Fixed iOS filesystem roots. Generified combo box which was missing after we generified the list Worked around an issue with the side menu bar clashing with the glass pane of the table in iOS Made sidemenu bar work correctly on iOS Fixed a long standing bug in rectangle which affected iOS clipping performance fixing endsWith3Points for TextArea init scrolling positions on removeAll Added picker to the GUI builder Added ability to define the swipe threshold of the ImageViewer and fixed an incorrect getter Made dragging more responsive for specific components such as list and possibly sidemenu Added better logging for push notification Made the auto complete text field hide the popup in case of an empty list Fixed Android execute regression Added mousewheel support for the JavaSE port and desktop builds Fixed switch to calc size properly on non ios mode Fixed orientationListener to be called only on orientation change. Fix for potential web browser crash on Android Fixed IDEA bug Fixed the -regen flag Added a new block overdraw mode which is currently off by default but might improve android performance for some cases with the new pipeline, this includes changes to all the layout managers to detect when an element is obscuring another element Made span label use container style to allow the label to behave more like a \u0026ldquo;label\u0026rdquo; Made infinite progress animations smoother and less EDT hostile Removed deletion of buffer in MapComponent which was causing an issue with the new Android pipeline where the buffer was deleted but was still queued for paint Made isCellRenderer public for consistency with the setCellRenderer API and for the performance monitor improvements Minor performance improvements for draw string, we now ignore drawString \u0026quot; \u0026quot; which happens a lot Fixed bug in command icon gap client property Added support for configuring the size of the side menu Fixed border layout center alignment absolute center mode to properly align, this is really a fix for issue 1042: Title Area Alignment on iOS 7 Added case sensitive mode to the XMLParser class for consistency with XML Fixed a bug in exporting blank localizations Improved spacing for ads on Android devices to grab the exact size required in pixels. Added some improvements to Android\u0026rsquo;s getProperty, now various properties instead of returning null will return the default value. If an intent sent an argument you should be able to retrieve it via getProperty. Fixed a simulator/SE port bug with text input that was very obvious in the iOS_7 5 skin Made share behavior on iOS work for OS\u0026rsquo;s prior to 6 by falling to lightweight share functionality. Added OS 7 skins to build script Made updateValue protected as a fix for issue 1057: Date Picker Format Added support for passing arguments via intent Fixed action bar icons dpi issue Fixed InfiniteProgress rotate speed to be more native like Fix for executing file URL\u0026rsquo;s. Patched a very strange awt bug on windows in the file chooser dialog Slightly improved peer components and text fields in the new pipeline Added an option to create an InfiniteScrollAdapter that doesn\u0026rsquo;t calls the fetch upon creation plus a few fixes to the impl. Updated popup dialog padding Updated popup dialog padding Restored the patch to workaround android paint issues. New component rendering debugging tool in the JavaSE port Fixed async rendering mode in Android to be much faster and some rendering glitches Patched duplicate background painting in form Fix for ad spacing in iOS ads Fixed exception in browser component in the SE port OnOffSwitch now supports iOS 7 rendering mode Filtering now supports the starts with both in the proxy model and the auto complete Fix for issue of dependencies between UI elements in the case of embedded container. Fixed some animations in new Android pipeline and removed layer to slightly speedup rendering Async paint pipeline fixes, still has some issues Exposed should write UTF from connection request Fixed issue with font loading in the designer Fixed a classcastexception Fix for issue 1050: drawLinearGradient broken in iOS Fix for issue 1049: Plugin 1.0.67: iOS7 Status bar is hidden by full screen using SocialBoo Made all URL\u0026rsquo;s work with space characters on all platforms Added ability to customize side menu swipe behavior Allowed localizing date/time spinner Added ios 6 skins Fixed resources being GC\u0026rsquo;d even when set to remain in ram Added prefetch media API Made span button default to more columns Changed picker start year to something more sensible Patched the blackberry mkdir method Capability to prefetch audio Added endsWith3Points to the TextArea Fixes for several issues were missing Scale should now act correctly for maps Fix for issue 1043 from Steve: iOS nextPowerOf2 needlessly goes one power too far Fix for image sizing issue with ARGB images from Steve Added flag to hide the text field toolbar for DONE/NEXT functionality Many fixes for text field input in the vkb always open mode Fixed the UIPopover to work correctly without artifacts on iOS 7 and fixed the picker on ipad to actually work Added the socket implementation code Added the media prepare API Regenerating the state machine code on regen. Regenerating the state machine code on regen. Fix for bug in component group in new XML UI mode Another fix for issue 805: keyReleased not invoked Added support for XML ui elements as an optional experimental feature and an ability to \u0026ldquo;compile\u0026rdquo; the XML changes to a resource file without launching the UI of the designer Minor fixes for text input in iOS with the async flag Fixed the JSON parser to support decimals in scientific notation based on request from the forums Added support for expand/collapse path in a tree Fixed event handling in multiline tree node mode with lead component. Fixed a performance issue - the system resources was messing up the local res caching. Fixes for Issue 1024: Double-tap Zoom in MapComponent Fix for Issue 1023: MapComponent pinch zoom to wrong position Fix for issue 1021: com.codename1.l10n.SimpleDateFormat.parse unexpectedly throws java.lang.StringIndexOutOfBoundsException Implementation of RFE 1019: MapComponent pointerDragged new tiles not loaded Fix for issue 1015: Generated \u0026ldquo;Back\u0026rdquo; command disappears from menu on Android when returning from next form Socket support for iOS, Android \u0026amp; Java SE Fixed potential exception in the image viewer when working in the designer Fixed on-off switch to not resize the button dynamically as it moves back and forth on Android Fixed the auto complete text field to work with the keyboard too Improved the always on keyboard mode in iOS to handle various edge cases correctly Added support for multine tree elements and arbitrary component types as entries within the tree Fixed pull to refresh y position Updated skins to fix issue 1014: Multi Image issue on Simulator and Real Devices Fix for Issue 1014: Multi Image issue on Simulator and Real Devices Fix for issue 1012: Effect of padding on horizontal position of a component Support for executing file URL\u0026rsquo;s on iOS Fix for RFE 1004: Support copy and paste URLs from the Network Monitor Fix for Issue 805: keyReleased not invoked Fix for issue 982: SimpleDateFormat crashes app on Windows Phone 8 Moved all date formatting code into Codename One package space to remove platform dependencies. Support for string based picker component Fix for Issue 361 on iOS: Ability to scroll Form/Components while virtual keyboard is showing New support for asynchronous mode for the editing component required for that fix. This allows edit string to effectively return immediately Ability to determine the height of the VKB from the implementation to provide more scroll space and to restrict the area of scroll rect to visible Ability to determine number of rows the text field can grow to Fix for RFE 1009: timeout on static ImageDownloadService methods Added a set default timeout static method Added an improvement to the behavior of native lookup to enable native interfaces in JavaSE Fix for issue 1010: Multiple cookie headers with different casing is not recognized on Android and JavaSE Fix for issue 1008: NoSuchElementException when sharing an image via ShareButton in iOS Made a fix for truetype fonts to fallback to classpath so the JavaSE packaged applications will work properly with TTF\u0026rsquo;s Added headphone processing callbacks Redid the logic for next text field in iOS behavior to match the logic used in Android. added support for multiple right commands (Action Bar) ","permalink":"https://www.codenameone.com/codename-one-3-0-release-notes/","summary":"\u003ch1 id=\"codename-one-30-release-notes\"\u003eCodename One 3.0 Release Notes\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003eHome\u003c/li\u003e\n\u003cli\u003e3.0 Release Notes\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"summary\"\u003eSummary\u003c/h3\u003e\n\u003cp\u003eVersion 3.0 is a major leap in Codename One\u0026rsquo;s mission of mobile write once run anywhere, its highlights include a completely rewritten VM for iOS advanced API\u0026rsquo;s and a new JavaScript target that officially makes Codename One the most ubiquitous WORA (Write Once Run Anywhere) platform in the market today.\u003c/p\u003e\n\u003ch3 id=\"highlights---click-for-details\"\u003eHighlights - Click For Details\u003c/h3\u003e\n\u003cp\u003eNew iOS VM\u003c/p\u003e\n\u003cp\u003eWhen Codename One debuted we used XMLVM as the underlying iOS virtual machine abstraction. XMLVM is an excellent product but its unmaintained and its goals are too different from the goals of Codename One. The new VM includes some features that would be remarkably hard to achieve with XMLVM such as: proper stack traces, faster builds (2x overall!), smaller code size, concurrent GC, deep OS binding (String - NSString relationship) etc. Read more about this work on \u003ca href=\"/blog/new-codename-one-ios-vm-is-now-the-default.html\"\u003ethe announcement blog\u003c/a\u003e.\u003c/p\u003e","title":"Codename One 3.0 Release Notes"},{"content":"\nWe are thrilled to announce the immediate availability of Codename One 3.0!\nTo celebrate this release we are giving away a $100 rebate discount for annual pro\nsubscriptions and $300 rebate discount for annual enterprise subscriptions.\nAll you need to do to get this rebate is signup for an annual subscription and the appropriate sum will\nbe refunded within 24 hours thru PayPal. This offer is valid before June 1st 2015.\nYou can check out the press release and full announcement here.\nGo a head and update your Plugin now to get the new Release.\nHighlights Of The Release – Click For Details ____New iOS VM\nWhen Codename One debuted we used XMLVM as the underlying iOS virtual\nmachine abstraction. XMLVM is an excellent product but its unmaintained and its goals are too different from the\ngoals of Codename One. The new VM includes some features that would be remarkably hard to achieve with XMLVM\nsuch as: proper stack traces, faster builds (2x overall!), smaller code size, concurrent GC, deep OS binding (String – NSString relationship) etc.\nRead more about this work on the announcement blog.\n____JavaScript build target (technology preview)\nAllows compiling Codename One applications to JavaScript client side webapps\nwithout server side code. Notice that this support includes threading support.\nNotice that this feature will be restricted to enterprise developers once it enters beta.\nThe Java VM work is based on TeaVM an OSS Java-JavaScript VM.\nRead more about this work in this blog post.\n____Charts API\nThe charts API supports drawing a wide range of charts such as bar, pie, line etc. It supports animating\ncharts and is based on the aChartEngine Android API.\nRead more about this work on Steve’s blog post.\n____New Demos\nProperty Cross – Browse properties for sale in the UK using a JSON webservice. Shows off JSON webservices, InfiniteScroll, URLImage etc. Dr Sbaitso – Demonstrates an AI bubble chat interface, includes text to speech using native interface and more. Photoshare – A simple social networking app that allows sharing photos Charts – Demonstrates all chart types Geoviz – Performs statistic analysis over US population based on locale specific data Flickr – Demo for the Toolbar class showing special title area effects ____New Themes\nNew beautiful and functional themes are now available through the plugins and\nthe designer tool.\n____Toolbar API\nMore advanced and highly customizable API for handling\nthe title area. It allows adding search to the title, animating its appearance/folding, placing commands\narbitrarily and using the side menu.\nRead more about this work on this blog post.\n____URLImage\nSimplified image download to an icon or preview,\nthat allows to implicitly apply special effects to said image (e.g. round corners, scaling etc.).\nRead more about this work on this blog post.\n____Built demos into the Eclipse/NetBeans Plugins\nThe main Codename One demos are now built-into the plugin so you can try them immediately without\nfixing classpaths and without downloading additional software.\n____New Android graphics pipeline\nWe rewrote the graphics pipeline on Android to work better in Android 4.x+ and use hardware acceleration\nwhere applicable. This new pipeline also includes support for the Shape \u0026amp; transform API’s.\nRead more about this work on this blog post.\n____Regular expression and validation support\nWe added a new regular expression package and a new validation framework that simplifies\nerror highlighting for input. As part of that work we also presented a rudimentary masked\ninput UI.\nRead more about this work on this blog post.\n____High DPI Image Support\nThere are 3 new DPI levels in Codename One all of which are now supported by the designer:\nDENSITY_560, DENSITY_2HD \u0026amp; DENSITY_4K.\n____Support for opening HTML files with hierarchies \u0026amp; Tar support\nThe builtin HTML support was improved by providing a way to open a hierarchy of files and not just\na self contained HTML file. As part of this improvement we also added support to the tar file format.\nRead more about this work on this blog post.\n____New Morph \u0026amp; Flip Transitions\nThe morph transition was inspired by the Material design UI, converting a component on one form to\na component on another form. The flip transition provides an impressive 3d effect thats trivial to apply\nto any form or transition.\n____InteractionDialog\nA new \u0026ldquo;modless\u0026rdquo; dialog that can \u0026ldquo;float\u0026rdquo; on top of the\nUI using the layered pane capability of the parent form\nRead more about this work on this blog post.\n____Significantly enhanced developer guide\nWe redid the developer guide from the ground up converting\nit to asciidoc and integrating it into the website in a more fluent way. We increased its breadth by over\n50%.\nCheck it our here or download the pdf.\n____iOS Beta Test Support (testflight)\nApple introduced a new way to test mobile applications for up to 1000 beta testers based on the testflight\nframework (but not to be confused with the old testflightapp.com product). We now support distributing\napps via this process for pro users.\nRead more about this work on this blog post.\n____MiG layout support\nMiG layout is one of the popular cross platform Java layout managers that works across FX, Swing, AWT\nand now on Codename One as well…\nRead more about this work on this blog post.\n____Facebook improvements such as publish support \u0026amp; version 2.0 API\nFacebook made a lot of changes to its API such as requiring a special\npublish permission\nand migrating graph calls to version 2.0. Both are now integrated into Codename One.\n____Added webservice wizard to simplify client-server calls\nThe\nwebservice wizard allows us to\ngenerate RPC calls to the server including servlet and client stubs.\nRead more about this work on this blog post.\n____Support for badging the native OS icon on iOS\nWe now support updating and setting a badge on an app icons in iOS devices.\nRead more about this work on this blog post.\n____TCP socket support\nWe finally added support for TCP sockets into Codename One.\nRead more about this work on this blog post.\n____Advanced keyboard input in iOS that doesn’t fold implicitly\nThis is an implementation of a feature that was requested\nquite a while back. Historically, when moving from one text field to the next the VKB would fold and reopen. We now allow you to seamlessly\nmove between input fields.\nYou can also read the far more detailed list of release notes here.\nOne of the things we are announcing today is a switch to faster release cycles, we already announced the\nnext two release dates which will probably map to versions 3.1 and 3.2 respectively: July 27th and October 27 2015.\nNotice that the dates are 3 months apart allowing us to make releases much faster and keep Codename One\nstable in shorter iterations. This effectively means that\nversioned builds\nwill become a more viable feature. It also means that the feature list for every release will be very volatile\nand we won’t announce them until the release is out of the door.\nWarning For Users Of The Old VM (XMLVM) If you are still using the build flag ios.newVM=false we strongly suggest you stop right now!\nEven if you don’t need appstore submission and aren’t worried about the impending July cutoff date for the old\nVM you would still need to migrate!\nApple broke xcode 5.x builds with its new Mac OS release Yosemite, this has been broken for a while and it\nseems that Apple has no intention of fixing this. Unfortunately Apple has a tendency of tying xcode upgrades and\nOS upgrades together, our build servers are still running Mavericks (the previous OS X release) and we have\nno intention of upgrading them right now. However, if we find ourselves in need of a new server or if Apple\nforces us to use a new version of xcode (and thus a newer version of Mac OS) we would be forced to upgrade\nthe servers.\nSuch an upgrade will make all builds targeting XMLVM fail!\nThe correct thing to do is move to the new VM which we are actively supporting as much as possible, we suggest\nyou do it now rather than hastily at a later date. It provides many advantages including stack traces \u0026amp;amp a\nsuperior gc. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nmanezi — April 30, 2015 at 12:22 pm (permalink) manezi says:\nFantastic news. Well done to the CN1 team!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-3-0-now-live/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-3-0-now-live/CodenameOne-Horizontal.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are thrilled to announce the immediate availability of Codename One 3.0!\u003cbr\u003e\nTo celebrate this release we are giving away a \u003cstrong\u003e$100 rebate discount\u003c/strong\u003e for annual pro\u003cbr\u003e\nsubscriptions and \u003cstrong\u003e$300 rebate discount\u003c/strong\u003e for annual enterprise subscriptions.\u003cbr\u003e\nAll you need to do to get this rebate is \u003ca href=\"http://www.codenameone.com/pricing.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003esignup\u003c/a\u003e for an annual subscription and the appropriate sum will\u003cbr\u003e\nbe refunded within 24 hours thru PayPal. This offer is valid before June 1st 2015.\u003cbr\u003e\nYou can check out the press release and full announcement \u003ca href=\"/files/pr/CodenameOne3.0PressRelease.pdf\"\u003ehere\u003c/a\u003e.\u003c/p\u003e","title":"Codename One 3.0 Now Live \u0026 Special Offer!"},{"content":"\nWe are very excited to announce the alpha release of the Codename One Javascript port. This brings us one\nstep closer to the coveted write once run anywhere ideal. Starting with Codename One version 3.0, you will\nbe able to deploy your projects as Javascript applications that run directly in the browser. The process is simple:\nSelect the \u0026ldquo;JavaScript\u0026rdquo; build target from the right click menu.\nLog into the Codename One build server.\nDownload the application as a .zip archive that will run on any web server – or try the app instantly in your\nbrowser using the \u0026ldquo;Preview\u0026rdquo; link.\nLimitations I mention above that this is an alpha release because\nnot all features have yet been implemented. The port is still\nunder active development, and most/all of the Codename One platform features will be implemented over the\nnext few months. If you build an app and it doesn’t work, it is likely due to a feature not being implemented yet.\nI have created a Project Status page for the project to record\nthe status of each feature.\nBrowser Support The goal is for this port to work in all modern browsers, but development has primarily occurred on Chrome,\nSafari, and Firefox (on the desktop), with mobile testing on Android’s Chrome browser and iOS’s Safari browser.\nOnce all of the features are complete, I will focus on ensuring support for the other major browsers (i.e. IE).\nPerformance When I first started working on the port, I didn’t know whether it would even be viable, performance-wise. I feared\nthat we might finish the port and find that the interface was sluggish, unresponsive, and clunky. The single-threaded\narchitecture of Javascript was viewed as a limitation, and it was thought that the EDT might cause the Javascript\nmain thread to lock and block the UI, causing the dreaded \u0026ldquo;This page is unresponsive\u0026rdquo; alert in the browser.\nI am happy to say that our fears were unfounded. Performance, on the desktop, seems comparable to the current\nJavaSE port – and in some cases it is even better. The true test of performance, however, is on mobile devices.\nOn newer devices (e.g. iPhone 6, iPad Air 2) the port is quite responsive; Animations and transitions are smooth –\nthough not quite as smooth as in the iOS port. On the previous generation of devices (e.g. Nexus 5, Nexus 7),\nI would describe the port as \u0026ldquo;usable\u0026rdquo;, but animations and transitions are a little jerky. As we move into even older\ndevices, the apps remain usable, but the slow responsiveness, animations, and transitions become more\nnoticeable.\nSo… at present, your apps should work very well in desktop browsers and quite well in new mobile devices.\nThe Secret Ingredient: TeaVM As recently as 4 months ago most of us believed that a Javascript port of Codename One was impossible due to\nCodename One’s extensive use of threads and concurrency, for which Javascript has no equivalent. Developers\nhad been working for years on solutions to try to add threading to the browser, but no full solution existed. And\nCodename One needed a full solution. It needed all of the bells and whistles of Java’s threading features:\nwait/notify/synchronized, etc..\nThe turning point was when Alexey Andreev told me that he had a way to support threads in TeaVM\nusing a sophisticated transformation of the Java code into continuations. This break-through was nothing short of\namazing, and it paved the way for Codename One in the browser. One of the most surprising things is how\nperformant TeaVM is able to be despite these transformations. Alexey has taken great care, each step of the way,\nto ensure that the generated Javascript code is both concise (for a small file size), and performant. Benchmarks\nhave shown the code to be as fast or faster than GWT on the same code – though we can’t really test that on\nCodename One since GWT doesn’t support threads – and thus can’t run Codename One.\nThe Future Shai always reminds me to just take this one step at a time, and not to get ahead of myself. But let’s cast that\naside for a moment and ruminate on the future potential of Codename One now that it can run inside the browser.\nI believe that Codename One is currently the closest thing to an heir-apparent to Swing that exists; and indeed\nthe API is quite similar to Swing. It was carefully crafted to be easily portable to other platforms. Many suggested\nfeatures or APIs have been rejected by Codename One because they wouldn’t be portable, or wouldn’t fit into the\nWORA paradigm.\nBeing able to run inside the browser opens up a whole array of possibilities for us Codename One developers.\nEnterprise applications that must target the \u0026ldquo;web first\u0026rdquo;, can now be written entirely in Java. No more messing\naround with HTML and Javascript for the client side. Write the application once, deploy to the web, and also\nprovide native application bundles for users that require the enhanced experience of a native app.\nThis port could also provide a gateway to some of the more niche platforms like Firefox OS and Chrome OS\nwhere the small user-base makes it hard to justify a full native port.\nUltimately, the future direction will depend on you, the developers who are using Codename One to realize your\ncreative solutions. How do you see web deployment fitting into your development cycle? How can the port be\nimproved to meet your needs? We want to hear from you.\nSame Origin One of the limitations of JavaScript is the same origin policy\nwhich means you can’t connect to a server other than the one the app was delivered from. Since resources\n(images, res files etc.) are stored in the server this makes the JavaScript impractical for local execution\nby just opening a file. So you can’t download the build result zip, extract it and run it in your browser, you\nneed to place it in a webserver for it to work.\nAs part of that work we also included a special servlet that will allow you to open a connection request to\nany destination. All requests will be proxied thru that servlet and thus allow you to connect to any domain\nyou choose seamlessly.\nHowever, we wanted developers to be able to preview their build results easily without requiring a specific server\nsetup. To that end we generate a monolithic HTML file build result that we provide as a \u0026ldquo;preview\u0026rdquo; that you can\nopen using the QR code or preview link as a result of the build. Its not as optimized as the actual result but you\ncan see it instantly without setting up a server.\nAvailability You will be able to send a JavaScript build with the next update of the plugin coming really soon!\nDuring the technology preview phase we will allow everyone to build to the JavaScript target and experience the\ntechnology. Once the port enters beta status it will become an enterprise only feature since it was the funding\nfrom enterprise customers that allowed this work to happen.\nContinued support from enterprise accounts is crucial for the growth of Codename One, it will allow us to build\nmore offerings such as this and expand/bolster our existing offerings. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nbryan — April 22, 2015 at 10:33 pm (permalink) bryan says:\nHave you got any demos that can be downloaded ?\nShai Almog — April 23, 2015 at 10:43 am (permalink) Shai Almog says:\nGood point. We will add some demos to the website.\nglegris — April 29, 2015 at 2:37 pm (permalink) glegris says:\nGreat work !\nDid you also consider Mozilla’s J2ME VM in Javascript: https://github.com/mozilla/… ?\nAs it provides a J2ME layer, It could avoid to write a specific port for IO and graphic primitives.\nNevertheless, not sure the project is as mature as TeaVM\nShai Almog — April 29, 2015 at 5:27 pm (permalink) Shai Almog says:\nI wasn’t familiar with that project. Interesting.\nEither way I think the TeaVM approach is probably superior in terms of compatibility to newer Java language features rather than CLDC limitations, good to know about it regardless…\nThomas Yuen — May 11, 2015 at 1:42 pm (permalink) Thomas Yuen says:\nIt is good to see js support but if it is only for the enterprise (the \u0026ldquo;rich\u0026rdquo;) customer, it is not so good (bad for biz)\nShai Almog — May 11, 2015 at 2:37 pm (permalink) Shai Almog says:\nEnterprise subscribers paid for this port so it wouldn’t exist without them.\nMore enterprise subscribers == more developers == more features and capabilities for everyone.\nSo its great this is an enterprise only feature as it will make some developers upgrade and make us a stronger/larger company. Even if you can’t afford this particular feature I’m sure you can benefit from that.\nThomas Yuen — May 11, 2015 at 5:02 pm (permalink) Thomas Yuen says:\nhope u hv a lot more enterprise cust than professional cust for i am abt to sub as prof. enterprise is bit too much for now.\nKL — May 14, 2015 at 2:28 pm (permalink) KL says:\nHi, Because of \u0026ldquo;same origin policy\u0026rdquo;, if my js apps need to do http request to origin server, should I hardcode the server domain/ip inside the apps? If not, how do I open the http request?\nConnectionRequest r = new ConnectionRequest(); r.setPost(false); r.setUrl(\u0026quot;http://www.abcdefg.com/hello.php\u0026quot;); // Possible not to hard code the domain name? NetworkManager.getInstance().addToQueue(r); Kindly advice.\nCan I ask here? Or where should I? Shai Almog — May 14, 2015 at 6:50 pm (permalink) Shai Almog says:\nIt should work exactly like it does in the simulator with the full URL’s. Keep in mind that our goal here is WORA so we want the code that works for you on the mobile native app to be the exact same code that works for the JavaScript version. You can ask here (if its relevant to the post) or in the discussion forum or in stack overflow (with the codenameone tag).\nYou can also use pro support if you signup for pro.\nKL — June 7, 2015 at 12:25 pm (permalink) KL says:\nCan I use the Display.getInstance().getProperty(\u0026quot;browser.window.location.host\u0026quot;, \u0026ldquo;DEFAULT\u0026rdquo;) to get the host/domain name? I tried, but it just return \u0026ldquo;DEFAULT\u0026rdquo; ..\nStill not implemented?\nShai Almog — June 7, 2015 at 3:05 pm (permalink) Shai Almog says:\nWhy do you you expect that to be in Display?\nYou are aware that Codename One isn’t a JavaScript/HTML5 API right?\nIts a native platform that allows you to target JavaScript, not the other way around.\nKL — June 7, 2015 at 3:33 pm (permalink) KL says:\nThanks, I am clearer now. Have to go through the developer guide again.\nGareth Murfin — May 6, 2016 at 2:18 am (permalink) Gareth Murfin says:\nJust read this again, I can say that the Javascript port works unbelievably well, it’s astounding work.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/javascript-port/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/javascript-port/html5-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are very excited to announce the alpha release of the Codename One Javascript port. This brings us one\u003cbr\u003e\nstep closer to the coveted \u003cem\u003ewrite once run anywhere\u003c/em\u003e ideal. Starting with Codename One version 3.0, you will\u003cbr\u003e\nbe able to deploy your projects as Javascript applications that run directly in the browser. The process is simple:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003eSelect the \u0026ldquo;JavaScript\u0026rdquo; build target from the right click menu.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eLog into the Codename One build server.\u003c/p\u003e","title":"Codename One in the Browser"},{"content":"\nWe are rebuilding the developer guide using JBake and asciidoc which means the guide would be better integrated\ninto the website thus providing more accessible hyperlinkable information. This is already making its way into\nthe site and into the PDF so we’d appreciate feedback.\nThis is still work in progress where we integrate the information that we conveyed in the blog over the past 18 months\ninto the guide, this is a lengthy process since the information needs to be edited into a more formal structure\nand updated with changes. Hopefully we will complete all this work by the release of 3.0 which is approaching fast. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nftp27 — April 29, 2015 at 8:58 am (permalink) ftp27 says:\nhttp://wiki.ftp27host.ru/in…\nMy partial translation old DevGuide into Russian 🙂\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-developer-guide/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-developer-guide/new-developer-guide.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are rebuilding the \u003ca href=\"/manual/\"\u003edeveloper guide\u003c/a\u003e using JBake and asciidoc which means the guide would be better integrated\u003cbr\u003e\ninto the website thus providing more accessible hyperlinkable information. This is already making its way into\u003cbr\u003e\nthe site and into the PDF so we’d appreciate feedback.\u003c/p\u003e\n\u003ch2 id=\"and-updated-with-changes-hopefully-we-will-complete-all-this-work-by-the-release-of-30-which-is-approaching-fast\"\u003eThis is still work in progress where we integrate the information that we conveyed in the blog over the past 18 months\u003cbr\u003e\ninto the guide, this is a lengthy process since the information needs to be edited into a more formal structure\u003cbr\u003e\nand updated with changes. Hopefully we will complete all this work by the release of 3.0 which is approaching fast.\u003c/h2\u003e\n\u003ch2 id=\"archived-comments\"\u003eArchived Comments\u003c/h2\u003e\n\u003cp\u003e\u003cem\u003eThis post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\u003c/em\u003e\u003c/p\u003e","title":"New Developer Guide"},{"content":"\nSending a push notification from the simulator or mobile device is pretty trivial when we use the Push\nclass. However, sending push messages from the server seems to be a bit more complicated for most developers\nsince its not as well documented. The main point of complexity is that we didn’t provide any samples of server\npush code and from the fact that the server expects arguments as POST.\nThis code should work for Java desktop and server side to perform a simple push, notice that the complexity is\nmostly related to JavaSE’s lack of simplified POST arguments.\nURLConnection connection = new URL(\u0026quot;https://codename-one.appspot.com/sendPushMessage\u0026quot;).openConnection(); connection.setDoOutput(true); connection.setRequestMethod(\u0026quot;POST\u0026quot;); connection.setRequestProperty(\u0026quot;Content-Type\u0026quot;, \u0026quot;application/x-www-form-urlencoded;charset=UTF-8\u0026quot;); String query = \u0026quot;packageName=PACKAGE_NAME\u0026amp;[[email protected]](/cdn-cgi/l/email-protection)\u0026amp;device=\u0026quot; + deviceId + \u0026quot;\u0026amp;type=1\u0026amp;auth=GOOGLE_AUTHKEY\u0026amp;certPassword=CERTIFICATE_PASSWORD\u0026amp;\u0026quot; + \u0026quot;cert=LINK_TO_YOUR_P12_FILE\u0026amp;body=\u0026quot; + URLEncoder.encode(MESSAGE_BODY, \u0026quot;UTF-8\u0026quot;); try (OutputStream output = connection.getOutputStream()) { output.write(query.getBytes(\u0026quot;UTF-8\u0026quot;)); } int c = connection.getResponseCode(); The PHP code below was sent to us by a developer, we didn’t test it but got feedback that it works fine.\n$args = http_build_query(array( 'certPassword' =\u0026gt; 'CERTIFICATE_PASSWORD', 'cert' =\u0026gt; 'LINK_TO_YOUR_P12_FILE', 'production' =\u0026gt; false, 'device' =\u0026gt; $device['deviceId'], 'packageName' =\u0026gt; 'YOUR_APP_PACKAGE_HERE', 'email' =\u0026gt; 'YOUR_EMAIL_ADDRESS_HERE', 'type' =\u0026gt; 1, 'auth' =\u0026gt; 'YOUR_GOOGLE_AUTH_KEY', 'body' =\u0026gt; $wstext)); $opts = array('http' =\u0026gt; array( 'method' =\u0026gt; 'POST', 'header' =\u0026gt; 'Content-type: application/x-www-form-urlencoded', 'content' =\u0026gt; $args ) ); $context = stream_context_create($opts); $response = file_get_contents(\u0026quot;https://codename-one.appspot.com/sendPushMessage\u0026quot;, false, $context); Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/server-initiated-push/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/server-initiated-push/push.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSending a push notification from the simulator or mobile device is pretty trivial when we use the \u003ccode\u003ePush\u003c/code\u003e\u003cbr\u003e\nclass. However, sending push messages from the server seems to be a bit more complicated for most developers\u003cbr\u003e\nsince its not as well documented. The main point of complexity is that we didn’t provide any samples of server\u003cbr\u003e\npush code and from the fact that the server expects arguments as POST.\u003c/p\u003e","title":"Server Initiated Push"},{"content":"\nDevices have sensors such as accelerometer, GPS and up until now our support for them was relatively basic.\nChen recently introduced a cn1lib\nthat includes support for various types of sensors on the device. Its really simple to use:\nSensorsManager sensor = SensorsManager.getSenorsManager(SensorsManager.TYPE_ACCELEROMETER); if (sensor != null) { sensor.registerListener(new SensorListener() { public void onSensorChanged(long timeStamp, float x, float y, float z) { //do your stuff here... } }); } Check it out if you need access to such features.\nCode Freeze We will be entering code freeze later today which should allow us to gear up towards the 3.0 release of Codename One\nin two weeks. All commits will be made against an issue and always with a peer review. Releasing 3.0 will allow\nus to improve versioned builds and cleanup our issue tracker. We already cleared more than 100 issues in the past\nweek in an effort to make this a high quality polished release.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/accelerometer-code-freeze/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/accelerometer-code-freeze/sensors.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eDevices have sensors such as accelerometer, GPS and up until now our support for them was relatively basic.\u003cbr\u003e\nChen recently introduced a \u003ca href=\"https://github.com/chen-fishbein/sensors-codenameone\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ecn1lib\u003c/a\u003e\u003cbr\u003e\nthat includes support for various types of sensors on the device. Its really simple to use:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eSensorsManager sensor = SensorsManager.getSenorsManager(SensorsManager.TYPE_ACCELEROMETER);\nif (sensor != null) {\n    sensor.registerListener(new SensorListener() {\n        public void onSensorChanged(long timeStamp, float x, float y, float z) {\n            //do your stuff here...\n        }\n    });\n}\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eCheck it out if you need access to such features.\u003c/p\u003e","title":"Accelerometer \u0026 Code Freeze"},{"content":"\nWhen Codename One packages applications into native apps we hide a lot of details to make the process simpler.\nOne of the things we had an issue with is getResource/getResourceAsStream both of which\nare problematic since they support hierarchies and a concept of package relativity.\nThat’s a concept that is problematic in iOS, generally everything about file access within the bundle in iOS\nis a bit problematic to accomplish in a cross platform way because Apple tries so hard to \u0026ldquo;simplify\u0026rdquo; and ends\nup creating fragmentation for us.\nSo we have our own getResourceAsSteam in the Display class and that works\njust fine, but it requires that all files be in the src root directory and still has some issues (e.g. if a file has 2 extensions).\nUnfortunately there is still one major use case that’s very difficult to adapt to this usage and that is html…\nWeb developers are used to constructing hierarchies to represent the various dependencies and use relative\nlinks/references. This is pretty difficult to avoid if you use pretty much any framework out there and so it was\npretty difficult to embed HTML into a Codename One application since using relative references was downright\ndifficult…\nWe now have a solution: the html package…\nJust place all of your resources in a hierarchy under the html package in the project root. Our build server will\ntar the entire content of that package and add an html.tar file into your native package instead.\nIt will then untar it on the device when you actually need the resources and only with new builds (not on every launch).\nSo just place all your HTML’s, javascripts, images \u0026amp; CSS’s in the html package and the packages/directories below it.\nThen you can use the web browser component like this:\ntry { browserComponent.setURLHierarchy(\u0026quot;/htmlFile.html\u0026quot;); } catch(IOException err) { ... } Notice that the path is relative to the html directory and starts with / but inside the HTML files\nyou should use relative (not absolute) paths. Also notice that an IOException can be thrown due\nto the process of untarring. Its unlikely to happen but is entirely possible.\nCodename One 3.0 We’ve been really bad about releasing Codename One 3.0, we wanted to do that quite a few times but\nthings got sidetracked with the new VM and various other issues that prevented us from reaching the point\nwe wanted for release.\nWe decided that now is probably the best time to do it and we shouldn’t procrastinate further. Currently\nthe tentative release date is April 27th, but this might move based on issues. With that in mind we would\nlike to have a 2 week code freeze to improve stability and bring the docs up to date. So we expect to enter\ncode freeze on April 13th next week! This means some features/issues will be delayed to post 3.0 but we are also trying to cram as many fixes as possible\ninto this release and are working hard on the issue tracker.\nWhen we release so rarely its a big problem and makes releases harder to produce, we are now thinking of\nmigrating towards a Chrome/Mozilla like release schedule and release every 3 months on a fixed freeze/release\nschedule. If you have thoughts on this please feel free to chime in.\nTeaVM In a previous post I mentioned a Javascript VM port and this was misunderstood by some developers as\nco-opting a separate open source project. Just to be clear, the work I posted about was based on\nTea VM and what Steve did was mostly create a Codename One\nport on top of that. Steve went into details here\nin his personal blog.\nSo why didn’t I just write TeaVM instead of making a generic Javascript VM statement?\nWe didn’t announce the product and I was not the technical guy involved, I’m neither familiar with the code\nor the project/people involved so I preferred to just use a generic term. I assumed people would understand\nthat when we make the actual announcement/availability we will explain the technical details including the\nrole of TeaVM in this.\nI apologize to Alexey, I had no intention of\nminimizing or reducing the credit of your effort/achievement!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/html-hierarchy-release-plan-teavm/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/html-hierarchy-release-plan-teavm/html5-banner.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen Codename One packages applications into native apps we hide a lot of details to make the process simpler.\u003cbr\u003e\nOne of the things we had an issue with is \u003ccode\u003egetResource/getResourceAsStream\u003c/code\u003e both of which\u003cbr\u003e\nare problematic since they support hierarchies and a concept of package relativity.\u003cbr\u003e\nThat’s a concept that is problematic in iOS, generally everything about file access within the bundle in iOS\u003cbr\u003e\nis a bit problematic to accomplish in a cross platform way because Apple tries so hard to \u0026ldquo;simplify\u0026rdquo; and ends\u003cbr\u003e\nup creating fragmentation for us.\u003c/p\u003e","title":"HTML Hierarchy, Release Plan \u0026 TeaVM"},{"content":"\nUp until recently we had to handcode validation logic into every form, this becomes tedious as we work\nthru larger applications. Some developers built their own generic logic, which leads to obvious duplication\nof effort. In the interest of keeping everything together we decided to release a standardized validation\nframework that allows us to define constraints on a set of components, mark invalid entries and disable\nsubmission buttons.\nSince we wanted regular expressions as a feature in the validation framework we incorporated an old regular\nexpression cn1lib that Steve ported into the API as well. This allows us to write regex in Codename One although\nwe didn’t integrate it as deeply as it is in JavaSE to avoid some of the overhead and potential incompatibilities.\nYou can see the RegEx package\ndescription for further details.\nUsing validation is pretty trivial, we use the Validator class to add constraints which define\nthe validation constraints for a specific component. We can also define the components to disable/enable\nbased on validation state and the way in which validation errors are rendered (change the components UIID,\npaint an emblem on top etc.). A Constraint is an interface that represents validation requirements.\nYou can define a constraint in Java or use some of the builtin constraints such as LengthConstraint,\nRegexConstraint etc.\nMasking isn’t a part of validation per se but it is such a common concept that I feel its use is warranted in this\nshort tutorial. Masking allows us to define input with a given structure e.g. credit card comprising of 16 digits\nsplit into groups of 4. This is common for date entry and many other types of input, we’d love to offer a more\npowerful masked input API in the future but for now you can implement a poor mans solution by using a\nDataChangedListener and stopping the current editing/moving to the next field based on\nconstraints. We implemented such masking as a sample in the code below together with a rather complete\nvalidation sample.\nThis sample below has a couple of neat tricks, the UI changes between tablet and phone form factor. It demonstrates\nmasking and various types of validation. It also demonstrates disabling the submit button to show that validation\nfailed and prevent the user from proceeding.\npublic void start() { if(current != null){ current.show(); return; } Form val = new Form(\u0026quot;Validation\u0026quot;); TableLayout tl; int spanButton = 2; if(Display.getInstance().isTablet()) { tl = new TableLayout(7, 2); } else { tl = new TableLayout(14, 1); spanButton = 1; } tl.setGrowHorizontally(true); val.setLayout(tl); val.addComponent(new Label(\u0026quot;First Name\u0026quot;)); TextField firstName = new TextField(); val.addComponent(firstName); val.addComponent(new Label(\u0026quot;Surname\u0026quot;)); TextField surname = new TextField(); val.addComponent(surname); val.addComponent(new Label(\u0026quot;E-Mail\u0026quot;)); TextField email = new TextField(); email.setConstraint(TextArea.EMAILADDR); val.addComponent(email); val.addComponent(new Label(\u0026quot;URL\u0026quot;)); TextField url = new TextField(); url.setConstraint(TextArea.URL); val.addComponent(url); val.addComponent(new Label(\u0026quot;Phone\u0026quot;)); TextField phone = new TextField(); phone.setConstraint(TextArea.PHONENUMBER); val.addComponent(phone); val.addComponent(new Label(\u0026quot;Credit Card\u0026quot;)); Container creditCardContainer = new Container(new GridLayout(1, 4)); final TextField num1 = new TextField(4); final TextField num2 = new TextField(4); final TextField num3 = new TextField(4); final TextField num4 = new TextField(4); num1.setConstraint(TextArea.NUMERIC); num2.setConstraint(TextArea.NUMERIC); num3.setConstraint(TextArea.NUMERIC); num4.setConstraint(TextArea.NUMERIC); creditCardContainer.addComponent(num1); creditCardContainer.addComponent(num2); creditCardContainer.addComponent(num3); creditCardContainer.addComponent(num4); val.addComponent(creditCardContainer); Button submit = new Button(\u0026quot;Submit\u0026quot;); TableLayout.Constraint cn = tl.createConstraint(); cn.setHorizontalSpan(spanButton); cn.setHorizontalAlign(Component.RIGHT); val.addComponent(cn, submit); Validator v = new Validator(); v.addConstraint(firstName, new LengthConstraint(2)). addConstraint(surname, new LengthConstraint(2)). addConstraint(url, RegexConstraint.validURL()). addConstraint(email, RegexConstraint.validEmail()). addConstraint(phone, new RegexConstraint(phoneRegex, \u0026quot;Must be valid phone number\u0026quot;)). addConstraint(num1, new LengthConstraint(4)). addConstraint(num2, new LengthConstraint(4)). addConstraint(num3, new LengthConstraint(4)). addConstraint(num4, new LengthConstraint(4)); automoveToNext(num1, num2); automoveToNext(num2, num3); automoveToNext(num3, num4); v.addSubmitButtons(submit); val.show(); } private void automoveToNext(final TextField current, final TextField next) { current.addDataChangeListener(new DataChangedListener() { public void dataChanged(int type, int index) { if(current.getText().length() == 5) { Display.getInstance().stopEditing(current); String val = current.getText(); current.setText(val.substring(0, 4)); next.setText(val.substring(4)); Display.getInstance().editString(next, 5, current.getConstraint(), next.getText()); } } }); } Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nDiamond — April 7, 2015 at 1:43 pm (permalink) Diamond says:\nHi Shai,\nIs the Validator and RegexConstraint present in the current plugin or will come with the next update?\nPhone number validation, will it work against 07123456789 or +97123456789 or both?\nMy suggestion on autoMoveToNext…Instead of checking the input on 5th letter why not 4 and just move the cursor to the next field for entry.\nLastly, will the keyboard close and re-open when stopEditing() and editString() are called? Or make the keyboard flashes?\nShai Almog — April 7, 2015 at 7:15 pm (permalink) Shai Almog says:\nHi,\nit made it into the current plugin and should be there already.\nNotice I just used the RegexConstraint for a phone, you can define any regex you want. We hardcoded email/URL since those are common and slightly more standardized.\nAuto move might be an interesting approach to masking, this is one of those things we need to think about.\nYes, the keyboard does flash. On my iphone this felt acceptable.\nGerben — August 12, 2015 at 8:31 am (permalink) Gerben says:\nA regex containing (?= does not seem to work yet. Example, a password that should contain at least one lowercase character:\n\u0026ldquo;^(?=.*[a-z]).{8,24}$\u0026rdquo;\nshannah78 — August 12, 2015 at 5:50 pm (permalink) shannah78 says:\nI don’t think lookarounds are supported. The Javadocs don’t mention them, and the code doesn’t look like it accommodates them:\nhttp://www.codenameone.com/…\nIf I were you I would just break this up into two constraints. E.g. The regex \u0026ldquo;[a-z]\u0026rdquo; will be sufficient to make sure it contains at least one lowercase character, and you can do the length constraint separately.\nMo — June 2, 2016 at 5:03 pm (permalink) Mo says:\nHi, thank you for an excellent work, and having used the Validator, I ran into the following issues:\n1. when I use the Validtor.setShowErrorMessageForFocusedComponent(true), the popup error message does not close as expected after correcting the invalid email/text or losing the focus on the TextField, and the only way to get ride of it, is to lose and gain the focus again on the TextField!.\n2. No internationalisation support for the error message and inline with the Label component. for example, you cannot use the RegexConstraint.validEmail(\u0026quot;invalid.email\u0026quot;) to retrive the localized message from the resource file.\n3. As the time of writing this!!, I have no idea on how to style the popup error component via CSS lib!!\nPLease advice if this is something was overlooked from my end?? and many thanks in advnce.\nShai Almog — June 3, 2016 at 4:03 am (permalink) Shai Almog says:\n1. Was this on a device?\n2. If you installed the bundle correctly you should see it localized.\n3. See setErrorMessageUIID(). It uses the PopupDialog UIID for the content itself.\nMo — June 4, 2016 at 9:24 am (permalink) Mo says:\n1. on the simulator,\nShai Almog — June 5, 2016 at 4:15 am (permalink) Shai Almog says:\nOn the device text entry behaves quite differently.\nChris — April 23, 2018 at 9:03 pm (permalink) Chris says:\nShai, keyboard will not close after automovenext(). This will lead to an issue when the device is rotated. Text in the field will display in the wrong location and misaligned as well.\nShai Almog — April 24, 2018 at 5:23 am (permalink) Shai Almog says:\nIs the parent container scrollable on the Y axis?\nAndroid resizes the screen on edit so you need to leave enough room for the text field in such cases.\nChris — April 24, 2018 at 6:45 pm (permalink) Chris says:\nYes scrollable on Y-Axis. But this is happening other way around when the tablet flipped form portrait mode to landscape.\nShai Almog — April 25, 2018 at 7:12 am (permalink) Shai Almog says:\nCan you post a screenshot? What do you mean by \u0026ldquo;other way around\u0026rdquo;?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/validation-regex-masking/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/validation-regex-masking/validation-regex-masking.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/blog/validation-regex-masking/validation-regex-masking-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eUp until recently we had to handcode validation logic into every form, this becomes tedious as we work\u003cbr\u003e\nthru larger applications. Some developers built their own generic logic, which leads to obvious duplication\u003cbr\u003e\nof effort. In the interest of keeping everything together we decided to release a standardized validation\u003cbr\u003e\nframework that allows us to define constraints on a set of components, mark invalid entries and disable\u003cbr\u003e\nsubmission buttons.\u003c/p\u003e","title":"Validation, RegEx \u0026 Masking"},{"content":"\nAs part of tracking a bug in iOS media playback Steve hit upon some code that recreated the OpenGL framebuffer\npretty much all the time. This was there to allow device rotation to work, but was implemented incorrectly…\nAfter this fix animations and UI is much smoother on iOS, if you notice any potential issues let us know.\nIn other news we just fixed two big GC issues in the new VM. The first was a rather complex edge case with GC firing\nup during native code where more than one allocation was made during the second (or later) allocations\n(yes edge case). Since objects allocated in native code still don’t have hard Java references the GC can’t \u0026ldquo;see\u0026rdquo;\nthose references and thus wiped them. The solution was pretty simple, we now toggle a flag that essentially\nblocks GC from happening while we are in such a native method…\nThe other issue was arguably harder to catch since it was more conceptual, but the fix consisted of exactly two\nlines of code… As you recall we use a mark-sweep algorithm to clean up the objects, new objects were implicitly\ncreated as marked which seemed to make a lot of sense (we create an object we will probably need it!).\nHowever, this created a rather tricky situation… If a user creates a new array e.g.:\nList objectsInListThatArentYetMarked = ...; Object[] newArrayToContainObjects = new Object[objectsInListThatArentYetMarked.size()]; objectsInListThatArentYetMarked.toArray(newArrayToContainObjects); objectsInListThatArentYetMarked = null; In this case objectsInListThatArentYetMarked will get wiped by the GC since its no longer necessary and won’t\nbe marked. Since the array is newly created it will be marked, so when our mark algorithm reaches it then it will\nsee a marked object and won’t traverse further (otherwise we will get into infinite recursions and performance penalties).\nThe solution is actually quite simple, we give newly created objects a special case -1 value and so they will\nbe marked as usual, but won’t be GC’d.\nSteve also made some fixes for premature object deletion, e.g. if we invoke a native method in C which uses\niOS’s dispatch_async calls (their equivalent of the callSerially method). By the time the async block is reached\nthe String argument might have been GC’d. However, there is a special case for releasing the NSString asynchronously\njust to avoid that. Steve made sure we don’t try to access Java objects that might be GC’d anywhere in our code.\nUpdate On JavaScript VM Steve made some pretty remarkable progress with the JavaScript VM and posted the video below showing\noff the unmodified poker demo running in a browser!\nFor those of you who haven’t followed this, the JavaScript VM port essentially works just like every other Codename One\nport where our build servers translate the java bytecode into JavaScript with the right porting layer.\nUnlike GWT this port works with threading code, unlike other solutions (such as echo2) this is a purely client\nside implementation. This would not have been possible just a couple of years ago but since JavaScript\nVM’s have come such a long way its actually proving to be a pretty interesting port. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nshannah78 — April 6, 2015 at 6:07 pm (permalink) shannah78 says:\nI would like to add that the fundamental advancement that has allowed us to run multithreaded code has nothing to do with the \u0026ldquo;Javascript VM\u0026rdquo;. Rather it is that we are using TeaVM to convert to javascript, and it includes a support for threads. This port would not have been possible without TeaVM or without Alexey Andreev’s help (TeaVM’s author). For more about TeaVM, check out https://github.com/konsolet…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/gc-crashes-bugs/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/gc-crashes-bugs/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAs part of tracking a bug in iOS media playback Steve hit upon some code that recreated the OpenGL framebuffer\u003cbr\u003e\npretty much all the time. This was there to allow device rotation to work, but was implemented incorrectly…\u003cbr\u003e\nAfter this fix animations and UI is much smoother on iOS, if you notice any potential issues let us know.\u003c/p\u003e\n\u003cp\u003eIn other news we just fixed two big GC issues in the new VM. The first was a rather complex edge case with GC firing\u003cbr\u003e\nup during native code where more than one allocation was made during the second (or later) allocations\u003cbr\u003e\n(yes edge case). Since objects allocated in native code still don’t have hard Java references the GC can’t \u0026ldquo;see\u0026rdquo;\u003cbr\u003e\nthose references and thus wiped them. The solution was pretty simple, we now toggle a flag that essentially\u003cbr\u003e\nblocks GC from happening while we are in such a native method…\u003c/p\u003e","title":"GC Crashes \u0026 Bugs"},{"content":"\nIts been a long weekend, but now that its finally over the long and tedious migration to github is almost completely\nbehind us.\nMake sure to update your URLs to the new repository at\nhttps://github.com/codenameone/CodenameOne/.\nThere are still some references to the old google code repository in the plugins etc. so you should update\nthem when we release the next update. Furthermore, if you used our custom update centers make sure your\nupdate center doesn’t reference a googlecode URL!\nNew Structure Since github encourages smaller repositories we decided it might be a good idea to split up some non-core\npieces of the project. So we moved the demos to the\ncodenameone-demos\nproject and the device skin UI resources were moved to\ncodenameone-skins.\nWe also removed some big directories containing the javadocs, repositories etc. Those are all mapped to\nserver locations on codenameone.com now.\nAnother big change is the removal of all the jar, zip and other dependencies that might be required for the\nproject build. These were major size contributors and allowed us to bring the project size down to a very manageable\nsize. Right now we are still mapping the files that are \u0026ldquo;really needed\u0026rdquo; vs. the ones that just should never\nhave been committed.\nWe created a new project called\ncn1-binaries that contains\nall those binaries. You will need to have it on the same level as the main cn1 project for everything to compile\nproperly. I’m not sure if this is OK with the github guidelines if not we will find another solution.\nThe Migration The migration was remarkably painful, the manual issue export code from Google didn’t work on Mac OS and there\nwere no public workaround. Its a Python script that assumes the users are familiar with python environments\nin a typical Google hackish sort of way. Eventually I just purchased a droplet instance from Digital Ocean and\nperformed the migration in the cloud, this has the benefit of using a very fast networking pipeline which made a\nlot of the work way faster even though I was working on a remote shared instance. It also made the python code\nwork since for things such as this Linux instructions are easier than the Mac OS instructions.\nSome issue meta-data didn’t transfer well, they are all marked as if I added them and then added all the comments\nwhich is pretty lame for a migration script. So you should make sure to signup to the issues you submitted and\nmake sure everything you provided is still there (e.g. test cases).\nSource migration was even more painful, it took roughly 15 attempts to get it right. The git-svn scripts all failed badly on\nfetching the repository during the GC phase and the only way we were eventually able to do this was thru\nthe direct svn command like this:\ngit svn clone https://codenameone.googlecode.com/svn/trunk -A .authors.txt . --no-metadata Notice that we used the --no-metadata tag which is discouraged, it just didn’t work otherwise. We also\npointed to the trunk thus discarding branch and tag data since we didn’t see any other way of getting this to work…\nUnfortunately, this was only the beginning. We ended up with a 7.4gb workspace which is obviously way too much…\nFollowing the instructions to remove directories and all their history we ended up with a 10gb repository\n(seriously…). Pruning data from a version control system is always difficult (this isn’t a GIT specific issue).\nDespite running the git gc with the aggressive and prune flag the size was still pretty huge.\nEventually the only thing that worked in shrinking the repository was to clone it to a new location using\nthe file: URL path e.g.:\ngit clone file:///path/project.git . Notice the . in the end indicating the empty current directory as the destination.\nOnce this was done we were able to split the repository to smaller repos and now we have the new\nstructure above while maintaining as much history as possible.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/github-migration-completed/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/github-migration-completed/github-logo.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIts been a long weekend, but now that its finally over the long and tedious migration to github is almost completely\u003cbr\u003e\nbehind us.\u003cbr\u003e\nMake sure to update your URLs to the new repository at\u003cbr\u003e\n\u003ca href=\"https://github.com/codenameone/CodenameOne/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttps://github.com/codenameone/CodenameOne/\u003c/a\u003e.\u003cbr\u003e\nThere are still some references to the old google code repository in the plugins etc. so you should update\u003cbr\u003e\nthem when we release the next update. Furthermore, if you used our custom update centers make sure your\u003cbr\u003e\nupdate center doesn’t reference a googlecode URL!\u003c/p\u003e","title":"Github Migration Completed"},{"content":"\nAs you may know Google is ending support for Google code effectively forcing us to migrate to github. While\nwe like a lot of things about github their 1gb per workspace restriction makes the migration process rather difficult\nsince we have to manually delete some histories for binary files we committed into SVN.\nMaking matters worse, Google’s so called \u0026ldquo;automated tools\u0026rdquo; are ridiculously simplistic and don’t support anything\nlike this or migration of more than 1000 issues!\nThis effectively means we will need to perform the migration manually, we will probably discard the existing tags\nbut we will try to preserve workspace history and the issues. This Friday we will close the issue tracker, all new issues\nwill be ignored, we will then move all the issues to a new github project that we will create for this purpose.\nWe will also move the code base and all future commits to the new repository but since commits are currently limited\nto Codename One team members this shouldn’t be a problem.\nOnce we will finish the migration we will leave the existing project in Google code for reference purposes.\nHopefully we will finish the migration process over the weekend but from past experience I’m rather pessimistic.\nThe svn2git tools were pretty badly broken the last time we checked them.\nHopefully our prior experience with such migration attempts will soften the blow and make the process easier\nthis time around. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAlexandre Richonnier — March 28, 2015 at 1:24 pm (permalink) Alexandre Richonnier says:\nMaybe you could give a chance to bitbucket?\nFor open source projects, there ‘s no limit.\nShai Almog — March 28, 2015 at 3:01 pm (permalink) Shai Almog says:\nWe looked at that and several others. While I’d love that it does seem that pretty much everyone is going to Github.\nI like Github in general, the site and tools are amazing. I think the main problem is git itself but since most people are moving in that direction we should probably align rather than fight it.\ncvconover — August 11, 2015 at 12:58 pm (permalink) cvconover says:\nShai,\nJust wondering what you do not like about git. It is the first vcs that I actually enjoyed working with from the command line.\nCheers\nCraig\nShai Almog — August 11, 2015 at 2:02 pm (permalink) Shai Almog says:\nActually I like GIT much better now with the improved tooling (3 years made a big difference).\nI love distributed versioning and loved it at Sun where it was pioneered (the guy that inspired Linus to write GIT and effectively outlined its architecture == ex Sun guy).\nThe main issue I had with GIT back then was that its conflict resolution approach was HORRIBLE, this has been greatly improved and is now in SVN level. The secondary issue was that it encrypts everything, which is great for a commercial project but for an open source project its not very useful. We had a conflict and merge broke down badly, unfortunately because everything was encrypted we effectively lost the data and couldn’t find it in history. With the old Sun unencrypted tools (SCCS) and even with SVN everything is stored as text files and if something goes wrong you can just look thru that.\nOverall, I’m much happier with Git today and I’m generally happy we made the move.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/github-migration-plan/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/github-migration-plan/github-logo.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAs you may know Google is ending support for Google code effectively forcing us to migrate to github. While\u003cbr\u003e\nwe like a lot of things about github their 1gb per workspace restriction makes the migration process rather difficult\u003cbr\u003e\nsince we have to manually delete some histories for binary files we committed into SVN.\u003cbr\u003e\nMaking matters worse, Google’s so called \u0026ldquo;automated tools\u0026rdquo; are ridiculously simplistic and don’t support anything\u003cbr\u003e\nlike this or migration of more than 1000 issues!\u003c/p\u003e","title":"Github Migration Plan"},{"content":"\nTable of Contents\nWhat does the GeoViz Library do? What is GeoJSON? GeoVizComponent vs MapComponent vs Native Maps Key Features Basic Usage Step One: Load the GeoJSON file Step Two: Create the GeoVizComponent Implementing a Custom Painter I attended a tutorial at OSCON last year on HTML5 graphics where I was introduced to some cool data-visualization technologies. One thing that left an impression was the in GeoJSON format, which we used to generate some maps inside the browser using the D3 library and SVG. This was around the time that I was working on the new Codename One graphics pipeline, so at each step of the tutorial my inner commentator was whispering \u0026ldquo;we could do this in Codename One without too much difficulty\u0026rdquo;.\nFast forward 6 months, and the new graphics pipeline is complete, so I thought, why not try implementing some of those cool GeoViz features in Codename One. We have all the pieces in place? So I present the Codename One GeoViz library.\nWhat does the GeoViz Library do? The GeoViz library allows you to load geographic data in GeoJSON format, and render it visually in your app. Below is a map of the USA that was rendered using this library.\nWhat is GeoJSON? GeoJSON is a standard format for storing geographic data in JSON format. A GeoJSON file may store a number of \u0026ldquo;features\u0026rdquo; which may include shape coordinates as well as information associated with the feature. For example, in the USA Map example, each state is a \u0026ldquo;feature\u0026rdquo; that includes shape coordinates for its contour, as well as property information such as the state name.\nOne of the nice things about GeoJSON is that it is already widely used and there are lots of existing free data sources (e.g. this GitHub Repo) where you can obtain state, country, city, etc…​ outlines that can now be easily included in your applications.\nGeoVizComponent vs MapComponent vs Native Maps Codename One already had two mechanisms for displaying maps: the MapComponent and the Native Maps library. Their purpose is different than the GeoVizComponent. Some key differences include:\nThe MapComponent uses a \u0026ldquo;tile\u0026rdquo;-based approach where it downloads tile images from a map server (e.g. Open Streetmaps or Google Maps). The GeoVizComponent renders geographic \u0026ldquo;shapes\u0026rdquo; that are stored as vectors so they can be rendered at any size, and transformed in any way you like without pixelization.\nThe MapComponent displays only maps as they are provided by the specified Map server. The GeoVizComponent will render any geographic information that can be expressed in a GeoJSON file. This might include a map of a building only, or a sparse map that only includes some key landmarks, or anything else you like.\nKey Features Pan and zoom. The component optionally supports pinch zoom and panning by dragging with your finger. You can also programmatically set the center point and zoom level, and animate the transition to the new viewport settings.\nCustom painter support. You can implement your own painters to customize how features of the map are rendered. E.g. you can change the background color or different regions based on the data in associated data sets.\nFeaturePressed/Released Events. You can detect touches to features of the map and respond to them accordingly.\nBasic Usage Step One: Load the GeoJSON file GeoJSONLoader loader = new GeoJSONLoader(); FeatureCollection coll = loader.loadJSON( Display.getInstance().getResourceAsStream(null, \u0026quot;/us-states.json\u0026quot;), \u0026quot;UTF-8\u0026quot; ); This example loads the us-states JSON file from the app resources using the GeoJSONLoader class.\nStep Two: Create the GeoVizComponent GeoVizComponent comp = new GeoVizComponent(coll); Implementing a Custom Painter The default painter will just render the map with black outlines and white fills. If you want to customize this you can install your own custom FeaturePainter. The following is an example custom painter taken from the GeoViz demo:\n// Add a custom feature painter so that we can paint states different // colors depending on the data in our CSV file. comp.setFeaturePainter(new FeaturePainter(){ /** * Callback to fill a feature (State). We implement this * so that we can fill selected states with red and other states * a color based on the currently selected year. * @param g The graphics context * @param feature The feature to paint * @param path The shape that is to be filled. */ @Override protected void fill(Graphics g, Feature feature, GeneralPath path) { int oldColor = this.getFillColor(); int oldAlpha = this.getFillAlpha(); if (feature == selectedFeature){ this.setFillColor(0xff0000); } else { RegionData[] regionData = popData.getRegionData( (String)feature.getProperties().get(\u0026quot;name\u0026quot;) ); if (currentYear \u0026gt; 0){ if (mode==MODE_POPULATION){ for (RegionData d : regionData){ if (d.year == currentYear){ if (d.pop != 0){ this.setFillColor( getColor(1.0, 0, 0, d.pop, minPopulation, maxPopulation)); this.setFillAlpha(getAlpha(d.pop, minPopulation, maxPopulation)); } break; } } } else if (mode==MODE_DENSITY){ for (RegionData d : regionData){ if (d.year == currentYear){ if (d.density != 0){ this.setFillColor(getColor(0, 1.0, 0, d.density, minDensity, maxDensity)); this.setFillAlpha(getAlpha(d.density, minDensity, maxDensity)); } break; } } } } } super.fill(g, feature, path); this.setFillColor(oldColor); this.setFillAlpha(oldAlpha); } }); For the full example, check out the GeoViz Demo.\nYou can also check out the Javadocs for the the library here. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nftp27 — March 25, 2015 at 10:27 am (permalink) Yesterday I’m solved a similar task 🙂\nChidiebere Okwudire — March 18, 2017 at 11:57 pm (permalink) Chidiebere Okwudire says:\nHi, nice! I want to do something but I’m wondering how best to convert my map (in this case an office floor map) into GeoJSON so that users can click on specific, predefined areas to designate their office spaces. Any pointers?\nChidiebere Okwudire — March 19, 2017 at 12:05 am (permalink) Chidiebere Okwudire says:\n@Steve: Demo link still points to the now extinct googlecode repo. Can you update it to point to Github?\nShai Almog — March 19, 2017 at 5:12 am (permalink) Shai Almog says:\nWe moved the demo repo here: https://github.com/codename…\nWe probably need to refresh that demo\nChidiebere Okwudire — March 25, 2017 at 10:30 pm (permalink) Chidiebere Okwudire says:\nAny idea if/how I can apply this concept to an arbitrary image? Use case is a floor map in which I want to define sitting positions such that users can click and indicate where they’re sitting for example. User ‘ftp27’ seems to have done something similar but I don’t know how…\nshannah78 — March 31, 2017 at 1:26 pm (permalink) shannah78 says:\nI’m not sure the best way to do this. It depends on what data you already have about your floor plan. E.g. Do you have the lat/lng coordinates of all office spaces? How big is the floor plan? If you don’t have the coordinates, it might be just as easy to create some sort of \u0026ldquo;hot\u0026rdquo; map to make certain areas clickable. There might be specific tools for doing a job like this, but in the worst case, I might just open my floor plan in photoshop, then create a new layer for each clickable office space and draw a rectangle of some sort on that layer over the corresponding office space. You could probably then export the layers in a way that you could feed into your app.\nI’ve never had to perform this task though so there may be better ways.\nChidiebere Okwudire — April 2, 2017 at 3:28 pm (permalink) Chidiebere Okwudire says:\nAll I have is a high-res jpeg. I’ve read a bit more about GeoViz and it indeed appears to be for geospatial data and not arbitrary images.\nIt’s pretty easy for me to determine the pixels coordinates of the polygons bounding the desired spaces. However, given the different DPIs on various devices, I doubt this will work… What coordinates are provided in the pointerPressed(), pointerReleased() methods of the ImageViewer class? I’m wondering if I can map these in a DPI-independent way…\nShai Almog — April 2, 2017 at 5:03 pm (permalink) Shai Almog says:\nYou can just scale both images together and use getRGB to get the pixel data of the color map.\nYou could use ImageViewer or just do something similar, check out its code.\nChidiebere Okwudire — April 5, 2017 at 3:05 am (permalink) Chidiebere Okwudire says:\nI’m not sure I completely get it: How does getRGB help in this case? On the original image, I define the coordinates of the bounding boxes of areas of interest. My challenge is how to translate these to the scaled image regardless of device DPI such that I can detect clicks within those areas and do other things like draw overlays.\nShai Almog — April 5, 2017 at 4:32 am (permalink) Shai Almog says:\nI don’t see the problem. You can just draw the image in any resolution you want.\nChidiebere Okwudire — April 5, 2017 at 5:41 am (permalink) Chidiebere Okwudire says:\nOkay. I’ll try it out and let you know if I run into any difficulties 😉\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/geo-visualization-library/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/geo-visualization-library/geoviz_demo.png\"\u003e\u003c/p\u003e\n\u003cp\u003eTable of Contents\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eWhat does the GeoViz Library do?\n\u003cul\u003e\n\u003cli\u003eWhat is GeoJSON?\u003c/li\u003e\n\u003cli\u003eGeoVizComponent vs MapComponent vs Native Maps\u003c/li\u003e\n\u003cli\u003eKey Features\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eBasic Usage\n\u003cul\u003e\n\u003cli\u003eStep One: Load the GeoJSON file\u003c/li\u003e\n\u003cli\u003eStep Two: Create the GeoVizComponent\u003c/li\u003e\n\u003cli\u003eImplementing a Custom Painter\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eI attended a tutorial at OSCON last year on HTML5 graphics where I was introduced to some cool data-visualization technologies. One thing that left an impression was the in \u003ca href=\"http://geojson.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGeoJSON format\u003c/a\u003e, which we used to generate some maps inside the browser using the D3 library and SVG. This was around the time that I was working on the new Codename One graphics pipeline, so at each step of the tutorial my inner commentator was whispering \u0026ldquo;we could do this in Codename One without too much difficulty\u0026rdquo;.\u003c/p\u003e","title":"Geo-Viz and Codename One"},{"content":"\nNow that the new website is live we are down to standard business again beyond just the typical bug fixes. Chen just updated the gallery support to include the ability to pick a video file and not just an image file.\nThe default functionality remains the same and compatible but now you can do something like:\nDisplay.getInstance().openGallery(new ActionListener() { public void actionPerformed(ActionEvent ev) { if(ev != null \u0026amp;\u0026amp; ev.getSource() != null) { String filePathToGalleryImageOrVideo = (String)ev.getSource(); .... } } }, Display.GALLERY_ALL); You can now use GALLERY_ALL, GALLERY_VIDEO or GALLERY_IMAGE to pick either one or both when showing\nthe gallery UI.\nA rather interesting issue was opened last week where a developer got a reject from Apple’s upload tool\ndue to an invalid binary. Missing the Icon.png file…\nOur iOS project build is pretty complex e.g.\nit takes screenshots\nand it also handles things like icon resizing. The latter is much simpler, we generate the roughly 10 icon\nsizes the Apple needs for the various iOS devices from the one icon you supply (seriously they expect 10 icons…).\nWe store these icons in the bundle and in this case the developer also stored an icon.png file in the root triggering\na collision. Naturally our build process needs to be smarter and catch onto those things but I would recommend\nthat you also practice caution when placing files in the root and try to place as much as possible within res files\n(yes you can have more than one) especially because they let you take advantage of multi-images.\nQuick note about the github migration plans We haven’t started yet since we need to cleanup a lot of things first. We also need to start updating the\nplugins and everything involved to the new URL’s. Once everything is planned out we will start a migration,\nhopefully issues will be able to make the transition.\nWe hope to publish a detailed transition plan sometime in the next couple of weeks.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/gallery-icon-update/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/gallery-icon-update/gallery-chart-fonts-icon.png\"\u003e\u003c/p\u003e\n\u003cp\u003eNow that the new website is live we are down to standard business again beyond just the typical bug fixes. Chen just updated the gallery support to include the ability to pick a video file and not just an image file.\u003cbr\u003e\nThe default functionality remains the same and compatible but now you can do something like:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eDisplay.getInstance().openGallery(new ActionListener() {\n    public void actionPerformed(ActionEvent ev) {\n        if(ev != null \u0026amp;\u0026amp; ev.getSource() != null) {\n            String filePathToGalleryImageOrVideo = (String)ev.getSource();\n            ....\n        }\n    }\n}, Display.GALLERY_ALL);\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eYou can now use GALLERY_ALL, GALLERY_VIDEO or GALLERY_IMAGE to pick either one or both when showing\u003cbr\u003e\nthe gallery UI.\u003c/p\u003e","title":"Gallery, Icons \u0026 Updates"},{"content":"\nThe new Codename One website is finally live now and you can check it out in all its glory at codenameone.com.\nThere are several things you need to know in order to make the transition smooth. First is that the new website supports https thruout so you can just navigate\nto https://www.codenameone.com/ to get a secure site. This is forced implicitly when you\ngo to the build server. In the old site we used an iframe on top of https for the build server, while this was secure it didn’t convey the trust\nlevel that should be conveyed.\nWhile the new build server UI should be pretty complete, there are some features we didn’t migrate yet, the old interface is still available if you\nneed it right here and will be for quite some time. We are still working hard to improve the website\nbut if you have any issues/broken links or suggestions please post them here.\nWe tried to migrate all the blog posts from the old blog, this worked with partial success specifically:\nDates/times on some of the older posts are incorrect Hierarchy got broken Emails are missing so you won’t get notified on responses to old comments. Some comments were \u0026ldquo;just lost\u0026rdquo; – its hard to know which ones though… However, the vast majority of the information (close to 1k comments) was preserved and provides a lot of important information\nabout our older blog posts. We migrated all the older posts but some formatting might be broken, we couldn’t go over all of them\n(there are hundreds from just the past two years) but if we missed something please let us know!\nMigration Part II Since Google killed Google Code over the weekend we are now faced with another migration to github. We started originally working\nwith github and quickly moved to Google Code which in our opinions still has a lot of advantages despite its clunky and outdated\ninterface. Specifically the biggest problem is migrating this amount of issues and a workspace of this size…\nEven simple projects that we tried to migrate such as the Google Native Maps project had failures in the migration process\nand this doesn’t leave us in a state of confidence about github fixing their problems.\nNow before people jump to conclusions about \u0026ldquo;us not understanding \u0026ldquo;distributed version controls advantages\u0026rdquo; a brief history\nlesson about git… Do you know it was actually inspired by Sun and that we used a distributed versioning system there for years\nthat IMO was FAR superior to git?\nIf you recall some of the history of git it\nwas inspired by Bit Keeper which is a proprietary\ntool built by an ex-Sun guy based on the work he did at Sun. So at Sun we used an older tool that was pretty great and far\nbetter than git. It didn’t have size restrictions and even had a halfway decent gui. It had its problems (NFS reliance) but\ngit has a whole set of other far greater problems such as painful conflict resolutions and assumptions about the\nway a workspace should be.\nSo to workaround the issues with github and remove the dependencies on google code we are now moving all the\nbinary files that we have in Google code to our servers with some exceptions. The JavaDocs are already hosted\nin this site, we will also migrate the Eclipse repository here so if you added the old URL you will need to update it to\nhttp://codenameone.com/eclipse/site.xml.\nSince other IDE’s (NetBeans \u0026amp; IntelliJ) both have a great central repository we will retire our own\nrepositories and you should get your updates from there. Make sure to do that since updated libs in the\nold repository will no longer work… Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nftp27 — March 17, 2015 at 3:12 pm (permalink) ftp27 says:\nVery sad bugs in new build server. Builds automatically deleted after build.\nShai Almog — March 17, 2015 at 6:01 pm (permalink) Shai Almog says:\nThe build server wasn’t replaced, its just a UI on top of the old server which you can still see here: https://codename-one.appspo… so all your builds should be perfectly fine!\nI’m not sure if I understand what you mean, did you try reloading the page?\nI see a build in progress here. Old builds are only kept up to 5 past builds and only for paying users. This was always the case.\nftp27 — March 19, 2015 at 10:57 am (permalink) ftp27 says:\nIt’s works. Thanks!\nChidiebere Okwudire — May 20, 2015 at 10:25 am (permalink) Chidiebere Okwudire says:\nIs it on purpose that the new website no longer gives a clear overview of all the platforms supported by CN1? I personally find that a sad omission. Can the list of supported platforms be re-introduced?\nNote, this information is still available via wikipedia at http://en.wikipedia.org/wik…\nShai Almog — May 20, 2015 at 5:15 pm (permalink) Shai Almog says:\nWhy is that necessary?\nThe wikipedia article is actually out of date since we now support a JavaScript build target so our platform support is wider.\nChidiebere Okwudire — May 21, 2015 at 7:08 am (permalink) Chidiebere Okwudire says:\nSuppose a new potential subscriber stumbles on your website, won’t it be very handy to see an overview of what platforms are supported? Right now all one sees is ‘Write Once Run Anywhere’ and the question that immediately comes to mind is: \u0026ldquo;Where is ‘anywhere’? I couldn’t find any single page on the website that answers this basic question. And when one googles for \u0026ldquo;CodenameOne supported platforms\u0026rdquo;, the first hit is that wiki page which you said is out-dated so that doesn’t help.\nLike I’ve mentioned to you before, I still think the marketing of this great product can/should be better 😉\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-website-now-live/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-website-now-live/newWebsiteLarge.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe new Codename One website is finally live now and you can check it out in all its glory at \u003ca href=\"http://codenameone.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ecodenameone.com\u003c/a\u003e.\u003cbr\u003e\nThere are several things you need to know in order to make the transition smooth. First is that the new website supports https thruout so you can just navigate\u003cbr\u003e\nto \u003ca href=\"https://www.codenameone.com/\"\u003ehttps://www.codenameone.com/\u003c/a\u003e to get a secure site. This is forced implicitly when you\u003cbr\u003e\ngo to the build server. In the old site we used an iframe on top of https for the build server, while this was secure it didn’t convey the trust\u003cbr\u003e\nlevel that should be conveyed.\u003c/p\u003e","title":"New Website Now Live!"},{"content":"\nThis website/blog has gotten really long in the tooth, we would have replaced it ages ago but since the build server is so tightly integrated in the code the effort to migrate was just too big. So recently we finally made the effort and migrated large blocks of code to be far more generic and we are now working hard on moving more than 3 years of content to the new website…\nBut I want to talk to you about something different and rather cool I discovered: JBake.\nDon’t let the spartan website fool you. Its a really cool and rather complete tool that’s meant to be Java’s answer to Jekyll.\nIn case you aren’t very familiar with the current fashion in website development, the current trend is static websites that can be super scalable and easy to deploy. Thanks to modern day JavaScript, such static websites are still very dynamic and interactive while providing levels of performance/scalability that are ridiculously high with CDN’s.\nThe problem here is that you want stuff to still be easy to maintain, e.g. if you have site-wide navigation\ncode you would want to reuse it. That’s where JBake comes in.\nIt allows you to use tools like FreeMarker,\nAsciiDoc etc. during website build time (rather than dynamically in runtime) thus generate a static website\nwith dynamic scripts. The basic level is things like server side includes done statically, but it also generates\nthings like the RSS feed (statically) and pretty much everything you need!\nOne of the nice things about it is that even if the tool isn’t perfectly mature in some ways since the output is\nstatic HTML so this isn’t something your users will ever be exposed to. JBake\nis very intuitive if you have Java programming experience, I had the basic site, with blog and designs running in less than a day and within two days it was perfect.\nAnother plus is that the community is very open and supportive which is hugely important when you are picking up any such tool.\nCurrently the only struggle is in migrating everything over since our existing CMS really made a mess of all the data and I still have no idea how we will migrate the old blog comments…\nSince JBake doesn’t have a logo file I chose to include a \u0026ldquo;teaser\u0026rdquo; to the\nJavaScript port of Codename One…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/jbake-new-website-coming-soon/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/jbake-new-website-coming-soon/javascript_port_teaser.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/blog/jbake-new-website-coming-soon/javascript_port_teaser.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThis website/blog has gotten really long in the tooth, we would have replaced it ages ago but since the build server is so tightly integrated in the code the effort to migrate was just too big. So recently we finally made the effort and migrated large blocks of code to be far more generic and we are now working hard on moving more than 3 years of content to the new website…\u003c/p\u003e","title":"JBake \u0026 New Website Coming Soon"},{"content":"Accepting Payments With Zooz Home Monetization Accepting Payments With Zooz To integrate with Zooz you need to register with them here and create a new application in their console. Make sure to create separate applications for iOS and Android since the keys can\u0026rsquo;t be reused between the platforms. We will try to add HTML5 support for Blackberry in a future update.\nOnce you did that the Codename One Payment API will seamlessly work with Zooz which is defined as a Manual payment provider and allows you to pay a fixed amount in a given currency.\n","permalink":"https://www.codenameone.com/accepting-payments-with-zooz/","summary":"\u003ch1 id=\"accepting-payments-with-zooz\"\u003eAccepting Payments With Zooz\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/monetization.html\"\u003eMonetization\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eAccepting Payments With Zooz\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eTo integrate with Zooz you need to register with them here and create a new application in their console. Make sure to create separate applications for iOS and Android since the keys can\u0026rsquo;t be reused between the platforms. We will try to add HTML5 support for Blackberry in a future update.\u003c/p\u003e\n\u003cp\u003eOnce you did that the Codename One Payment API will seamlessly work with Zooz which is defined as a Manual payment provider and allows you to pay a fixed amount in a given currency.\u003c/p\u003e","title":"Accepting Payments With Zooz"},{"content":"Advanced Build Build hints/arguments allow us to manipulate the build process on the build servers\nHome Developers Advanced Build Sending Build Settings To The Server When sending a build to the server you can provide additional parameters to the build which will be incorporated into the build process on the server to hint on multiple different build time options.You can do this by right clicking the Codename One project and entering the project properties. There you will find the \u0026ldquo;Build Hints\u0026rdquo; tab in which you can just type the arguments and the appropriate values from the list below.\nWe removed this page since it duplicates content from the developer guide and we should probably maintain only one authoritative list. The up to date list is here.\n","permalink":"https://www.codenameone.com/advanced-build/","summary":"\u003ch1 id=\"advanced-build\"\u003eAdvanced Build\u003c/h1\u003e\n\u003cp\u003eBuild hints/arguments allow us to manipulate the build process on the build servers\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://beta.codenameone.com/getting-started.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDevelopers\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eAdvanced Build\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"sending-build-settings-to-the-server\"\u003eSending Build Settings To The Server\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"Build Hints UI\" loading=\"lazy\" src=\"/uploads/advanced_build.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen sending a build to the server you can provide additional parameters to the build which will be incorporated into the build process on the server to hint on multiple different build time options.You can do this by right clicking the Codename One project and entering the project properties. There you will find the \u0026ldquo;Build Hints\u0026rdquo; tab in which you can just type the arguments and the appropriate values from the list below.\u003c/p\u003e","title":"Advanced Build"},{"content":"","permalink":"https://www.codenameone.com/javadoc/","summary":"","title":"API"},{"content":"Architecture Of The GUI Builder Home Developers Architecture Of The GUI Builder The Codename One GUI builder has several unique underlying concepts that aren\u0026rsquo;t as common among such tools, in this article I will try to clarify some of these basic ideas.\nBasic Concepts The Codename One Designer isn\u0026rsquo;t a standard code generator, the UI is saved within the resource file and can be designed without the source files available. This has several advantages:\nNo fragile generated code to break. Designers who don\u0026rsquo;t know Java can use the tool. The \u0026ldquo;Codename One LIVE!\u0026rdquo; application can show a live preview of your design as you build it. Images and theme settings can be integrated directly with the GUI without concern. The tool is consistent since the file you save is the file you run. GUI\u0026rsquo;s/themes can be downloaded dynamically without replacing the application (this can reduce download size). It allows for control over application flow. It allows preview within the tool without compilation. This does present some disadvantages and oddities:\nIts harder to integrate custom code into the GUI builder/designer tool. The tool is somewhat opaque, there is no \u0026ldquo;code\u0026rdquo; you can inspect to see what was accomplished by the tool. If the resource file grows too large it can significantly impact memory/performance of a running application. Binding between code and GUI isn\u0026rsquo;t as intuitive and is mostly centralized in a single class. In theory you don\u0026rsquo;t need to generate any code, you can load any resource file that contains a UI element as you would normally load a Resource file:\nResources r = Resources.open(\u0026#34;/myFile.res\u0026#34;); Then you can just create a UI using the UIBuilder API:\nUIBuilder u = new UIBuilder(); Container c = u.createContainer(r, \u0026#34;uiNameInResource\u0026#34;); (Notice that since Form \u0026amp; Dialog both derive from Container you can just downcast to the appropriate type).\nThis would work for any resource file and can work completely dynamically! E.g. you can download a resource file on the fly and just show the UI that is within the resource file\u0026hellip; That is what Codename One LIVE! is doing internally.\nIDE Bindings While the option of creating a Resource file manually is powerful, its not nearly as convenient as modern GUI builders allow. Developers expect the ability to override events and basic behavior directly from the GUI builder and in mobile applications even the flow for some cases.\nTo facilitate IDE integration we decided on using a single Statemachine class, similar to the common controller pattern. We considered multiple classes for every form/dialog/container and eventually decided this would make code generation more cumbersome.\nThe designer effectively generates one class \u0026ldquo;StatemachineBase\u0026rdquo; which is a subclass of UIBuilder (you can change the name/package of the class in the Codename One properties file at the root of the project). StatemachineBase is generated every time the resource file is saved assuming that the resource file is within the src directory of a Codename One project. Since the state machine base class is always generated, all changes made into it will be overwritten without prompting the user.\nUser code is placed within the Statemachine class, which is a subclass of the Statemachine Base class. Hence it is a subclass of UIBuilder!\nWhen the resource file is saved the designer generates 2 major types of methods into Statemachine base:\nFinders - findX(Container c). A shortcut method to find a component instance within a hierarchy of containers. Effectively this is a shortcut syntax for UIBuilder.findByName(), its still useful since the method is type safe. Hence if a resource component name is changed the find() method will fail in subsequent compilations.\nCallback events - these are various callback methods with common names e.g.: onCreateFormX(), beforeFormX() etc. These will be invoked when a particular event/behavior occurs.\nWithin the GUI builder, the event buttons would be enabled and the GUI builder provides a quick and dirty way to just override these methods. To prevent a future case in which the underlying resource file will be changed (e.g formX could be renamed to formY) a super method is invoked e.g. super.onCreateFormX();\nThis will probably be replaced with the @Override annotation when Java 5 features are integrated into Codename One.\nWorking With The Generated Code The generated code is rather simplistic, e.g. the following code from the tzone demo adds a for the remove button toggle:\nAs you can see from the code above implementing some basic callbacks within the state machine is rather simple. The method findFriendsRoot(c.getParent()); is used to find the \u0026ldquo;FriendsRoot\u0026rdquo; component within the hierarchy, notice that we just pass the parent container to the finder method. If the finder method doesn\u0026rsquo;t find the friend root under the parent it will find the \u0026ldquo;true\u0026rdquo; root component and search there. The friends root is a container that contains the full list of our \u0026ldquo;friends\u0026rdquo; and within it we can just work with the components that were instantiated by the GUI builder. Implementing Custom Components There are two basic approaches for custom components:\nOverride a specific type - e.g. make all Form\u0026rsquo;s derive a common base class. Replace a deployed instance. The first uses a feature of UIBuilder which allows overriding component types, specifically override createComponentInstance to return an instance of your desired component e.g.:\nThis code allows me to create a unified global form subclass. That\u0026rsquo;s very useful when I want so global system level functionality that isn\u0026rsquo;t supported by the designer normally.\nThe second approach allows me to replace an existing component:\nNotice that we replace the title with an empty label, in this case we do this so we can later replace it while animating the replace behavior thus creating a slide-in effect within the title. It can be replaced though, for every purpose including the purpose of a completely different custom made component. By using the replace method the existing layout constraints are automatically maintained.\n","permalink":"https://www.codenameone.com/architecture-of-the-gui-builder/","summary":"\u003ch1 id=\"architecture-of-the-gui-builder\"\u003eArchitecture Of The GUI Builder\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eDevelopers\u003c/li\u003e\n\u003cli\u003eArchitecture Of The GUI Builder\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eThe Codename One GUI builder has several unique underlying concepts that aren\u0026rsquo;t as common among such tools, in this article I will try to clarify some of these basic ideas.\u003c/p\u003e\n\u003ch3 id=\"basic-concepts\"\u003eBasic Concepts\u003c/h3\u003e\n\u003cp\u003eThe Codename One Designer isn\u0026rsquo;t a standard code generator, the UI is saved within the resource file and can be designed without the source files available. This has several advantages:\u003c/p\u003e","title":"Architecture Of The GUI Builder"},{"content":"Archived Builds Home Developers Archived Builds This functionality was deprecated in recent versions and is no longer supported\n","permalink":"https://www.codenameone.com/archived-builds/","summary":"\u003ch1 id=\"archived-builds\"\u003eArchived Builds\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://beta.codenameone.com/getting-started.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDevelopers\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eArchived Builds\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eThis functionality was deprecated in recent versions and is no longer supported\u003c/p\u003e","title":"Archived Builds"},{"content":"The build server was moved to https://cloud.codenameone.com/secure/index.html\n","permalink":"https://www.codenameone.com/build-server/","summary":"\u003cp\u003eThe build server was moved to \u003ca href=\"https://cloud.codenameone.com/secure/index.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttps://cloud.codenameone.com/secure/index.html\u003c/a\u003e\u003c/p\u003e","title":"Build Server"},{"content":"Codename One Cloud Services Home Developers Cloud Services Codename One offers seamless cloud services specifically tailored for mobile device requirements and integrations with our content partners. These services include auto-configuration of device networking, push notification, analytics, ad network integrations, web services as well as quite a few other elaborate features.\nThe cloud services can be used by developers as they see fit.\n","permalink":"https://www.codenameone.com/cloud/","summary":"\u003ch1 id=\"codename-one-cloud-services\"\u003eCodename One Cloud Services\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003eHome\u003c/li\u003e\n\u003cli\u003eDevelopers\u003c/li\u003e\n\u003cli\u003eCloud Services\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eCodename One offers seamless cloud services specifically tailored for mobile device requirements and integrations with our content partners. These services include auto-configuration of device networking, push notification, analytics, ad network integrations, web services as well as quite a few other elaborate features.\u003c/p\u003e\n\u003cp\u003eThe cloud services can be used by developers as they see fit.\u003c/p\u003e","title":"Cloud"},{"content":"Codename One IDE Plugin (Integrated Development Environment) Home Developers IDE Plugin Codename One integrates seamlessly with the leading Java development environments (NetBeans \u0026amp; Eclipse) using the Codename One IDE plugin. The plugin simplifies \u0026amp; streamlines common tasks such as creating a new project, running/debugging it in the simulator and sending it to the build server.\nThe plugin is effectively the backbone between the Codename One Designer tool, the Codename One Build Server \u0026amp; Codename One API/Services.\nThe plugin, consists of several layers. Its visual layer merely adapts the IDE to the requirements of the Codename One platform, however its architecture is generic and based on an Apache Ant build system allowing its functionality to be leveraged even without IDE\u0026rsquo;s.\nUnlike similar tools the plugin is not all encompassing and developers can customize all aspects of the build process using Ant scripts and commonly available tools.\n","permalink":"https://www.codenameone.com/codename-one-ide-plugin-integrated-development-environment/","summary":"\u003ch1 id=\"codename-one-ide-plugin-integrated-development-environment\"\u003eCodename One IDE Plugin (Integrated Development Environment)\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eDevelopers\u003c/li\u003e\n\u003cli\u003eIDE Plugin\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eCodename One integrates seamlessly with the leading Java development environments (NetBeans \u0026amp; Eclipse) using the Codename One IDE plugin. The plugin simplifies \u0026amp; streamlines common tasks such as creating a new project, running/debugging it in the simulator and sending it to the build server.\u003c/p\u003e\n\u003cp\u003eThe plugin is effectively the backbone between the Codename One Designer tool, the Codename One Build Server \u0026amp; Codename One API/Services.\u003c/p\u003e","title":"Codename One IDE Plugin (Integrated Development Environment)"},{"content":"Codename One LIVE! Home Developers LIVE! The Codename One LIVE! mobile application allows developers to monitor their Codename One Build Server \u0026amp; connect to the Codename One Designer for live editing of user interface elements on the device!\nWhen a build is completed on the Codename One Build Server developers can simply launch Codename One LIVE! and click on the application entry to instantly install the application over the air! Furthermore, when developing user interfaces using the Codename One Designer tool, the Codename One LIVE! application allows developers/designers to preview the UI being built on the desktop instantly. Without the process of sending a build. This allows developers and designers to work closely together and get instant feedback on device \u0026ldquo;feel\u0026rdquo; for their user interfaces.\nYou can install Codename One LIVE! by logging into the build server and selecting the LIVE! tab within it.\n","permalink":"https://www.codenameone.com/codename-one-live/","summary":"\u003ch1 id=\"codename-one-live\"\u003eCodename One LIVE!\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003eHome\u003c/li\u003e\n\u003cli\u003eDevelopers\u003c/li\u003e\n\u003cli\u003eLIVE!\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eThe Codename One LIVE! mobile application allows developers to monitor their Codename One Build Server \u0026amp; connect to the Codename One Designer for live editing of user interface elements on the device!\u003c/p\u003e\n\u003cp\u003eWhen a build is completed on the Codename One Build Server developers can simply launch Codename One LIVE! and click on the application entry to instantly install the application over the air! Furthermore, when developing user interfaces using the Codename One Designer tool, the Codename One LIVE! application allows developers/designers to preview the UI being built on the desktop instantly. Without the process of sending a build. This allows developers and designers to work closely together and get instant feedback on device \u0026ldquo;feel\u0026rdquo; for their user interfaces.\u003c/p\u003e","title":"Codename One LIVE!"},{"content":"Comparison Chart We charge for all our products and services using PayPal (which accepts credit cards), we also accept SWIFT money transfers for annual subscriptions of pro level or higher. If you require specific invoicing types please use our contact form with your details.\nCodename One provides a 30 day money back guarantee with no questions asked for all purchases made via paypal, please use our contact form if you are unsatisfied in any way with your purchased subscription.\nPlease notice that all standard licenses are individual (per developer seat) and are non-transferable.\nFree $0/mo\nCommunity Support Royalty Free iOS Builds Android Builds Windows Phone Builds Blackberry Builds Sign Up\nBasic $19/mo\nUnlimited Build Credits 50mb build Size Access To Native Sources Sign Up\nProfessional $849 Annually\n$79/mo\nPush Notification Online Training On Device Unit Tests Concurrent Builds Versioning Live Preview Crash Reporting E-Mail Support Native Desktop Apps Sign Up\nEnterprise $3,799 Annually\n$399/mo\nHigh Priority Builds JavaScript App Generation Continuous Integration Office Hours/Phone Support Optional SLA Sign Up\nWhat\u0026rsquo;s The Benefit Of A Pro Subscription? We created videos detailing some of the benefits of a pro subscription. The biggest benefit is the extensive email support however these features are also very useful:\nPush notification Codename One LIVE! Versioning Cloud storage/files Crash protection Use source download Native Desktop apps for Mac OS X and Windows FAQ\u0026rsquo;s Can I build more than one app?\nThere are no limits on the number of apps or number of users! Our pricing is per developer seat.\nHow many licenses do I need?\nOne per every developer on your team that is working with Codename One.\nCan I purchase a basic license for one developer in my team and an enterprise license for another? Can I mix license grades?\nNo. All licenses within the organization must be of the same subscription level and every developer needs a license. We find that additional developers start routing support requests through the paid account making the complexity of supporting the enterprise/pro account within the org much higher.\nIf we end development with Codename One but still have an app in the store do we still need to pay?\nOnly if you use push services/crash protection or other cloud features. If you don\u0026rsquo;t use the runtime cloud services the application will work without the cloud regardless of your subscription status. Notice that the developer documentation highlights such services as cloud services and they are always limited to pro subscriptions or higher.\nCan I use Codename One for free on a commercial project?\nYes. To avoid abuse free users are limited to 100 build credits every month. Paid users have no such restriction. Enterprise/Pro developers are allowed to send multiple builds concurrently without any limitations. Builds are prioritized based on subscription level, some of the build servers are dedicated strictly for Enterprise/Pro subscription hence providing them with better service/speed.\nCan I build to all devices for free?\nYes. Up to 100 credits per month with an iOS build taking up 8 credits due to the cost of running Mac servers in the cloud and the longer build times.\nWhat is the size limitation?\nFree users have a 1MB limit on the size of the JAR file sent to the build server\nWhat about academic licenses?\nThe base version of Codename One was designed to be sufficient for the needs of academic/research work so there is no need for academic specific licenses.\nWhat are the quotas for push services?\nPro users are limited to 1M messages per month which cannot exceed, 50,000 messages per day and 3,000 messages per hour. Enterprise are limited to 10M messages per month 500,000 per day and 30,000 per hour. If you need more than that you can use multiple enterprise accounts or contact us.\nCan I build offline?\nCodename One is an open source project and that includes all the pieces including the native device ports. However, as a policy the Codename One team doesn\u0026rsquo;t provide help in compiling these sources since the complexity of supporting this process is excessive. For enterprise class account we provide technical support for such issues but no explicit or easy to use tools! This service is provided not as a practical day to day tool but rather to provide the sense of a safety net. Codename One also supports a corporate server setups which effectively install a company wide private cloud within the organization, this is a more practical approach than building offline since it combines the simplicity of the cloud without the corporate complexities. See the corporate section below for more information on that offering.\nCan I download the sources generated by the server?\nOnly paid subscribers can download the sources generated by the server. However, sources are only generated for Android/iOS \u0026amp; Windows Phone. On J2ME/Blackberry there are no sources generated and the work is performed entirely on the bytecode level.\nCan I use Codename One to build desktop apps?\nYes, however they will look like a tablet application and act very much like it in terms of scrolling behavior. You will need a pro account to build native desktop apps.\nWould desktop apps be \u0026ldquo;really\u0026rdquo; native?\nThey are Java applications wrapped with a native installer/wrapper. They feel like a mobile application within a desktop which is a reasonable user experience for some cases e.g. Windows tablets.\nWhy do I need a pro account for a desktop app?\nThe bundled JRE significantly increases the size of the build and the space/bandwidth it takes for our servers to process such a build. This is a heavy cost which is why we are only enabling this as a pro feature at this time.\nCorporate Server The corporate offering provides customers with the ability to install a Codename One build cloud within their corporate firewall. This provides the corporations sys-admins the ability to guarantee security thru existing means. Since the servers are installed on premise the pricing is for the server offering only and one year of updates. In a corporate setting support is priced separately since no limitation is made on the number of developers although it isn\u0026rsquo;t a requirement to purchase support. The starting price for the corporate server before support costs is $19,900 annually.\nSupport is provided for the process of administering and installing the corporate server both by phone \u0026amp; email with on-site support available at additional pay.\nThe corporate solution requires that your company perform the setup and installation of at least 4 separate servers with a complex configuration process. This requires a trained system administrator to perform the setup based on instructions from Codename One.\nIf you think the corporate server is right for you please fill out the form here.\n","permalink":"https://www.codenameone.com/comparison-chart/","summary":"\u003ch1 id=\"comparison-chart\"\u003eComparison Chart\u003c/h1\u003e\n\u003cp\u003eWe charge for all our products and services using PayPal (which accepts credit cards), we also accept SWIFT money transfers for annual subscriptions of pro level or higher. If you require specific invoicing types please use our \u003ca href=\"/contact-us.html\"\u003econtact form\u003c/a\u003e with your details.\u003c/p\u003e\n\u003cp\u003eCodename One provides a 30 day money back guarantee with no questions asked for all purchases made via paypal, please use our \u003ca href=\"/contact-us.html\"\u003econtact form\u003c/a\u003e if you are unsatisfied in any way with your purchased subscription.\u003c/p\u003e","title":"Comparison Chart"},{"content":"ComponentSource Notice: This web-page is here for historical reasons. We no longer work with ComponentSource.\nAs Official Distributors, ComponentSource offers convenient, one-stop shopping from 250+ Software Publishers specializing in Application Development \u0026amp; Operations.\nYou can see Codename One\u0026rsquo;s section in the ComponentSource website well as individual products and their prices.\nThere you can see the list of toll free numbers in the attached spreadsheet below.\nDownload Toll Free Numbers XLS file\n","permalink":"https://www.codenameone.com/componentsource/","summary":"\u003ch1 id=\"componentsource\"\u003eComponentSource\u003c/h1\u003e\n\u003cp\u003e\u003cstrong\u003eNotice:\u003c/strong\u003e This web-page is here for historical reasons. We no longer work with ComponentSource.\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/uploads/component_source_logo.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAs Official Distributors, ComponentSource offers convenient, one-stop shopping from 250+ Software Publishers specializing in Application Development \u0026amp; Operations.\u003c/p\u003e\n\u003cp\u003eYou can see Codename One\u0026rsquo;s section in the \u003ca href=\"http://www.componentsource.com/features/codenameone/index.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eComponentSource website\u003c/a\u003e well as \u003ca href=\"http://www.componentsource.com/products/codename-one/index-gbp.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eindividual products and their prices\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eThere you can see the list of toll free numbers in the attached spreadsheet below.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/files/componentsource_countries_and_toll_free_numbers.xlsx\"\u003eDownload Toll Free Numbers XLS file\u003c/a\u003e\u003c/p\u003e","title":"ComponentSource"},{"content":"Codename One Designer Home Developers Designer Codename One Designer The Codename One Designer allows developers and visual artists to create mobile applications using drag and drop visual tools featuring live preview of changes within the tool and on devices!\nCodename One Designer includes the following features:\nGUI Builder - drag and drop GUI builder featuring layout managers to arrange components in locations intelligently Theme Creator - A visual environment that allows customizing themes for the Codename One platform Image management - Allows handling images for the Codename One platform including PNG/SVG as well as smart image formats for multi-DPI support Seamless Localization The Codename One Designer GUI builder environment integrates seamlessly with the IDE Plugin to provide seamless UI construction and backend logic. However, the Codename One Designer does not require coding and can be used independently by novices without experience in software development. Some effort is required in order to truly understand the capabilities/mindset of this tool.\n","permalink":"https://www.codenameone.com/designer/","summary":"\u003ch1 id=\"codename-one-designer\"\u003eCodename One Designer\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003eHome\u003c/li\u003e\n\u003cli\u003eDevelopers\u003c/li\u003e\n\u003cli\u003eDesigner\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"codename-one-designer-1\"\u003eCodename One Designer\u003c/h2\u003e\n\u003cp\u003eThe Codename One Designer allows developers and visual artists to create mobile applications using drag and drop visual tools featuring live preview of changes within the tool and on devices!\u003c/p\u003e\n\u003cp\u003eCodename One Designer includes the following features:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eGUI Builder - drag and drop GUI builder featuring layout managers to arrange components in locations intelligently\u003c/li\u003e\n\u003cli\u003eTheme Creator - A visual environment that allows customizing themes for the Codename One platform\u003c/li\u003e\n\u003cli\u003eImage management - Allows handling images for the Codename One platform including PNG/SVG as well as smart image formats for multi-DPI support\u003c/li\u003e\n\u003cli\u003eSeamless Localization\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe Codename One Designer GUI builder environment integrates seamlessly with the IDE Plugin to provide seamless UI construction and backend logic. However, the Codename One Designer does not require coding and can be used independently by novices without experience in software development. Some effort is required in order to truly understand the capabilities/mindset of this tool.\u003c/p\u003e","title":"Designer"},{"content":"Device Simulator Home Developers Device Simulator The Codename One Device Simulator allows us to run/debug applications for multiple devices. It allows sending device events and device manipulations such as rotation, physical input etc. It supports multiple device types using an open pluggable architecture and is entirely open source.\nDue to its unique architecture the device simulator allows developers to use all their existing development \u0026amp; debugging tools to check the quality and issues that arise while developing mobile applications.\nThe device simulator is very fast allowing developers to instantly check their applications without waiting for a slow emulator to \u0026ldquo;boot up\u0026rdquo;, while it is not a replacement for checking applications on a physical device it still provides very good parity with device functionality.\n","permalink":"https://www.codenameone.com/device-simulator/","summary":"\u003ch1 id=\"device-simulator\"\u003eDevice Simulator\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003eHome\u003c/li\u003e\n\u003cli\u003eDevelopers\u003c/li\u003e\n\u003cli\u003eDevice Simulator\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eThe Codename One Device Simulator allows us to run/debug applications for multiple devices. It allows sending device events and device manipulations such as rotation, physical input etc. It supports multiple device types using an open pluggable architecture and is entirely open source.\u003c/p\u003e\n\u003cp\u003eDue to its unique architecture the device simulator allows developers to use all their existing development \u0026amp; debugging tools to check the quality and issues that arise while developing mobile applications.\u003c/p\u003e","title":"Device Simulator"},{"content":"Discussion Forum You can also view the discussion group below through the Google Groups interface\nHome Discussion Forum Please try to ask questions on StackOverflow (and tag them as codenameone).\nIf that doesn\u0026rsquo;t work we still answer questions posted here but StackOverflow is more convenient/powerful.\n","permalink":"https://www.codenameone.com/discussion-forum-old/","summary":"\u003ch1 id=\"discussion-forum\"\u003eDiscussion Forum\u003c/h1\u003e\n\u003cp\u003eYou can also view the discussion group below through the \u003ca href=\"https://groups.google.com/group/codenameone-discussions?hl=en\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eGoogle Groups interface\u003c/a\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eDiscussion Forum\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003ePlease try to ask questions on \u003ca href=\"http://stackoverflow.com/tags/codenameone\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eStackOverflow\u003c/a\u003e (and tag them as codenameone).\u003cbr\u003e\nIf that doesn\u0026rsquo;t work we still answer questions posted here but \u003ca href=\"http://stackoverflow.com/tags/codenameone\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eStackOverflow\u003c/a\u003e is more convenient/powerful.\u003c/p\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003c!-- raw HTML omitted --\u003e","title":"Discussion Forum-old"},{"content":"Error Sending Email Home Error This page is reached when you tried to use a contact-us form and an error occurred on the server side. Please try again, your message was probably not received. If you got to this page we would appreciate a report of this via the issue tracker or the discussion forum.\n","permalink":"https://www.codenameone.com/error/","summary":"\u003ch1 id=\"error-sending-email\"\u003eError Sending Email\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eError\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eThis page is reached when you tried to use a contact-us form and an error occurred on the server side. Please try again, your message was probably not received. If you got to this page we would appreciate a report of this via the \u003ca href=\"https://github.com/codenameone/CodenameOne/issues\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eissue tracker\u003c/a\u003e or the \u003ca href=\"/discussion-forum.html\"\u003ediscussion forum\u003c/a\u003e.\u003c/p\u003e","title":"Error"},{"content":"Executive Overview Home Executive Overview Codename One is a one of a kind solution that allows you to rapidly get your products onto the market and easily maintain them on all platforms. It is a powerful open source solution that allows your development team to leverage their Java skills when targeting all platforms including iPhone/iPad.\nDevelopers can quickly deliver complex solutions making use of native device features and can access native code from their Java code to allow access to every device feature. Some of the end user feature highlights used by Codename One developers include:\n[\nGPS ](#)\n[\nPull To Refresh ](#)\n[\nSide swipe menus ](#)\n[\nSwipeable components, tabs and containers ](#)\n[\n100% fully themeable ](#)\n[\nNative web browser integration and Java-JavaScript bridge ](#)\n[\nMaps with layers and full customizability, native map integration with Google Maps ](#)\n[\nComplex and highly animated charting ](#)\n[\nTrue type fonts ](#)\n[\nCamera - capture video or photos \u0026amp; access the device gallery ](#)\n[\nPayment/purchase API works both with device in-app-payments and with credit card payments ](#)\n[\nVideo playback in app or full screen ](#)\n[\nSocial integration (facebook) including like button and share button ](#)\n[\nAnalytics (google analytics, seamless integration) + 3rd party analytics ](#)\n[\n3rd party extension libraries ](/cn1libs.html)\n[\nAds - both full screen and banner ad support ](#)\n[\nL10n - seamless localization of applications, update languages on the fly ](#)\n[\nPush notifications, email \u0026amp; SMS integration ](#)\n[\nXML, JSON, CSV parsing ](#)\n[\nContacts ](#)\n[\nDevice calendar ](#)\n[\nRSS feed reader ](#)\n[\nand much much more\u0026hellip; ](#)\nThe main benefit of Codename One development is in shortened development cycles, easy maintenance costs and developer training.\nBuild \u0026amp; Cloud Server Power Codename One has a unique build server architecture that allows building native apps for iPhone without requiring a Mac and for Windows Phone without requiring a Windows machine. All of the setup of complex tools and installations is alleviated thanks to the build server.\nThe Codename One Cloud services simplify the process of development further by making some functionality such as object cloud storage completely seamless and infinitely scalable. It allows push notification to work on all devices with a considerably simpler setup than any other option out there.\n","permalink":"https://www.codenameone.com/executive-overview/","summary":"\u003ch1 id=\"executive-overview\"\u003eExecutive Overview\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eExecutive Overview\u003c/li\u003e\n\u003c/ol\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003cp\u003eCodename One is a one of a kind solution that allows you to rapidly get your products onto the market and easily maintain them on all platforms. It is a powerful open source solution that allows your development team to leverage their Java skills when targeting all platforms including iPhone/iPad.\u003c/p\u003e\n\u003cp\u003eDevelopers can quickly deliver complex solutions making use of native device features and can access native code from their Java code to allow access to every device feature. Some of the end user feature highlights used by Codename One developers include:\u003c/p\u003e","title":"Executive Overview"},{"content":"Expression Language for JSON and XML Copied with permission from blog post by Eric Coolman, all rights reserved.\nHome Developers Expression Language for JSON and XML The com.codename1.processing.Result class provides a subset of XPath, but it is not limited to just XML documents, it can also work with JSON documents, and even with raw hashtables.\nExample 1 As an example, we\u0026rsquo;ll demonstrate how to process a response from the Google Reverse Geocoder API. The XML fragment below can be seen in full here, (or in JSON format here).\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34;?\u0026gt; \u0026lt;GeocodeResponse\u0026gt; \u0026lt;status\u0026gt;OK\u0026lt;/status\u0026gt; \u0026lt;result\u0026gt; \u0026lt;!-- (irrelevant content removed) --\u0026gt; \u0026lt;address_component\u0026gt; \u0026lt;long_name\u0026gt;London\u0026lt;/long_name\u0026gt; \u0026lt;short_name\u0026gt;London\u0026lt;/short_name\u0026gt; \u0026lt;type\u0026gt;locality\u0026lt;/type\u0026gt; \u0026lt;type\u0026gt;political\u0026lt;/type\u0026gt; \u0026lt;/address_component\u0026gt; \u0026lt;!-- (irrelevant content removed) --\u0026gt; \u0026lt;address_component\u0026gt; \u0026lt;long_name\u0026gt;Ontario\u0026lt;/long_name\u0026gt; \u0026lt;short_name\u0026gt;ON\u0026lt;/short_name\u0026gt; \u0026lt;type\u0026gt;administrative_area_level_1\u0026lt;/type\u0026gt; \u0026lt;type\u0026gt;political\u0026lt;/type\u0026gt; \u0026lt;/address_component\u0026gt; \u0026lt;address_component\u0026gt; \u0026lt;long_name\u0026gt;Canada\u0026lt;/long_name\u0026gt; \u0026lt;short_name\u0026gt;CA\u0026lt;/short_name\u0026gt; \u0026lt;type\u0026gt;country\u0026lt;/type\u0026gt; \u0026lt;type\u0026gt;political\u0026lt;/type\u0026gt; \u0026lt;/address_component\u0026gt; Above, the data highlighted in red is the values I want to retrieve, and the data highlighted in blue are the unique qualifiers that I will use to select that data.\nResult result = Result.fromContent(input, Result.XML); String country = result.getAsString(\u0026#34;/result/address_component[type=\u0026#39;country\u0026#39;]/long_name\u0026#34;); String region = result.getAsString(\u0026#34;/result/address_component[type=\u0026#39;administrative_area_level_1\u0026#39;]/long_name\u0026#34;); String city = result.getAsString(\u0026#34;/result/address_component[type=\u0026#39;locality\u0026#39;]/long_name\u0026#34;); If you are at all familiar with processing responses from webservices, you will notice that what would normally require several lines of code of selecting and testing nodes in regular java can now be done in a single line using the new path expressions.\nIn the code above, input can be any of:\nan InputStream directly from ConnectionRequest.readResponse() an XML or JSON document in the form of a string an XML DOM (Element) returned from XMLParser a JSON DOM (Hashtable) returned from JSONParser To use the expression processor when calling a webservice, you could use something like the following:\npublic class GoogleReverseGeocoderService extends ConnectionRequest { private final static String BASEURL = \u0026#34;http://maps.googleapis.com/maps/api/geocode/json?sensor=true\u0026#34;; private final static String PARAM_LATLNG=\u0026#34;latlng\u0026#34;; public GoogleReverseGeocoderService(double latitude, double longitude) { setUrl(BASEURL + \u0026#39;\u0026amp;\u0026#39; + PARAM_LATLNG + \u0026#39;=\u0026#39; + latitude + \u0026#39;,\u0026#39; + longitude); setContentType(\u0026#34;application/json\u0026#34;); addRequestHeader(\u0026#34;Accept\u0026#34;, \u0026#34;application/json\u0026#34;); setPost(false); } } Location l = Display.getInstance().getLocationManager().getLocation(); ConnectionRequest request = new GoogleReverseGeocoderService(l.getLatitude(), l.getLongitude()) { protected void readResponse(InputStream input) throws IOException { Result result = Result.fromContent(input, Result.JSON); // ... expressions here } }; NetworkManager.getInstance().addToQueue(request); It can also be instantiated with the result of one of the document parsers:\nJSONParser parser = new JSONParser(); Result result = Result.fromContent(parser.parse(new InputStreamReader(input))); The path processor is currently slightly more advanced for handling XML documents, but soon handling both JSON and XML will be exactly the same. For example, the XML processor currently handles global selections by using a double slash anywhere within the expression, for example:\n// get all address_component names anywhere in the document with a type of political String array[] = result.getAsStringArray(\u0026#34;//address_component[type=\u0026#39;political\u0026#39;]/long_name\u0026#34;); // get all types anywhere under the second result (dimension is 0-based) String array[] = result.getAsStringArray(\u0026#34;/result[1]//type\u0026#34;); NOTE: If you decide to try out the above code against Google’s JSON webservice, note that Google pluralizes each of the node names in that API (ie. results, address_components, and types) where they don’t in the XML services.\nExample 2 It also possible to do some more complex expressions. We’ll use the following XML fragment for the next batch of examples:\n\u0026lt;rankings type=\u0026#34;aus\u0026#34; gender=\u0026#34;male\u0026#34; date=\u0026#34;2011-12-31\u0026#34;\u0026gt; \u0026lt;player id=\u0026#34;1036\u0026#34; coretennisid=\u0026#34;6752\u0026#34; rank=\u0026#34;1\u0026#34; delta=\u0026#34;0\u0026#34; singlespoints=\u0026#34;485000\u0026#34; doublespoints=\u0026#34;675\u0026#34; deductedpoints=\u0026#34;0\u0026#34; totalpoints=\u0026#34;485675\u0026#34;\u0026gt; \u0026lt;firstname\u0026gt;Bernard\u0026lt;/firstname\u0026gt; \u0026lt;lastname\u0026gt;Tomic\u0026lt;/lastname\u0026gt; \u0026lt;town\u0026gt;SOUTHPORT\u0026lt;/town\u0026gt; \u0026lt;state\u0026gt;QLD\u0026lt;/state\u0026gt; \u0026lt;dob\u0026gt;1992-10-21\u0026lt;/dob\u0026gt; \u0026lt;/player\u0026gt; \u0026lt;player id=\u0026#34;2585\u0026#34; coretennisid=\u0026#34;1500\u0026#34; rank=\u0026#34;2\u0026#34; delta=\u0026#34;0\u0026#34; singlespoints=\u0026#34;313500\u0026#34; doublespoints=\u0026#34;12630\u0026#34; deductedpoints=\u0026#34;0\u0026#34; totalpoints=\u0026#34;326130\u0026#34;\u0026gt; \u0026lt;firstname\u0026gt;Mathew\u0026lt;/firstname\u0026gt; \u0026lt;lastname\u0026gt;Ebden\u0026lt;/lastname\u0026gt; \u0026lt;town\u0026gt;CHURCHLANDS\u0026lt;/town\u0026gt; \u0026lt;state\u0026gt;WA\u0026lt;/state\u0026gt; \u0026lt;dob\u0026gt;1987-11-26\u0026lt;/dob\u0026gt; \u0026lt;/player\u0026gt; \u0026lt;player id=\u0026#34;6457\u0026#34; coretennisid=\u0026#34;287\u0026#34; rank=\u0026#34;3\u0026#34; delta=\u0026#34;0\u0026#34; singlespoints=\u0026#34;132500\u0026#34; doublespoints=\u0026#34;1500\u0026#34; deductedpoints=\u0026#34;0\u0026#34; totalpoints=\u0026#34;134000\u0026#34;\u0026gt; \u0026lt;firstname\u0026gt;Lleyton\u0026lt;/firstname\u0026gt; \u0026lt;lastname\u0026gt;Hewitt\u0026lt;/lastname\u0026gt; \u0026lt;town\u0026gt;EXETER\u0026lt;/town\u0026gt; \u0026lt;state\u0026gt;SA\u0026lt;/state\u0026gt; \u0026lt;dob\u0026gt;1981-02-24\u0026lt;/dob\u0026gt; \u0026lt;/player\u0026gt; \u0026lt;!-- ... etc ... --\u0026gt; \u0026lt;/rankings\u0026gt; Above, if you want to select the IDs of all players that are ranked in the top 2, you can use an expression like:\nint top2[] = result.getAsIntegerArray(\u0026#34;//player[@rank \u0026lt; 3]/@id\u0026#34;); (Notice above that the expression is using an attribute for selecting both rank and id. In JSON documents, if you attempt to select an attribute, it will look for a child node under the attribute name you ask for).\nIf a document is ordered, you might want to select nodes by their position, for example:\nString first2[] = result.getAsStringArray(\u0026#34;//player[position() \u0026lt; 3]/firstname\u0026#34;); String secondLast = result.getAsString(//player[last() - 1]/firstName); It is also possible to select parent nodes, by using the ‘..’ expression. For example:\nint id = result.getAsInteger(\u0026#34;//lastname[text()=\u0026#39;Hewitt\u0026#39;]/../@id\u0026#34;); Above, we globally find a lastname element with a value of ‘Hewitt’, then grab the parent node of lastname which happens to be the player node, then grab the id attribute from the player node. Alternatively, you could get the same result from the following simpler statement:\nint id = result.getAsInteger(\u0026#34;//player[lastname=\u0026#39;Hewitt\u0026#39;]/@id\u0026#34;); It is also possible to nest expressions, for example:\nString id=result.getAsInteger(\u0026#34;//player[//address[country/isocode=\u0026#39;CA\u0026#39;]]/@id\u0026#34;); In the above example, if the player node had an address object, we’d be selecting all players from Canada. This is a simple example of a nested expression, but they can get much more complex, which will be required as the documents themselves get more complex. Moving on, to select a node based on the existence of an attribute:\nint id[] = result.getAsIntegerArray(\u0026#34;//player[@rank]/@id\u0026#34;); Above, we selected the IDs of all ranked players. Conversely, we can select the non-ranked players like this:\nint id[] = result.getAsIntegerArray(\u0026#34;//player[@rank=null]/@id\u0026#34;); (Logical not (!) operators currently are not implemented). You can also select by the existence of a child node.\nint id[] = result.getAsIntegerArray(\u0026#34;//player[middlename]/@id\u0026#34;); Above, we selected all players that have a middle name. Keep in mind that the Codename One path expression language is not a full implementation of XPath 1.0, but does already handle many of the most useful features of the specification. I hope you find it useful!\n","permalink":"https://www.codenameone.com/expression-language-for-json-and-xml/","summary":"\u003ch1 id=\"expression-language-for-json-and-xml\"\u003eExpression Language for JSON and XML\u003c/h1\u003e\n\u003cp\u003eCopied with permission from blog post by Eric Coolman, all rights reserved.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eHome\u003c/li\u003e\n\u003cli\u003eDevelopers\u003c/li\u003e\n\u003cli\u003eExpression Language for JSON and XML\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eThe com.codename1.processing.Result class provides a subset of XPath, but it is not limited to just XML documents, it can also work with JSON documents, and even with raw hashtables.\u003c/p\u003e\n\u003cp\u003eExample 1 As an example, we\u0026rsquo;ll demonstrate how to process a response from the Google Reverse Geocoder API. The XML fragment below can be seen in full here, (or in JSON format here).\u003c/p\u003e","title":"Expression Language for JSON and XML"},{"content":"Building Hello World Using Codename One A quick walkthru of the process of building a hello world app.\nHome Building Hello World Using Codename One ","permalink":"https://www.codenameone.com/hello-world/","summary":"\u003ch1 id=\"building-hello-world-using-codename-one\"\u003eBuilding Hello World Using Codename One\u003c/h1\u003e\n\u003cp\u003eA quick walkthru of the process of building a hello world app.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eBuilding Hello World Using Codename One\u003c/li\u003e\n\u003c/ol\u003e\n\u003c!-- raw HTML omitted --\u003e","title":"Hello World"},{"content":"Inneractive integration is no longer supported\n","permalink":"https://www.codenameone.com/inneractive/","summary":"\u003cp\u003eInneractive integration is no longer supported\u003c/p\u003e","title":"Inneractive"},{"content":"\nWhile its pretty easy to use native interfaces\nto write Android native code some things aren’t necessarily as obvious. E.g. if you want to integrate a 3rd party library, specifically one that includes native C JNI code this process is somewhat undocumented.\nIf you need to integrate such a library into your native calls you have the following 3 options:\nThe first option (and the easiest one) is to just place a Jar file in the native/android directory.\nThis will link your binary with the jar file. Just place the jar under the native/android and the build server will pick it up and will add it to the classpath.\nNotice that Android release apps are obfuscated by default which might cause issues with such libraries if they reference API’s that are unavailable on Android.\nYou can workaround this by adding a build hint to the proguard obfuscation code that blocs the obfuscation of the problematic classes using the build hint:\nandroid.proguardKeep=-keep class com.mypackage.ProblemClass { *; } The second option is to add an Android Library Project. Not all 3rd parties can be packaged as a simple jar, some 3rd parties needs to declare\nActivities add permissions, resources, assets, and/or even add native code (.so files). To link a Library project to your CN1 project open the Library\nproject in Eclipse or Android Studio and make sure the project builds, after the project was built successfully remove the bin directory from the\nproject and zip the whole project.\nRename the extension of the zip file to .andlib and place the andlib file under native/android directory. The build server will pick it up and will link it to the project.\nWe recently added a 3rd option :aar files. The aar file is a binary format from Google that represents an Android Library project. One of the problem with\nthe Android Library projects was the fact that it required the project sources which made it difficult for 3rd party vendors to publish libraries, so android\nintroduced the aar file which is a binary format that represents a Library project. To learn more about arr you can read\nthis.\nYou can link an aar file by placing it under the native/android and the build server will link it to the project.\nTo use any of the options above 3rd parties API’s you will need to create a\nNativeInterface and access\nthe libs API’s under the android implementation only section. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — June 29, 2015 at 10:49 am (permalink) Chidiebere Okwudire says:\nHi Chen,\nUnder option 1, can you elaborate what you mean by \u0026ldquo;API’s that are unavailable on Android\u0026rdquo; when talking about obfuscation?\nJohn Markh — January 18, 2017 at 7:13 pm (permalink) John Markh says:\nI would be great to have a code example to, for example, using Android PackageManager to retrieve a list of installed applications.\nShai Almog — January 19, 2017 at 6:15 am (permalink) Shai Almog says:\nThere are quite a few samples in the cn1libs section where pretty much all the libraries are open source.\nUsing this query on github I was able to find several results: https://github.com/search?q…\nShai Almog — January 19, 2017 at 6:17 am (permalink) Shai Almog says:\nHi,\nsorry for the late reply. Not sure why Chen didn’t answer back then…\nA JAR might import javax.swing and use it for some cases but might handle that case correctly by catching the class not found exception. However, this might collide with obfuscation that doesn’t like those sort of tricks…\nAmina Benzerga — July 13, 2017 at 3:31 pm (permalink) Amina Benzerga says:\nthe query does not work anymore, could you please give me a example? Thank you 🙂\nShai Almog — July 14, 2017 at 6:35 am (permalink) Shai Almog says:\nI see 11 results in the link above\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/integrating-android-3rd-party-libraries-jni/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/integrating-android-3rd-party-libraries-jni/binary.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/blog/integrating-android-3rd-party-libraries-jni/binary.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWhile its pretty easy to use \u003ca href=\"http://www.codenameone.com/how-do-i---access-native-device-functionality-invoke-native-interfaces.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003enative interfaces\u003c/a\u003e\u003cbr\u003e\nto write Android native code some things aren’t necessarily as obvious. E.g. if you want to integrate a 3rd party library, specifically one that includes native C JNI code this process is somewhat undocumented.\u003cbr\u003e\nIf you need to integrate such a library into your native calls you have the following 3 options:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003eThe first option (and the easiest one) is to just place a Jar file in the native/android directory.\u003cbr\u003e\nThis will link your binary with the jar file. Just place the jar under the native/android and the build server will pick it up and will add it to the classpath.\u003cbr\u003e\nNotice that Android release apps are obfuscated by default which might cause issues with such libraries if they reference API’s that are unavailable on Android.\u003cbr\u003e\nYou can workaround this by adding a build hint to the proguard obfuscation code that blocs the obfuscation of the problematic classes using the build hint:\u003c/p\u003e","title":"Integrating Android 3rd Party Libraries \u0026 JNI"},{"content":"Issues Home Issues You can follow the full set of issues in our issue tracker and submit additional issues from there.\n","permalink":"https://www.codenameone.com/issues/","summary":"\u003ch1 id=\"issues\"\u003eIssues\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eIssues\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eYou can follow the full set of issues in our \u003ca href=\"https://github.com/codenameone/CodenameOne/issues\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eissue tracker\u003c/a\u003e and submit additional issues from there.\u003c/p\u003e","title":"Issues"},{"content":"Introducing Codename One High level overview for Java developers.\nHome Introducing Codename One Special Notes For RIM/J2ME Developers If you have prior experience in LWUIT then Codename One would feel right at home, it is based on the original LWUIT source code and was created by the original creators of LWUIT!\nCodename One doesn\u0026rsquo;t provide access to the MIDlet class or any of the RIM/MIDP API\u0026rsquo;s, however all such API\u0026rsquo;s have functional equivalents in the Codename One API\u0026rsquo;s. Instead of using the MIDlet class you use the lifecycle class generated for you by the wizard and work from there.\nInstead of using HttpConnection and the Connector class you should use ConnectionRequest and the NetworkManager class.\nThere are no JSR\u0026rsquo;s in Codename One since everything is included, Codename One automatically detects the JSR\u0026rsquo;s you use and automatically adds the permissions/JSR\u0026rsquo;s as necessary.\nThere is no need to obfuscate since Codename One handles all of the complexities for you!\nWhen working in Codename One you can either use the Codename One GUI builder or handcode your application by using Forms and showing them as necessary.\n","permalink":"https://www.codenameone.com/java-developer-overview/","summary":"\u003ch1 id=\"introducing-codename-one\"\u003eIntroducing Codename One\u003c/h1\u003e\n\u003cp\u003eHigh level overview for Java developers.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eIntroducing Codename One\u003c/li\u003e\n\u003c/ol\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003ch4 id=\"special-notes-for-rimj2me-developers\"\u003eSpecial Notes For RIM/J2ME Developers\u003c/h4\u003e\n\u003cp\u003eIf you have prior experience in LWUIT then Codename One would feel right at home, it is based on the original LWUIT source code and was created by the original creators of LWUIT!\u003c/p\u003e\n\u003cp\u003eCodename One doesn\u0026rsquo;t provide access to the MIDlet class or any of the RIM/MIDP API\u0026rsquo;s, however all such API\u0026rsquo;s have functional equivalents in the Codename One API\u0026rsquo;s. Instead of using the MIDlet class you use the lifecycle class generated for you by the wizard and work from there.\u003cbr\u003e\nInstead of using HttpConnection and the Connector class you should use ConnectionRequest and the NetworkManager class.\u003c/p\u003e","title":"Java Developer Overview"},{"content":"Monetization Making money with Codename One\nHome Monetization You can make money with your apps using in-app-purchase, paid apps or ads. We support several ad networks specifically admob, flurry \u0026amp; vserv.\n","permalink":"https://www.codenameone.com/monetization/","summary":"\u003ch1 id=\"monetization\"\u003eMonetization\u003c/h1\u003e\n\u003cp\u003eMaking money with Codename One\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eMonetization\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eYou can make money with your apps using in-app-purchase, paid apps or ads. We support several ad networks specifically admob, flurry \u0026amp; vserv.\u003c/p\u003e","title":"Monetization"},{"content":"NetBeans Plugin Setup Instructions The instructions assume NetBeans 7.x or newer is installed correctly\nHome Download NetBeans Plugin Setup Instructions Select The Tools-\u0026gt;Plugins Menu Option \u0026amp; Select the \u0026ldquo;Available Plugins\u0026rdquo; Tab Select The CodenameOne Plugin and click install Follow The Wizard To Install The Plugin Continue to Next Step\n","permalink":"https://www.codenameone.com/netbeans-plugin-setup-instructions/","summary":"\u003ch1 id=\"netbeans-plugin-setup-instructions\"\u003eNetBeans Plugin Setup Instructions\u003c/h1\u003e\n\u003cp\u003eThe instructions assume NetBeans 7.x or newer is installed correctly\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/download.html\"\u003eDownload\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eNetBeans Plugin Setup Instructions\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"select-the-tools-plugins-menu-option--select-the-available-plugins-tab\"\u003eSelect The Tools-\u0026gt;Plugins Menu Option \u0026amp; Select the \u0026ldquo;Available Plugins\u0026rdquo; Tab\u003c/h2\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/uploads/netbeans-plugin-installation-1.png\"\u003e\u003cbr\u003e\n\u003cimg loading=\"lazy\" src=\"/uploads/netbeans-plugin-installation-2.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"select-the-codenameone-plugin-and-click-install\"\u003eSelect The CodenameOne Plugin and click install\u003c/h2\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/uploads/netbeans-plugin-installation-3.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"follow-the-wizard-to-install-the-plugin\"\u003eFollow The Wizard To Install The Plugin\u003c/h2\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/uploads/netbeans-plugin-installation-4.png\"\u003e\u003cbr\u003e\n\u003cimg loading=\"lazy\" src=\"/uploads/netbeans-plugin-installation-5.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/download.html#step2\"\u003eContinue to Next Step\u003c/a\u003e\u003c/p\u003e","title":"NetBeans Plugin Setup Instructions"},{"content":"Newsletter Signup for our low volume monthly newsletter email\nHome Newsletter Please use the signup form in the bottom of this website on the right side.\n","permalink":"https://www.codenameone.com/newsletter/","summary":"\u003ch1 id=\"newsletter\"\u003eNewsletter\u003c/h1\u003e\n\u003cp\u003eSignup for our low volume monthly newsletter email\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eNewsletter\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003ePlease use the signup form in the bottom of this website on the right side.\u003c/p\u003e","title":"Newsletter"},{"content":"Parsing: JSON, XML \u0026amp; CSV Quick tutorial covering the builtin parsers in Codename One\nHome Developers Parsing: JSON, XML \u0026amp; CSV Codename One has several builtin parsers for JSON, XML \u0026amp; CSV formats which you can use to parse data from the internet or data that is shipping with your product. E.g. use the CSV data to setup default values for your application.\nThe parsers are all geared towards simplicity and small size, they don\u0026rsquo;t validate and will fail in odd ways when faced with broken data.\nCSV is probably the easiest to use, the \u0026ldquo;Comma Separated Values\u0026rdquo; format is just a list of values separated by commas (or some other character) with newlines to indicate another row in the table. These usually map well to an Excel spreadsheet or database table.\nTo parse a CSV just use the CSVParser class as such:\nCSVParser parser = new CSVParser(); String[][] data = parser.read(stream); The data array will contain a two dimensional array of the CSV data. You can change the delimiter character by using the CSVParser constructor that accepts a character.\nThe JSON \u0026ldquo;Java Script Object Notation\u0026rdquo; format is popular on the web for passing values to/from webservices since it works so well with JavaScript. Parsing JSON is just as easy but has two different variations. You can use the JSONParser class to build a tree of the JSON data as such:\nJSONParser parser = new JSONParser(); Hashtable response = parser.parse(reader); The response is a Hashtable containing a nested hierarchy of Vectors, Strings and numbers to represent the content of the submitted JSON. To extract the data from a specific path just iterate the Hashtable keys and recurs into it. Notice that there is a webservices demo as part of the kitchen sink showing the returned data as a Tree structure.\nAn alternative approach is to use the static data parse() method of the JSONParser class and implement a callback parser e.g.:\nJSONParser.parse(reader, callback); Notice that a static version of the method is used! The callback object is an instance of the JSONParseCallback interface which includes multiple methods. These will be invoked by the parser to indicate internal parser states in a similar way to a traditional XML SAX event based parser.\nAdvanced readers might want to dig deeper into the processing language contributed by Eric Coolman which allows for xpath like expressions when parsing JSON \u0026amp; XML. Read about it in Eric\u0026rsquo;s blog.\nLast but not least is the XML parser, to use it just create an instance of the XMLParser class and invoke parse:\nXMLParser parser = new XMLParser(); Element elem = parser.parse(reader); The element contains children and attributes and represents a tag element within the XML document or even the document itself. You can iterate over the XML tree to extract the data from within the XML file.\n","permalink":"https://www.codenameone.com/parsing-json-xml-csv/","summary":"\u003ch1 id=\"parsing-json-xml--csv\"\u003eParsing: JSON, XML \u0026amp; CSV\u003c/h1\u003e\n\u003cp\u003eQuick tutorial covering the builtin parsers in Codename One\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eDevelopers\u003c/li\u003e\n\u003cli\u003eParsing: JSON, XML \u0026amp; CSV\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/uploads/parsing-json-xml--csv.png\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One has several builtin parsers for JSON, XML \u0026amp; CSV formats which you can use to parse data from the internet or data that is shipping with your product. E.g. use the CSV data to setup default values for your application.\u003c/p\u003e\n\u003cp\u003eThe parsers are all geared towards simplicity and small size, they don\u0026rsquo;t validate and will fail in odd ways when faced with broken data.\u003c/p\u003e","title":"Parsing: JSON, XML \u0026 CSV"},{"content":" Password Reset Home Build Server Password Reset Captcha Error! E-mail:\nPassword Reset\n","permalink":"https://www.codenameone.com/password-reset/","summary":"\u003c!-- raw HTML omitted --\u003e\n\u003ch1 id=\"password-reset\"\u003ePassword Reset\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/build-server.html\"\u003eBuild Server\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003ePassword Reset\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"captcha-error\"\u003eCaptcha Error!\u003c/h2\u003e\n\u003cp\u003eE-mail:\u003c/p\u003e\n\u003cp\u003ePassword Reset\u003c/p\u003e","title":"Password Reset"},{"content":"Performance \u0026amp; Network Monitors Quick introduction to builtin tools in the Codename One simulator\nHome Developers Performance \u0026amp; Network Monitors Using The Network Monitor While the Network Monitor Eric wrote about is a quite powerful tool, it does have some complexities and doesn\u0026rsquo;t display all the internal post operations for some cases. To solve that issue we created a network monitor tool which is integrated with the simulator and provides a one click tool to view network activity easily. The tool is really simple to use, just open it from the Simulator window and it will load with all instances of the simulator until its explicitly closed.\nYou can view all the details you would expect about every network request/response sent to/from your simulator by selecting from the list to your left.\nUsing The Performance Monitor NetBeans ships with a powerful profiler and there are quite a few excellent profilers that can give you allot of information about application execution. However, while a profiler will inform you of slow methods it will not inform you of slow components. Since the Codename One code is very generic you will see performance issues as slow EDT/Components within the profiler even if only one specific component is slow.\nThe performance monitor shows you the time (in nano seconds = billionth of a second) it takes to render a component and which components get painted the most. It also informs you about memory overhead (relevant also for GC activity) and occurrences that could be interesting to you when debugging performance issues. This tool is designed to help you investigate slow performance feel of an application by understanding what is actually happening within your application.\n","permalink":"https://www.codenameone.com/performance-network-monitors/","summary":"\u003ch1 id=\"performance--network-monitors\"\u003ePerformance \u0026amp; Network Monitors\u003c/h1\u003e\n\u003cp\u003eQuick introduction to builtin tools in the Codename One simulator\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eDevelopers\u003c/li\u003e\n\u003cli\u003ePerformance \u0026amp; Network Monitors\u003c/li\u003e\n\u003c/ol\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003ch2 id=\"using-the-network-monitor\"\u003eUsing The Network Monitor\u003c/h2\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/uploads/performance--network-monitor-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWhile the Network Monitor Eric wrote about is a quite powerful tool, it does have some complexities and doesn\u0026rsquo;t display all the internal post operations for some cases. To solve that issue we created a network monitor tool which is integrated with the simulator and provides a one click tool to view network activity easily. The tool is really simple to use, just open it from the Simulator window and it will load with all instances of the simulator until its explicitly closed.\u003c/p\u003e","title":"Performance \u0026 Network Monitors"},{"content":"Resellers Authorized Resellers \u0026amp; dealers\nHome Resellers We discontinued our reseller program and no longer work with 3rd party resellers or dealers.\n","permalink":"https://www.codenameone.com/resellers/","summary":"\u003ch1 id=\"resellers\"\u003eResellers\u003c/h1\u003e\n\u003cp\u003eAuthorized Resellers \u0026amp; dealers\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eResellers\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eWe discontinued our reseller program and no longer work with 3rd party resellers or dealers.\u003c/p\u003e","title":"Resellers"},{"content":"Signing Code signing and provisioning for the various platforms\nHome Developers Signing Important: this document is out of date! Please check out the developer guide section here\nWhile Codename One can simplify most of the grunt work in creating cross platform mobile applications, signing is not something that can be significantly simplified since it represents the developers individual identity in the markets. In this document we attempt to explain how to acquire certificates for the various markets and how to set them up to the build.\nThe good news is that this is usually a \u0026ldquo;one time deal\u0026rdquo; and once its done the work becomes easier (except for the case of iOS where a provisioning profile should be maintained).\niOS (iPhone/iPad) iOS signing has two distinct modes: App Store signing which is only valid for distribution via iTunes (you won\u0026rsquo;t be able to run the application yourself) and development mode.\nSigning for iOS can be accomplished using the Codename One certificate wizard, for the advanced cases where you already have a certificate or the wizard can\u0026rsquo;t answer your requirements you can follow the guide below.\nYou have two major files to keep track of: Certificate - your signature Provisioning Profile - details about your application and who is allowed to run it\nYou need two of each file (4 total files) one pair is for development and the other pair is for that precious moment when you are ready to upload to the App Store.\nWarning: this process only works on a Mac, the Adobe process linked here for Windows will produce an invalid certificate that will not WORK! Adobe wrote a pretty decent signing tutorial on this subject for Air which you can pretty much follow to get the files we need (p12 and mobileprovision). They also cover the certificate to p12 conversion process. Currently as far as we know, the best option for developers who don\u0026rsquo;t have access to a Mac is to use a service like http://www.macincloud.com/.\nThe first step you need to accomplish is signing up as a developer to Apple\u0026rsquo;s iOS development program, even for testing on a device this is required!\nThe Apple website will guide you through the process of applying for a certificate at the end of this process you should have a distribution and development certificate pair. After that point you can go to the iOS provisioning portal where there are plenty of videos and tutorials to guide you through the process. You need to create an application ID and register your development devices.\nYou then create a provisioning profile which comes in two flavors: distribution (for building the release version of your application) and development. The development provisioning profile needs to contain the devices on which you want to test.\nYou can then configure the 4 files in the IDE and start sending builds to the Codename One cloud.\nIf you have problems along the way or fail to install the resulting files check out the troubleshooting guide here.\nAndroid Its really easy to sign Android applications if you have the JDK installed. Find the keytool executable (it should be under the JDK\u0026rsquo;s bin directory) and execute the following command:\nkeytool -genkey -keystore Keystore.jks -storetype JKS -alias [alias_name] -keyalg RSA -keysize 2048 -validity 15000 -dname \u0026#34;CN=[full name], OU=[ou], O=[comp], L=[City], S=[State], C=[Country Code]\u0026#34; -storepass [password] -keypass [password] The elements in the brackets should be filled up based on this:\nAlias: [alias_name] (just use your name/company name without spaces) Full name: [full name] Organizational Unit: [ou] Company: [comp] City: [City] State: [State] CountryCode: [Country Code] Password: [password] (we expect both passwords to be identical) Executing the command will produce a Keystore.ks file in that directory which you need to keep since if you lose it you will no longer be able to upgrade your applications! Fill in the appropriate details in the project properties or in the CodenameOne section in the Netbeans preferences dialog.\nFor more details see http://developer.android.com/guide/publishing/app-signing.html\nBlackBerry You can now get signing keys for free from Blackberry by going here. After obtaining the certificates and installing them on your machine (you will need the Blackberry development environment for this). You will have two files: sigtool.db and sigtool.csk on your machine (within the JDE directory hierarchy). We need them and their associated password to perform the signed build for Blackberry application.\nJ2ME Currently signing J2ME application\u0026rsquo;s isn\u0026rsquo;t supported. You can use tools such as the Sprint WTK to sign the resulting jad/jar produced by Codename One.\n","permalink":"https://www.codenameone.com/signing/","summary":"\u003ch1 id=\"signing\"\u003eSigning\u003c/h1\u003e\n\u003cp\u003eCode signing and provisioning for the various platforms\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eHome\u003c/li\u003e\n\u003cli\u003eDevelopers\u003c/li\u003e\n\u003cli\u003eSigning\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eImportant:\u003c/strong\u003e this document is out of date! Please check out the developer guide section \u003ca href=\"https://www.codenameone.com/developer-guide\"\u003e\u003cstrong\u003ehere\u003c/strong\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eWhile Codename One can simplify most of the grunt work in creating cross platform mobile applications, signing is not something that can be significantly simplified since it represents the developers individual identity in the markets. In this document we attempt to explain how to acquire certificates for the various markets and how to set them up to the build.\u003c/p\u003e","title":"Signing"},{"content":"Submit App Submit your Codename One app to be included in the gallery\nHome Gallery Submit App This page is currently unavailable due to the website migration. We will restore this functionality as we move forward, thanks for your patience.\n","permalink":"https://www.codenameone.com/submit-app/","summary":"\u003ch1 id=\"submit-app\"\u003eSubmit App\u003c/h1\u003e\n\u003cp\u003eSubmit your Codename One app to be included in the gallery\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/gallery.html\"\u003eGallery\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eSubmit App\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eThis page is currently unavailable due to the website migration. We will restore this functionality as we move forward, thanks for your patience.\u003c/p\u003e","title":"Submit App"},{"content":"Swing Codename One introduction for Swing developers\nHome Developers Swing If you are familiar with Swing then Codename One will be instantly familiar to you! It was built by Swing fans and was deeply inspired by everything in Swing and everything missing in Swing. We took what we liked in Swing and added all the stuff that was missing. So Codename One is Swing redesigned for mobile with the advantage of \u0026ldquo;hindsight\u0026rdquo;!\nWhat is similar to Swing Lightweight architecture, you can just override paint EDT - Event Dispatch Thread List renderer, List model Layout managers Component-Container hierarchy Dialog\u0026rsquo;s block code execution Runtime PLAF/Theme switching What is different Built in transitions \u0026amp; animations InvokeAndBlock() - you can stop the EDT in its place when doing it right! (like foxtrot) Painters Styles Themes Standardized GUI builder Standardized resource file Seamless localization Integration with IO/Networking (e.g. progress indication with one line of code) Multi-DPI support 9-piece image borders Heavyweight/native integration Statically linked (no worries about \u0026ldquo;is this version installed\u0026rdquo;) No JComponent hack, Component-Container as originally intended To learn more about Codename One in general you can go to our developer section. Read below for information on how Codename One is similar/different from Swing below.\nGetting Started As a Swing developer you should have no trouble understanding typical handcoded Codename One apps, you have a Component/Container hierarchy and no \u0026ldquo;J\u0026rdquo; prefix e.g.:\nButton first = new Button(\u0026#34;First\u0026#34;); Button second = new Button(\u0026#34;Second\u0026#34;); Container cnt = new Container(new BoxLayout(BoxLayout.X_AXIS)); cnt.addComponent(first); cnt.addComponent(second); Just places the two buttons in a row one next to the other just like it would in Swing!\nSo what is different? A great deal of things but the first thing that is highly noticeable is theming and styles. You can style a component via the designer tool\u0026rsquo;s UI, every component accepts the style of the theme. So to make a text area look like a label (which allows for a multi-line label) all we have to do is:\nTextArea t = new TextArea(\u0026#34;Text area that looks like a label and breaks lines\u0026#34;); t.setEditable(false); t.setUIID(\u0026#34;Label\u0026#34;); Lifecycle \u0026amp; Mobile Development Programming for mobile is very different from programming to the desktop, there is no main method. Instead you have a \u0026ldquo;lifecycle\u0026rdquo; class that manages the application behavior and states as the phone/tablet switches states (think of this as a sort of Applet). Unlike Swing which focused on solving only the UI side of things, Codename One handles IO and all phone functionality as well and integrtes this together.\nLast but not least, because code is statically translated on the server you can\u0026rsquo;t do things such as adding libraries that weren\u0026rsquo;t compiled properly or might use unavailable functionality. You can use native code or work from sources as discussed here.\nForms \u0026amp; Dialogs Swing has top level components specifically Frame and Dialog (or more accurately JFrame/JDialog \u0026amp; JWindow), Codename One has Form. Since mobile devices don\u0026rsquo;t have Windows a Form always takes up the entire screen and there is always only one current form (which you can acquire via Display.getInstance().getCurrent()). A Dialog is really a special case Form (it subclasses the Form class) and is modal just like the Swing/AWT Dialog in the sense that it blocks the EDT thread until its disposed (with the dispose() method).\nCodename One has a ContentPane in much the same way and it is \u0026ldquo;hidden\u0026rdquo; so addComponent calls to form are effectively equivalent to form.getContentPane().addComponent(\u0026hellip;).\nIn some platforms the Form\u0026rsquo;s title is just a component in the NORTH part of the internal border layout (the layer above the content pane which is hidden from developers) however on some platforms (Android 4.x specifically) it is natively implemented by default. So while you can get the title area for the form it is ill advisable since that code will not be portable.\n","permalink":"https://www.codenameone.com/swing/","summary":"\u003ch1 id=\"swing\"\u003eSwing\u003c/h1\u003e\n\u003cp\u003eCodename One introduction for Swing developers\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://beta.codenameone.com/developing-in-codename-one.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDevelopers\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eSwing\u003c/li\u003e\n\u003c/ol\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003cp\u003eIf you are familiar with Swing then Codename One will be instantly familiar to you! It was built by Swing fans and was deeply inspired by everything in Swing and everything missing in Swing. We took what we liked in Swing and added all the stuff that was missing. So Codename One is Swing redesigned for mobile with the advantage of \u0026ldquo;hindsight\u0026rdquo;!\u003c/p\u003e","title":"Swing"},{"content":"Themeing Build a Codename One theme and leverage the native theme layer\nHome Developers Themeing When Creating a Codename One Theme The Default Uses The Platform Native Theme You can easily create a theme with any look you desire or you can \u0026ldquo;inherit\u0026rdquo; the platform native theme and start from that point. When adding a new theme you are given the option.\nAny Theme Can Be Made To Derive A Native Theme Codename One uses a theme constant called \u0026ldquo;includeNativeBool\u0026rdquo;, when that constant is set to true Codename One starts by loading the native theme first and then applying all the theme settings. This effectively means your theme \u0026ldquo;derives\u0026rdquo; the style of the native theme first, similar to the cascading effect of CSS.\nBy avoiding this flag you can create themes that look EXACTLY the same on all platforms.\nYou Can Simulate Different OS Platforms By Using The Native Theme Menu Developers can pick the platform of their liking and see how the theme will appear in that particular platform by selecting it and having the preview update on the fly.\nYou Can Easily Create Deep Customizations That Span Across All Themes In this case we just customized the UIID of a label and created a style for the new UIID. When deriving a native theme its important to check the various platform options to make sure that basic assumptions aren\u0026rsquo;t violated. E.g. labels might be transparent on one platform but opaque on others. Or labels might look good in a dialog in Android but look horrible in an iOS dialog (hint: use the DialogBody UIID for text content within a dialog).\nCodename One Allows You to Override a Resource For A Specific Platform A common case we run into when adapting for platform specific looks is that a specific resource should be different to match the platform conventions. The Override feature allows us to define resources that are specific to a given platform combination. Override resources take precedence over embedded resources thus allowing us to change the look or even behavior (when overriding a GUI builder element) for a specific platform/OS.\nTo Override Just Select The Platform Where Overriding Is Applicable Then click the green checkbox to define that this resource is specific to this platform. All resources added at this point will only apply to the given platform. If you change your mind and are no longer interested in a particular override just delete it in the override mode and it will no longer be overridden.\nIn This Case We Just Select a New Image Object Applicable To This Platform This is easily done by selecting the \u0026ldquo;\u0026hellip;\u0026rdquo; button. We can easily do the same in the GUI builder although this is a dangerous road to start following since it might end up with a great deal of fragmentation.\n","permalink":"https://www.codenameone.com/themeing/","summary":"\u003ch1 id=\"themeing\"\u003eThemeing\u003c/h1\u003e\n\u003cp\u003eBuild a Codename One theme and leverage the native theme layer\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eDevelopers\u003c/li\u003e\n\u003cli\u003eThemeing\u003c/li\u003e\n\u003c/ol\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003ch3 id=\"when-creating-a-codename-one-theme-the-default-uses-the-platform-native-theme\"\u003eWhen Creating a Codename One Theme The Default Uses The Platform Native Theme\u003c/h3\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/uploads/themeing-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eYou can easily create a theme with any look you desire or you can \u0026ldquo;inherit\u0026rdquo; the platform native theme and start from that point. When adding a new theme you are given the option.\u003c/p\u003e\n\u003ch3 id=\"any-theme-can-be-made-to-derive-a-native-theme\"\u003eAny Theme Can Be Made To Derive A Native Theme\u003c/h3\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/uploads/themeing-2.jpg\"\u003e\u003c/p\u003e","title":"Themeing"},{"content":"Codename One training is now organized as a structured, self-paced curriculum.\nStart with fundamentals, continue with deep technical topics, then complete the full-stack real-world track.\nAll courses include video lessons and companion slide material.\n","permalink":"https://www.codenameone.com/training/","summary":"\u003cp\u003eCodename One training is now organized as a structured, self-paced curriculum.\u003c/p\u003e\n\u003cp\u003eStart with fundamentals, continue with deep technical topics, then complete the full-stack real-world track.\u003c/p\u003e\n\u003cp\u003eAll courses include video lessons and companion slide material.\u003c/p\u003e","title":"Training"},{"content":"vserv.mobi Ads Home Monetization vserv.mobi The Vserv.mobi ad network provides a unique proposition where ads are displayed in full screen before during and sometimes after application execution. The biggest feature within vserv is its ability to seamlessly integrate with an existing application and provide value to the developers without changing a single line of application code.\nThe CodenameOne plugin only requires your Vserv ZoneId to integrate the SDK and enable Premium Ads on your App. To test your integration you can set the ZoneID to 8063 to enable test Ads.\nTo get started, register with Vserv.mobi here.\n","permalink":"https://www.codenameone.com/vserv-mobi-ads/","summary":"\u003ch1 id=\"vservmobi-ads\"\u003evserv.mobi Ads\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/monetization.html\"\u003eMonetization\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003evserv.mobi\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eThe Vserv.mobi ad network provides a unique proposition where ads are displayed in full screen before during and sometimes after application execution. The biggest feature within vserv is its ability to seamlessly integrate with an existing application and provide value to the developers without changing a single line of application code.\u003c/p\u003e\n\u003cp\u003eThe CodenameOne plugin only requires your Vserv ZoneId to integrate the SDK and enable Premium Ads on your App. To test your integration you can set the ZoneID to 8063 to enable test Ads.\u003c/p\u003e","title":"vserv.mobi Ads"},{"content":"Thanks for contacting us Your message was sent successfully\nHome Contact-Us Our sales/support team has been notified of this via email and will be in touch.\n","permalink":"https://www.codenameone.com/your-messages-was-sent/","summary":"\u003ch1 id=\"thanks-for-contacting-us\"\u003eThanks for contacting us\u003c/h1\u003e\n\u003cp\u003eYour message was sent successfully\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eContact-Us\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eOur sales/support team has been notified of this via email and will be in touch.\u003c/p\u003e","title":"Your Messages was sent"},{"content":"\nChen was working with a customer that needed some specific ad network support and decided to open source\nsome of that work. We now have integration with Flurry both for its ads and analytics\nsupport both of which are pretty cool and have some distinct advantages over the current Google equivalents.\nYou can download the project here, Chen wrote a\nvery detailed usage tutorial in the wiki page\nso there is no point in repeating it.\nOne of the big advantages here is that the flurry integration is a cn1lib project which makes it a great integration reference\ntutorial. We now have 2 ad networks integrated in that way which means that if you want to integrate another one you have a beaten path to follow. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — March 2, 2015 at 1:29 pm (permalink) Anonymous says:\nThis looks interesting!\nQuestions that come to mind:\n1. Is there any reason why the methods setUserID, setAge, and setGender are not exposed via FlurryManager? I see that they are defined in FlurryNative so I would expect that in the manager class as well.\n2. Are there any restrictions for using crash reporting (cf. the cn1 in-built feature that requires a Pro license)?\nCheers\nAnonymous — March 3, 2015 at 2:04 am (permalink) Anonymous says:\n1. Those are probably an omission due to lack of information from the customer.\n2. The crash reporting in flurry won’t give you any valuable information since Codename One apps are stripped by default so you will get giberrish. There are other complexities involved as well.\nWith the new VM we would like to upgrade the crash reporting capability to a level that would provide you with Java thread states which is far more useful than anything Flurry has for a Java developer. But that is still a way off.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/flurry-interstitial-ads-analytics/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/flurry-interstitial-ads-analytics/flurry_logo.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/blog/flurry-interstitial-ads-analytics/flurry_logo.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eChen was working with a customer that needed some specific ad network support and decided to open source\u003cbr\u003e\nsome of that work. We now have integration with Flurry both for its ads and \u003ca href=\"https://developer.yahoo.com/analytics/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eanalytics\u003c/a\u003e\u003cbr\u003e\nsupport both of which are pretty cool and have some distinct advantages over the current Google equivalents.\u003c/p\u003e\n\u003cp\u003eYou can download the project \u003ca href=\"https://code.google.com/p/flurry-codenameone/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere\u003c/a\u003e, Chen wrote a\u003cbr\u003e\nvery detailed \u003ca href=\"https://code.google.com/p/flurry-codenameone/wiki/Usage\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eusage tutorial in the wiki page\u003c/a\u003e\u003cbr\u003e\nso there is no point in repeating it.\u003c/p\u003e","title":"Flurry Interstitial Ads \u0026 Analytics"},{"content":"\nCodename One provides a rich set of drawing primitives in its Graphics class. It allows you to draw text, shapes, and images to the screen. The position where these elements will be rendered is determined based on a combination of Graphics state information (e.g. the current translation, and transform) and coordinates that are passed to the drawing method. Understanding how these coordinates are calculated can be tricky when you first begin using the API.\nTake, for example, the Graphics.drawRect(int x,int y, int width, int height) method. If you are coming to Codename One with fresh eyes, you can probably figure out that this method will draw a width x height rectangle at the coordinate (x,y). However you would probably also want to know exactly what the axes of the coordinate system are. E.g. where is (0,0), and in which directions do x and y get larger.\nThe Coordinate System The Codename One coordinate system follows the example of Swing (and many other – but not all- graphics libraries) and places the origin in the upper left corner of the screen. X-values grow to the right, and Y-values grow downward as illustrated below:\nTherefore the screen origin is at the top left corner of the screen. Given this information, consider the method call on the Graphics context g:\ng.drawRect(10,10, 100, 100); Where would this rectangle be drawn on the screen?\nIf you answered something something like \u0026ldquo;10 pixels from the top, and 10 pixels from the left of the screen\u0026rdquo;, you\nmight be right. It depends on whether the graphics has a translation or transform applied to it. If there is\ncurrently a translation of (20,20) (i.e. 20 pixels to the right, and 20 pixels down), then the rectangle would be rendered at (30, 30).\nYou can always find out the current translation of the graphics context using the Graphics.getTranslateX() and Graphics.getTranslateY() methods:\n// Find out the current translation int currX = g.getTranslateX(); int currY = g.getTranslateY(); // Reset the translation to zeroes g.translate(-currX, -currY); // Now we are working in absolute screen coordinates g.drawRect(10, 10, 100, 100); // This rectangle should now be drawn at the exact screen // coordinates (10,10). //Restore the translation g.translate(currX, currY); Note: This example glosses over issues such as clipping and transforms which may cause it to not work as you expect. E.g. When painting a component inside its paint() method, there is a clip applied to the context so that only the content you draw within the bounds of the component will be seen.\nIf, in addition, there is a transform applied that rotates the context 45 degrees clockwise, then the rectangle will be drawn at a 45 degree angle with its top left corner somewhere on the left edge of the screen.\nLuckily you usually don’t have to worry about the exact screen coordinates for the things you paint. Most of the time, you will only be concerned with relative coordinates.\nRelative Coordinates Usually, when you are drawing onto a Graphics context, you are doing so within the context of a Component’s paint() method (or one of its variants). In this case, you generally don’t care what the exact screen coordinates are of your drawing. You are only concerned with their relative location within the coordinate. You can leave the positioning (and even sizing) of the coordinate up to Codename One.\nTo demonstrate this, let’s create a simple component called Rectangle component, that simply draws a rectangle on the screen. We will use the component’s position and size to dictate the size of the rectangle to be drawn. And we will keep a 5 pixel padding between the edge of the component and the edge of our rectangle.\nclass RectangleComponent extends Component { public void paint(Graphics g){ g.setColor(0x0000ff); g.drawRect(getX()+5, getY()+5, getWidth()-10, getHeight()-10); } } The result is as follows:\nNote: The x and y coordinates that are passed to the drawRect(x,y,w,h) method are relative to the component’s parent’s origin — not the component itself .. its parent. This is why we the x position is getX()+5 and not just 5.\nTransforms and Rotations Unlike the Graphics drawXXX primitives, methods for setting transformations, including scale(x,y) and rotate(angle), are always applied in terms of screen coordinates. This can be confusing at first, because you may be unsure whether to provide a relative coordinate or an absolute coordinate for a given method.\nThe general rule is:\nAll coordinates passed to the drawXXX() and fillXXX() methods will be subject to the graphics context’s transform and translation settings. All coordinates passed to the context’s transformation settings are considered to be screen coordinates, and are not subject to current transform and translation settings. Let’s take our RectangleComponent as an example. Suppose we want to rotate the rectangle by 45 degrees, our first attempt might look something like:\nclass RectangleComponent extends Component { @Override protected Dimension calcPreferredSize() { return new Dimension(250,250); } public void paint(Graphics g) { g.setColor(0x0000ff); g.rotate((float) (Math.PI / 4.0)); g.drawRect(getX() + 5, getY() + 5, getWidth() - 10, getHeight() - 10); g.rotate(-(float) (Math.PI / 4.0)); } }(10,10, 100, 100); Tip: When performing rotations and transformations inside a paint() method, always remember to revert your transformations at the end of the method so that it doesn’t pollute the rendering pipeline for subsequent components.\nThe behaviour of this rotation will vary based on where the component is rendered on the screen. To demonstrate this, let’s try to place five of these components on a form inside a BorderLayout and see how it looks:\nclass MyForm extends Form { public MyForm() { super(\u0026quot;Rectangle Rotations\u0026quot;); for ( int i=0; i\u0026lt; 10; i++ ){ this.addComponent(new RectangleComponent()); } } } The result is as follows:\nThis may not be an intuitive outcome since we drew 10 rectangle components, be we only see a portion of one rectangle. The reason is that the rotate(angle) method uses the screen origin as the pivot point for the rotation. Components nearer to this pivot point will experience a less dramatic effect than components farther from it. In our case, the rotation has caused all rectangles except the first one to be rotated outside the bounds of their containing component - so they are being clipped. A more sensible solution for our component would be to place the rotation pivot point somewhere inside the component. That way all of the components would look the same. Some possibilities would be:\nTop Left Corner:\npublic void paint(Graphics g) { g.setColor(0x0000ff); g.rotate((float)(Math.PI/4.0), getAbsoluteX(), getAbsoluteY()); g.drawRect(getX() + 5, getY() + 5, getWidth() - 10, getHeight() - 10); g.rotate(-(float) (Math.PI / 4.0), getAbsoluteX(), getAbsoluteY()); } Center:\npublic void paint(Graphics g) { g.setColor(0x0000ff); g.rotate( (float)(Math.PI/4.0), getAbsoluteX()+getWidth()/2, getAbsoluteY()+getHeight()/2 ); g.drawRect(getX() + 5, getY() + 5, getWidth() - 10, getHeight() - 10); g.rotate( -(float)(Math.PI/4.0), getAbsoluteX()+getWidth()/2, getAbsoluteY()+getHeight()/2 ); } You could also use the Graphics.setTransform() class to apply rotations and other complex transformations (including 3D perspective transforms), but I’ll leave that for its own topic as it is a little bit more complex.\nEvent Coordinates While we’re on the topic of coordinates I would be remiss if I didn’t mention how coordinates are passed in events (e.g. touch events). We saw in part one of this series that you can listen for touch events on a component by overriding the pointerPressed(x,y) method. The coordinates received in this method will be absolute screen coordinates , so you may need to do some conversions on these coordinates before using them in your drawXXX() methods.\nRecall from part I, that our pointerPressed() method looked like:\npublic void pointerPressed(int x, int y) { addPoint(x-getParent().getAbsoluteX(), y-getParent().getAbsoluteY()); } In this case we translated these points so that they would be relative to the origin of the parent component. This is because the drawXXX() methods for this component take coordinates relative to the parent component.\nSummary Understanding the coordinate system is crucial for obtaining predictable graphics results. When you first begin, you may be unsure of whether a method expects coordinates to be relative to the current component, the parent component, or the screen origin. This post provided a few tips to help navigate the API. In the worst case, you can also just use a bit of trial and error.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-graphics-understanding-coordinates/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-graphics-understanding-coordinates/graphics.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/blog/codename-one-graphics-understanding-coordinates/graphics.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One provides a rich set of drawing primitives in its Graphics class. It allows you to draw text, shapes, and images to the screen. The position where these elements will be rendered is determined based on a combination of Graphics state information (e.g. the current translation, and transform) and coordinates that are passed to the drawing method. Understanding how these coordinates are calculated can be tricky when you first begin using the API.\u003c/p\u003e","title":"Codename One Graphics – Understanding Coordinates"},{"content":"\nOne of the pains in Codename One is the access to the demos, yes we have the downloadable demo bundle and the SVN but for a compete novice to Codename One this isn’t front and center. Chen decided to address that by embedding the latest versions of the demos both into the Eclipse and the NetBeans plugins, now when you create a new Codename One project you can also create a demo project and \u0026ldquo;just run it\u0026rdquo;. This allows you to quickly learn/debug our sample code which should help with the Codename One learning curve.\nChen and Steve also adapted the code built by Steve as part of the new graphics pipeline for perspective transforms\nand introduced a cool new flip transition that you can see in the video below, its really trivial to use just set form.setTransitionOutAnimation(new FlipTransition()); and that’s it. This is already in the current plugin and you can play with it right now!\nAs part of ongoing support for customers we also introduced improved location support on Android which uses the new Google Play API’s that include hybrid location. This means location should be more accurate and return a result faster, this will only be used if you integrate the Google Play Services support (which you can now rely on if you write Android native interfaces). To do that just add the build hint android.includeGPlayServices=true and this will be used seamlessly.\nThe infinite adapter API is sometimes\nless intuitive\nto developers who just want to work with a Container that makes a request for more components, to simplify this use case we added a new\nInfiniteContainer API\nwhich is based on the infinite adapter but provides a more intuitive (albeit less flexible) API. When using the infinite container API you need to subclass it\nand override the fetch components method to fetch additional entries.\nLast but not least we now have a simple weak hash map implementation that is very similar to the one in java util but under our own package at the moment.\nThis is a very useful class for caching temporary objects.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/easy-demos-flip-more/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/easy-demos-flip-more/flip.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/blog/easy-demos-flip-more/flip.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the pains in Codename One is the access to the demos, yes we have the downloadable demo bundle and the SVN but for a compete novice to Codename One this isn’t front and center. Chen decided to address that by embedding the latest versions of the demos both into the Eclipse and the NetBeans plugins, now when you create a new Codename One project you can also create a demo project and \u0026ldquo;just run it\u0026rdquo;. This allows you to quickly learn/debug our sample code which should help with the Codename One learning curve.\u003c/p\u003e","title":"Easy Demos, Flip \u0026 More"},{"content":"\nThis material is out of date by now. We recommend checking out the Codename One Academy.\nWe just released a new online course on Udemy called\n\u0026ldquo;Learn Mobile Programming By Example With Codename One\u0026rdquo;.\nBefore a single day went by we already have over 600 students enrolled which is pretty cool. This course is based on the videos we made for the\nDr. Sbaitso demo and the\nPropertyCross demo with some additional\nvideos thrown in to tie everything together and introduce Codename One.\nWe’d appreciate if you would help us spread the word about this and inform people about\nthis course.\nFYI in case you are new here and missed it, we also have another free course on Udemy covering the\nphoto share app.\nThat course is also available on youtube,\nwe also have the Codename One 101 course which is free for pro subscribers.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-free-course-learn-mobile-programming-by-example-with-codename-one/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-free-course-learn-mobile-programming-by-example-with-codename-one/course_phone_collage.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/blog/new-free-course-learn-mobile-programming-by-example-with-codename-one/course_phone_collage.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThis material is out of date by now. We recommend checking out the \u003ca href=\"/blog/launching-codename-one-academy.htmls\"\u003eCodename One Academy\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eWe just released a new online course on Udemy called\u003cbr\u003e\n\u0026ldquo;\u003ca href=\"https://www.udemy.com/learn-mobile-programming-by-example-with-codename-one/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eLearn Mobile Programming By Example With Codename One\u003c/a\u003e\u0026rdquo;.\u003cbr\u003e\nBefore a single day went by we already have over 600 students enrolled which is pretty cool. This course is based on the videos we made for the\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/blog/dr-sbaitso\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDr. Sbaitso\u003c/a\u003e demo and the\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/blog/propertycross-demo\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ePropertyCross demo\u003c/a\u003e with some additional\u003cbr\u003e\nvideos thrown in to tie everything together and introduce Codename One.\u003c/p\u003e","title":"New Free Course: Learn Mobile Programming By Example With Codename One"},{"content":"\nThe new property cross demo shows off the usage of webservices, JSON parsing, infinite scroll, URLImage and lots of other Codename One features. It uses a UK webservice that allows listing properties for sale in the UK.\nWe created a set of videos explaining how that demo works and the various features within it, check them out:\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/propertycross-demo/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/propertycross-demo/property_cross_thumb.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/blog/propertycross-demo/property_cross_thumb.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe new \u003ca href=\"https://code.google.com/p/codenameone/source/browse/trunk/Demos/PropertyCross/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eproperty cross demo\u003c/a\u003e shows off the usage of webservices, JSON parsing, infinite scroll, URLImage and lots of other Codename One features. It uses a UK webservice that allows listing properties for sale in the UK.\u003c/p\u003e\n\u003cp\u003eWe created a set of videos explaining how that demo works and the various features within it, check them out:\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"discussion\"\u003eDiscussion\u003c/h2\u003e\n\u003cp\u003e\u003cem\u003eJoin the conversation via GitHub Discussions.\u003c/em\u003e\u003c/p\u003e\n\u003cdiv class=\"cn1-giscus\"\u003e\n  \u003cscript\n    src=\"https://giscus.app/client.js\"\n    data-repo=\"codenameone/CodenameOne\"\n    data-repo-id=\"MDEwOlJlcG9zaXRvcnkzMjk3MzQ2Nw==\"\n    data-category=\"General\"\n    data-category-id=\"DIC_kwDOAfcim84B-_xx\"\n    data-mapping=\"pathname\"\n    data-strict=\"0\"\n    data-reactions-enabled=\"1\"\n    data-emit-metadata=\"0\"\n    data-input-position=\"top\"\n    data-theme=\"preferred_color_scheme\"\n    data-lang=\"en\"\n    data-loading=\"lazy\"\n    crossorigin=\"anonymous\"\n    async\u003e\n  \u003c/script\u003e\n\u003c/div\u003e","title":"PropertyCross Demo"},{"content":"\nIn my previous post, I created a static analog clock component. In this post, I will use Codename One’s animation API to update the clock every continually so that it will keep time correctly.\nHow Animation Works in Codename One From the Developer’s Guide:\nThe Codename One event dispatch thread has a special animation \u0026ldquo;pulse\u0026rdquo; allowing an animation to update its state and draw itself.\nEvery component in Codename One contains an animate() method that returns a boolean value, you can also implement the Animation interface in an arbitrary component to implement your own animation. In order to receive animation events you need to register yourself within the parent form, it is the responsibility of the parent for to call animate().\nIf the animate method returns true then the animation will be painted. It is important to deregister animations when they aren’t needed to conserve battery life. However, if you derive from a component, which has its own animation logic you might damage its animation behavior by deregistering it, so tread gently with the low level API’s.\u0026quot;\nDevice Support The Codename One animation API is a core feature of Codename One and it is supported on all platforms.\nAnimating the Clock In order to animate our clock so that it updates once per second, we only need to do two things:\nImplement the animate() method to indicate when the clock needs to be updated/re-drawn. Register the component with the form so that it will receive animation \u0026ldquo;pulses\u0026rdquo;. The animate() method in my AnalogClock class:\nDate currentTime = new Date(); long lastRenderedTime = 0; @Override public boolean animate() { if ( System.currentTimeMillis()/1000 != lastRenderedTime/1000){ currentTime.setTime(System.currentTimeMillis()); return true; } return false; } This method will be called on each \u0026ldquo;pulse\u0026rdquo; of the EDT. It checks the last time the clock was rendered and returns true only if the clock hasn’t been rendered in the current \u0026ldquo;time second\u0026rdquo; interval. Otherwise it returns false. This ensures that the clock will only be redrawn when the time changes.\nStarting and Stopping the Animation Animations can be started and stopped via the Form.registerAnimated(component) and Form.deregisterAnimated(component) methods. I have chosen to encapsulate these calls in start() and stop() methods in my component as follows:\npublic void start(){ this.getComponentForm().registerAnimated(this); } public void stop(){ this.getComponentForm().deregisterAnimated(this); } So the code to instantiate the clock, and start the animation would be something like:\nAnalogClock clock = new AnalogClock(); parent.addComponent(clock); clock.start(); The Final Result You can view the full source to this component here.\nYou may want to compare this to the static version from the\nprevious post to help identify the parts that are related to animation.\nHigher-Level Animations This tutorial dealt with the low-level animation API since the focus of this series is on low-level graphics. For most common use-cases, however, Codename One provides higher-level APIs that make it much easier to incorporate animations into your UI. Some examples of these APIs include:\nTransitions between forms. Animating components when their layouts are changed. Animating components when their hierarchy is changed. See the Developer’s Guide for more information about these APIs.\nMore Advanced Animations This tutorial only scratched the surface of what is possible with the Codename One animation API. In a future installment, we will explore the Motion class and see how it can be used to develop more complex animations and UI effects.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-graphics-low-level-animations/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-graphics-low-level-animations/clock_small.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/blog/codename-one-graphics-low-level-animations/clock_small.png\"\u003e\u003c/p\u003e\n\u003cp\u003eIn my previous post, I created a static analog clock component. In this post, I will use Codename One’s animation API to update the clock every continually so that it will keep time correctly.\u003c/p\u003e\n\u003ch4 id=\"how-animation-works-in-codename-one\"\u003eHow Animation Works in Codename One\u003c/h4\u003e\n\u003cp\u003eFrom the \u003ca href=\"http://www.codenameone.com/manual/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDeveloper’s Guide:\u003c/a\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eThe Codename One event dispatch thread has a special animation \u0026ldquo;pulse\u0026rdquo; allowing an animation to update its state and draw itself.\u003c/p\u003e\n\u003cp\u003eEvery component in Codename One contains an animate() method that returns a boolean value, you can also implement the Animation interface in an arbitrary component to implement your own animation. In order to receive animation events you need to register yourself within the parent form, it is the responsibility of the parent for to call animate().\u003c/p\u003e","title":"Codename One Graphics – Low Level Animations"},{"content":"\nNow that we are officially in the 64bit era of the iOS app store and our new VM is the default target it has gotten much stabler and helped us track issues that have been a part of Codename One since its inception. As part of improving the VM and fixing bugs we made a lot of changes to the VM including some core conceptual changes.\nOne of the core changes we made is removing the\nreference counting\n. In our original architecture we created a reference counting/GC hybrid which seemed like a good idea in theory. In practice reference counters are surprisingly slow (despite their inaccurate reputation) this is mainly due to multi-threaded access which makes the reference counting code problematic. We tried many approaches but eventually after many experiments we just removed the reference counter completely and saw a big speed boost. Since our GC is concurrent and never stops the world (it can stop the allocating thread if its out of RAM) you shouldn’t see any stalls assuming your thread yields properly.\nRemoving the reference counting logic reduced code size by 20% which helps speed up compilation and the overall app performance so this is a pretty significant leap. Doing that helped us leapfrog past the performance of the previous VM in most (although not all) benchmarks. With the new VM compilation time is often under 2 minutes as opposed to 5 minute compilation time on the old VM, this alone justifies the effort in migration.\nWe also came across several \u0026ldquo;gotchas\u0026rdquo; in the new VM that you should be aware of:\nDefault encoding – the old VM defaulted to US-ASCII as its encoding where the new VM defaults to UTF-8. UTF-8 is slightly slower so you might want to explicitly use US-ASCII.\nException performance – Exceptions in the new VM are really slow by comparison. This is mostly because we create the stack trace data before throwing which is somewhat inefficient. This shouldn’t be a big deal as long as you don’t use code that relies on exceptions for better performance e.g. looping an array until array out of bounds exception is thrown. This would be slower than just using a standard if.\nThread overhead – The new VM take up a bit more RAM per object but this is very noticeable in threads. Every thread can take half a megabyte in RAM to get started! This is pretty expensive but there is a reason. The new VM allocates stack objects for all the data within the thread stack frame. Furthermore, every object allocated within a thread is stored by the thread and only placed into the global pool when the thread and GC thread sync. This allows allocation code to be lock free and very fast as a result!\nOn a completely different note we now have a new Demo in SVN titled Property Cross that demonstrates property search in the UK. It allows you to search a UK database for houses for sale and then scroll an infinite list of properties. Mark your favorites and get additional details on them. We’ll try to post a detailed tutorial on it in the coming weeks.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — February 10, 2015 at 7:44 am (permalink) Anonymous says:\nI wish you can also improve the Windows port so that it can catchup to the Android and iOS.\nAnonymous — February 10, 2015 at 1:18 pm (permalink) Anonymous says:\nThat request isn’t echoed by our enterprise customers. Due to the major effort required in rewriting that port we will only undertake it if we have several enterprise seats demanding it.\nAnonymous — February 10, 2015 at 8:09 pm (permalink) Anonymous says:\nInteresting demo – some nice techniques to be aware of.\nAnonymous — February 11, 2015 at 7:48 am (permalink) Anonymous says:\nPity. So even if I advise my Co + manager to subscribe as an enterprise client it wouldn’t be enough as you need several…what a shame. Thanks for the feedback though.\nAnonymous — February 11, 2015 at 4:26 pm (permalink) Anonymous says:\nYou can be one company that has several enterprise developer seats but yes we do see the expense.\nTo do Windows Phone right we need to start over and that’s up to 12 man months of work so picking that up without concrete \u0026ldquo;real\u0026rdquo; paying customer demand that would eventually recoup the cost doesn’t make much sense. We already did 3 separate efforts on the port only to be thwarted by MS’s changing strategies and limited market penetration. Its hard to convince ourselves to go at it again when the platform is so uncertain.\nThere are also constant rumors about APK support in Windows Phone which will really make this redundant.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/status-of-the-new-vm-new-demo/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/status-of-the-new-vm-new-demo/status-of-the-new-vm-new-demo-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/status-of-the-new-vm-new-demo/status-of-the-new-vm-new-demo-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eNow that we are officially in the 64bit era of the iOS app store and our new VM is the default target it has gotten much stabler and helped us track issues that have been a part of Codename One since its inception. As part of improving the VM and fixing bugs we made a lot of changes to the VM including some core conceptual changes.\u003c/p\u003e\n\u003cp\u003eOne of the core changes we made is removing the\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/blog/beating-the-arc\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nreference counting\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n. In our original architecture we created a reference counting/GC hybrid which seemed like a good idea in theory. In practice reference counters are surprisingly slow (despite their inaccurate reputation) this is mainly due to multi-threaded access which makes the reference counting code problematic. We tried many approaches but eventually after many experiments we just removed the reference counter completely and saw a big speed boost. Since our GC is concurrent and never stops the world (it can stop the allocating thread if its out of RAM) you shouldn’t see any stalls assuming your thread yields properly.\u003c/p\u003e","title":"Status Of The New VM \u0026 New Demo"},{"content":"\nThis post was written by\nSteve Hannah\n, one of the newest additions to the Codename One team and a long time community contributor.\nThe upcoming update to Codename One will include a new package (com.codename1.charts) for rendering charts in your applications. This includes models and renderers for many common classes of charts including many flavours of bar charts, line charts, scatter charts, and pie charts.\n**\nGoals\n**\nFor the charts package, we wanted to enable Codename One developers to add charts and visualizations to their apps without having to include external libraries or embedding web views. We also wanted to harness the new features in the graphics pipeline to maximize performance.\nDifferences from CN1aChartEngine\nThis package is based on the existing\nCN1aChartEngine library\n, but has been refactored substantially to reduce its size, improve its performance, and simplify its API. If you have used the existing CN1aChartEngine library, much of the API (e.g. models and renderers) will be familiar. The key differences are:\n**\nAPI\n**\n. It includes ChartComponent, a first-class Codename One Component that can be included anywhere inside your forms. CN1aChartEngine used a number of Android-like abstractions (e.g. View, Intent, and Activity) to simplify the porting process from the original Android library. While this indeed made it easier to port, it made the API a little bit confusing for Codename One development.\n**\nPerformance\n**\n. It uses the built-in Codename One graphics pipeline for rendering all graphics. CN1aChartEngine used the CN1Pisces library for rendering graphics, which is an order of magnitude slower than the built-in pipeline. This was for historical reasons. When CN1aChartEngine was first developed, the built-in pipeline was missing some features necessary to implement charts.\n** Note ** _\nActually, just before refactoring CN1aChartEngine to produce the charts package, I ported it over to use the built-in pipeline. If you are already using CN1aChartEngine in your app, and want to benefit from the improved performance without having to change your code, you can update to\nthat version\n.\n_\n**\nDevice Support\n**\nSince the charts package makes use of 2D transformations and shapes, it requires some of the new graphics features that are not yet available on all platforms. Currently the following platforms are supported:\nSimulator\nAndroid\niOS\nIf you require support for other platforms, you may want to use the\nCN1aChartEngine\nlibrary instead.\n**\nFeatures\n**\nBuilt-in support for many common types of charts including bar charts, line charts, stacked charts, scatter charts, pie charts and more.\nPinch Zoom – The ChartComponent class includes optional pinch zoom support.\nPanning Support – The ChartComponent class includes optional support for panning.\n**\nChart Types\n**\nThe com.codename1.charts package includes models and renderers for many different types of charts. It is also extensible so that you can add your own chart types if required. The following screen shots demonstrate a small sampling of the types of charts that can be created.\n** Note ** _\nThe above screenshots were taken from the ChartsDemo app. You can start playing with this app now by checking it out from our subversion repository.\n_\n**\nHow to Create A Chart\n**\nAdding a chart to your app involves four steps:\n**\nBuild the model\n**\n. You can construct a model (aka data set) for the chart using one of the existing model classes in the com.codename1.charts.models package. Essentially, this is just where you add the data that you want to display.\n**\nSet up a renderer\n**\n. You can create a renderer for your chart using one of the existing renderer classes in the com.codename1.charts.renderers package. The renderer allows you to specify how the chart should look. E.g. the colors, fonts, styles, to use.\n**\nCreate the Chart View\n**\n. Use one of the existing view classes in the com.codename1.charts.views package.\n**\nCreate a ChartComponent\n**\n. In order to add your chart to the UI, you need to wrap it in a ChartComponent object.\nYou can check out the\nChartsDemo\napp for specific examples, but here is a high level view of some code that creates a Pie Chart.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — February 5, 2015 at 2:46 am (permalink) Anonymous says:\nthis is a great addition to the product. Are the charts clickable .. can i drill down? like if i want to drill down into a particular pie in the pie chart and render some other detail, can i do so ?\nAnonymous — February 6, 2015 at 2:07 am (permalink) Anonymous says:\nThe charts are clickable just like any component in Codename One. You can enable pinch zoom and panning by enabling flags on the component. In addition, you can derive the component and override the seriesPressed() and/or seriesReleased() methods to handle clicks on particular series in the chart. These methods receive events that tell you what part of the series was interacted with.\nIf you wanted to create interactivity, you could use these events to modify the data model, then repaint the component. You could also use Codename One’s animation plumbing to do these things in a smooth transition.\nI’ll be writing more about this in future posts. If there are particular things you’d like to see in the posts, please let me know and I’ll try to incorporate them.\nSteve\nAnonymous — February 6, 2015 at 6:02 pm (permalink) Anonymous says:\nCan we use these library file in Intellij also ? Is so, do I have to just put them in the lib folder of the project ?\nAnonymous — February 6, 2015 at 6:13 pm (permalink) Anonymous says:\nThe new charts API is part of the codename one core. No need for libraries. The old chart engine libraries will work in IntelliJ also. Yes just place the cn1lib files in your lib directory and select \u0026ldquo;Refresh libs\u0026rdquo;.\nmanezi — May 18, 2015 at 9:56 am (permalink) manezi says:\nThanks for the great work. Is additional platform support likely to be offered any time soon for com.codename1.charts? Or are platform limitations preventing this?\nShai Almog — May 18, 2015 at 3:28 pm (permalink) Shai Almog says:\nIt also works on the JavaScript port now.\nWhich platforms are you interested in?\nIt works on all of our supported platforms except for J2ME, RIM and Windows Phone. J2ME \u0026amp; RIM are pretty outdated and irrelevant by now. We will probably rewrite the Windows work on top of their upcoming Android support at which point we we will have full support for charts.\nSana Maghraoui — December 24, 2016 at 9:32 am (permalink) Sana Maghraoui says:\nhello! I’m trying to do run this charts but I’m not able can u help me please?\nShai Almog — December 25, 2016 at 8:14 am (permalink) Shai Almog says:\nHi,\nwhat isn’t working?\nSana Maghraoui — December 25, 2016 at 5:15 pm (permalink) Sana Maghraoui says:\nhello!\nI downloaded the project chart_master but it’s unrunnable\nShai Almog — December 26, 2016 at 5:06 am (permalink) Shai Almog says:\nIt’s a bit hard to setup a new project for first timers. That’s why we have this demo in the new menu of intellij and NetBeans. Just create a new demo project and it should be one of the options.\nSana Maghraoui — December 26, 2016 at 8:37 am (permalink) Sana Maghraoui says:\nhi!\nIt’s okay I made it but It’s static can I make it dynamic?\nSana Maghraoui — December 26, 2016 at 1:57 pm (permalink) Sana Maghraoui says:\nhello I need to make dynamic charts can you help me?\nShai Almog — December 27, 2016 at 6:24 am (permalink) Shai Almog says:\nThere is a dynamic chart in the demo as well as in the kitchen sink demo (under sales)\nSana Maghraoui — December 27, 2016 at 9:53 am (permalink) Sana Maghraoui says:\nI mean with dynamic that get information from the DataBase and display it\nSana Maghraoui — December 27, 2016 at 10:02 am (permalink) Sana Maghraoui says:\n*please help me I need to get information from the database and to display it\nShai Almog — December 28, 2016 at 1:23 pm (permalink) Shai Almog says:\nKitchen sink gets information from a UI table, getting it from a database or a UI table is similar. External source that refreshes the table.\nSana Maghraoui — December 28, 2016 at 10:04 pm (permalink) Sana Maghraoui says:\nthank you for your replies but I can’t adapt the project to the one I working with I need help .I’m not finding the Myapplication .java in the kitchenSkin in the Demo so how can I do?thank you for your help\nShai Almog — December 29, 2016 at 5:51 am (permalink) Shai Almog says:\nKitchen sink has files that are named differently (pretty much all apps/demos do), this specific demo has that code in the SalesDemo.\nJared Ruplinger — October 9, 2017 at 3:05 pm (permalink) Jared Ruplinger says:\nFor those who are having trouble following the examples in the demo linked from this post, you might want to check out the \u0026ldquo;newer\u0026rdquo; demo from the post at https://www.codenameone.com…\nIt is a smidge simpler. That aside, however, there are a lot of moving pieces to the charts functionality and it would sure be nice to have some more thorough documentation.\nShai Almog — October 10, 2017 at 4:40 am (permalink) Shai Almog says:\nYes, I agree. We need simpler charts. We added some simpler code into the kitchen sink under the sales demo. It tries to demonstrate a more \u0026ldquo;real world\u0026rdquo; use case.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-charts/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-charts/codename-one-charts-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/codename-one-charts/codename-one-charts-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThis post was written by\u003cbr\u003e\n\u003ca href=\"http://sjhannah.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nSteve Hannah\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, one of the newest additions to the Codename One team and a long time community contributor.\u003c/p\u003e\n\u003cp\u003eThe upcoming update to Codename One will include a new package (\u003ccode\u003ecom.codename1.charts\u003c/code\u003e) for rendering charts in your applications. This includes models and renderers for many common classes of charts including many flavours of bar charts, line charts, scatter charts, and pie charts.\u003c/p\u003e","title":"Codename One Charts"},{"content":"\nI recently flew to\ndev day at Riga\n, I was quite ill before the trip so it was pretty difficult and that’s the main reason I didn’t make a trip report like I normally do. However, the conference and the people running it did seem like a whole lot of fun that unfortunately I was in no shape to enjoy.\nI did prepare a demo/presentation for the trip though and since I gave my talk under the influence of medication I think its wise to post a tutorial to the demo I did here both for those who were in attendance and for the rest of the Codename One community.\nThe demo I made is a homage to an old Soundblaster demo, its generally a chat app between you and an AI that I designed to look like iMessage. It uses text to speech (with native interfaces) to vocalize the responses of the \u0026ldquo;AI\u0026rdquo;. Notice the AI is really trivial and I don’t cover it in the video tutorials below.\nYou can see the full source code of the demo in our\ndemos directory here\n. Here are videos explaining pretty much the whole demo.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/dr-sbaitso/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/dr-sbaitso/dr-sbaitso-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/dr-sbaitso/dr-sbaitso-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI recently flew to\u003cbr\u003e\n\u003ca href=\"http://rigadevday.lv/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\ndev day at Riga\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, I was quite ill before the trip so it was pretty difficult and that’s the main reason I didn’t make a trip report like I normally do. However, the conference and the people running it did seem like a whole lot of fun that unfortunately I was in no shape to enjoy.\u003c/p\u003e\n\u003cp\u003eI did prepare a demo/presentation for the trip though and since I gave my talk under the influence of medication I think its wise to post a tutorial to the demo I did here both for those who were in attendance and for the rest of the Codename One community.\u003c/p\u003e","title":"Dr. Sbaitso"},{"content":"\nThis post was written by\nSteve Hannah\n, one of the newest additions to the Codename One team and a long time community contributor.\nThe new Codename One graphics pipeline includes support for advanced 2D and 3D transformations.\nLast time\nI talked about some of the new features in Codename One’s graphics. Then I presented an example app to demonstrate the use of the new shapes API. In this instalment, I will focus on some of the new graphics transformation features.\n**\nBackground\n**\nThe Graphics class has included limited support for 2D transformations for some time now including scaling, rotation, and translation:\nscale(x,y) : Scales drawing operations by a factor in each direction.\ntranslate(x,y) : Translates drawing operations by an offset in each direction.\nrotate(angle) : Rotates about the origin.\nrotate(angle, px, py) : Rotates about a pivot point.\nNote: scale() and rotate() methods are only available on platforms that support Affine transforms. Currently only Android, iOS and the simulator (JavaSE) support these methods.\n**\nDevice Support\n**\nYou can check if a particular Graphics context supports rotation and scaling using the isAffineSupported() method.\ne.g.\npublic void paint(Graphics g) { if (g.isAffineSupported()) { // Do something that requires rotation and scaling } else { // Fallback behaviour here } } **\nExample:\n**\nDrawing an Analog Clock\nIn the following sections, I will implement an analog clock component. This will demonstrate three key concepts in Codename One’s graphics:\nUsing the GeneralPath class for drawing arbitrary shapes.\nUsing Graphics.translate() to translate our drawing position by an offset.\nUsing Graphics.rotate() to rotate our drawing position.\nThere are three separate things that need to be drawn in a clock:\n**\nThe tick marks\n**\n. E.g. most clocks will have a tick mark for each second, larger tick marks for each hour, and sometimes even larger tick marks for each quarter hour.\n**\nThe numbers\n**\n. We will draw the clock numbers (1 through 12) in the appropriate positions.\n**\nThe hands\n**\n. We will draw the clock hands to point at the appropriate points to display the current time.\n**\nThe AnalogClock Component\n**\nOur clock will extend the Component class, and override the paintBackground() method to draw the clock as follows:\n**\nSetting up the Parameters\n**\nBefore we actually draw anything, let’s take a moment to figure out what values we need to know in order to draw an effective clock. Minimally, we need two values:\nThe center point of the clock.\nThe radius of the clock.\nIn addition, I am adding the following parameters to to help customize how the clock is rendered:\n**\nThe padding\n**\n(i.e. the space between the edge of the component and the edge of the clock circle.\n**\nThe tick lengths\n**\n. I will be using 3 different lengths of tick marks on this clock. The longest ticks will be displayed at quarter points (i.e. 12, 3, 6, and 9). Slightly shorter ticks will be displayed at the five-minute marks (i.e. where the numbers appear), and the remaining marks (corresponding with seconds) will be quite short.\n**\nDrawing the Tick Marks\n**\nFor the tick marks, we will use a single GeneralPath object, making use of the moveTo() and lineTo() methods to draw each individual tick.\n**\nTip:\n**\nThis example uses a little bit of trigonometry to calculate the (x,y) coordinates of the tick marks based on the angle and the radius. If math isn’t your thing, don’t worry. This example just makes use of the identities: x=rcosθ and y=rsinθ.\nFor more information about drawing shapes using GeneralPath, I recommend you check out my\nprevious post on Codename One Graphics\n.\nAt this point our clock should include a series of tick marks orbiting a blank center as shown below:\n**\nDrawing the Numbers\n**\nI have seen clocks before that don’t include any actual numbers, but these are far too advanced for my rudimentary clock-reading skills. I want my clock to have numbers on it. Nothing fancy. Just \u0026ldquo;1\u0026rdquo; through \u0026ldquo;12\u0026rdquo; labelling the appropriate tick marks.\nThe Graphics.drawString(str, x, y) method allows you to draw text at any point of a component. The tricky part here is calculating the correct x and y values for each string so that the number appears in the correct location.\nFor the purposes of this tutorial, I’m going to use the following strategy. For each number (1 through 12):\nUse the Graphics.translate(x,y) method to apply a translation from the clock’s center point to the point where the number should appear.\nDraw number (using drawString()) at the clock’s center. It should be rendered at the correct point due to our translation.\nInvert the translation performed in step 1.\n**\nNote:\n**\nThis example is, admittedly, a little contrived to allow for a demonstration of the Graphics.translate() method. We could have just as easily passed the exact location of the number to drawString() rather than draw at the clock center and translate to the correct location.\nNow, we should have a clock with tick marks and numbers as shown below:\n**\nDrawing the Hands\n**\nOur clock will include three hands: Hour, Minute, and Second. I will use a separate GeneralPath object for each hand. For the positioning/angle of each, I will employ the following strategy:\nDraw the hand at the clock center pointing toward 12 (straight up).\nTranslate the hand slightly down so that it overlaps the center.\nRotate the hand at the appropriate angle for the current time, using the clock center as a pivot point.\n**\nDrawing the Second Hand\n**\nFor the \u0026ldquo;second\u0026rdquo; hand, I will just use a simple line from the clock center to the inside edge of the medium tick mark at the 12 o’clock position.\nGeneralPath secondHand = new GeneralPath(); secondHand.moveTo((float)cX, (float)cY); secondHand.lineTo((float)cX, (float)(cY-(r-medTickLen))); And I will translate it down slightly so that it overlaps the center. This translation will be performed on the GeneralPath object directly rather than through the Graphics context:\nShape translatedSecondHand = secondHand.createTransformedShape(Transform.makeTranslation(0f, 5));\n**\nRotating the Second Hand\n**\nThe rotation of the second hand will be performed in the Graphics context via the rotate(angle, px, py) method. This requires us to calculate the angle. The px and py arguments constitute the pivot point of the rotation, which, in our case will be the clock center.\n**\nWarning:\n**\nThe rotation pivot point is expected to be in absolute screen coordinates rather than relative coordinates of the component. Therefore we need to get the absolute clock center position in order to perform the rotation.\n**\nNote:\n**\nRemember to call resetAffine() after you’re done with the rotation, or you will see some unexpected results on your form.\n**\nDrawing the Minute And Hour Hands\n**\nThe mechanism for drawing the hour and minute hands is largely the same as for the minute hand. There are a couple of added complexities though:\nWe’ll make these hands trapezoidal, and almost triangular rather than just using a simple line. Therefore the GeneralPath construction will be slightly more complex.\nCalculation of the angles will be slightly more complex because they need to take into account multiple parameters. E.g. The hour hand angle is informed by both the hour of the day and the minute of the hour.\nThe remaining drawing code is as follows:\n**\nThe Final Result\n**\nAt this point, we have a complete clock as shown below:\nYou can view the full source to this component\nhere\n.\n**\nAnimating the Clock\n**\nThe current clock component is cool, but it is static. It just displays the time at the point the clock was created. Next time we’ll improve on this by adding animation support so that the clock will \u0026ldquo;tick\u0026rdquo; and keep the correct time – just like a real clock.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — January 29, 2015 at 3:48 am (permalink) Anonymous says:\nThat’s very cool Steve. Semi off-topic, but you might be interested in this JavaFX clock: http://blog.crisp.se/2012/0… – it uses JavaFX bound properties in a very elegant fashion.\nAnonymous — January 29, 2015 at 4:07 am (permalink) Anonymous says:\nAs an FYI I created the original properties project that inspired JavaFX properties: https://java.net/projects/b…\nThis predated my LWUIT work but we didn’t take it into LWUIT due to size concerns… Adding \u0026ldquo;proper\u0026rdquo; properties to Codename One is something that has been on my wishlist for quite some time, but to do this properly I would want the VM to support this internally so properties would have zero overhead compared to fields. That would take some effort…\nAnonymous — January 29, 2015 at 4:23 am (permalink) Anonymous says:\nI can blame you ! LOL. I have to admit having used Swing, LWUIT etc for a very long time, then coming to FX with it’s extensive use of binding was quite a shock and hard on my tired old brain – but then when see code like the clock I mentioned, where the binding makes it \u0026ldquo;just work\u0026rdquo; with almost no code, you can really see the power of the concept.\nAnonymous — January 31, 2015 at 7:11 am (permalink) Anonymous says:\nGreat stuff!! Thanks for this. We need more examples that push CN1 to its limits!\nIn case some one struggles with showing the clock.. just set the form layout to GridLayout like this:\nForm f = new Form(\u0026quot;\u0026quot;);\nf.setLayout(new GridLayout(1, 1));\nAnalogClock analogClock = new AnalogClock();\nf.addComponent(analogClock);\nf.repaint();\nf.show;\nJosé Helana — December 7, 2015 at 8:21 am (permalink) José Helana says:\nhow do I get the clock to have the time automatically\nShai Almog — December 8, 2015 at 4:47 am (permalink) Shai Almog says:\nYou can use the java.util.Calendar class to get the current time and set it to the hands.\nSee the last section of this tutorial with animating the clock.\nFranck Marchand — March 3, 2016 at 10:17 am (permalink) Franck Marchand says:\nThanks for this example.\nBut do you know why It doesn’t work If I add AnalogClock in Container sets with BoxLayout ?\nShai Almog — March 4, 2016 at 3:42 am (permalink) Shai Almog says:\nDid you override calcPreferredSize() to give the clock a size?\nFranck Marchand — March 4, 2016 at 1:13 pm (permalink) Franck Marchand says:\nNo, juste:\ntb.addCommandToSideMenu(new Command(\u0026ldquo;Clock2\u0026rdquo;, theme.getImage(\u0026ldquo;teams_icn_badgeage_48x48.png\u0026rdquo;)) {\n@Override\npublic void actionPerformed(ActionEvent evt) {\nForm fm = new Form(new BoxLayout(BoxLayout.Y_AXIS));\nTmAnalogClock clock = new TmAnalogClock();\nfm.addComponent(clock);\nfm.show;\n}\n});\nShai Almog — March 5, 2016 at 4:13 am (permalink) Shai Almog says:\nYou need to override the calcPreferredSize() to give the clock a size or invoke setPreferredSize() to hardcode a minimum size.\nFranck Marchand — March 7, 2016 at 11:54 am (permalink) Franck Marchand says:\nThanks, it works.\nAhmed Elnabwy — May 5, 2017 at 6:45 am (permalink) Ahmed Elnabwy says:\nimports ,please\nShai Almog — May 6, 2017 at 5:41 am (permalink) Shai Almog says:\nimport com.codename1.ui.*;\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-graphics-part-2-drawing-an-analog-clock/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-graphics-part-2-drawing-an-analog-clock/codename-one-graphics-part-2-drawing-an-analog-clock-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Codename One Clock\" loading=\"lazy\" src=\"/blog/codename-one-graphics-part-2-drawing-an-analog-clock/codename-one-graphics-part-2-drawing-an-analog-clock-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThis post was written by\u003cbr\u003e\n\u003ca href=\"http://sjhannah.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nSteve Hannah\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, one of the newest additions to the Codename One team and a long time community contributor.\u003c/p\u003e\n\u003cp\u003eThe new Codename One graphics pipeline includes support for advanced 2D and 3D transformations.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://www.codenameone.com/blog/codename-one-graphics\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nLast time\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nI talked about some of the new features in Codename One’s graphics. Then I presented an example app to demonstrate the use of the new shapes API. In this instalment, I will focus on some of the new graphics transformation features.\u003c/p\u003e","title":"Codename One Graphics Part 2: Drawing an Analog Clock"},{"content":"\nIn the past we made several attempts at compiling Codename One applications to webapps, these were only partially successful. On the surface this seems relatively simple: just use something like GWT and the Canvas API to generate a web app. However, Codename One requires threads (for the EDT) and that’s just not something you can really hide. GWT is also problematic since it requires the source code rather than the bytecode of the application…\nA couple of years ago I attended a session from Tony Epple and Jaroslav Tulach at JavaOne where they discussed the work they were doing on\nbck2brwsr\n. This looked very interesting and I instantly broached the subject of threads with Jaroslav. Fast forward to today and Jaroslav is interested in implementing threads on bck2brwsr and looking for sponsorship to do that…\nThat’s where we can step in… We would like to sponsor Jaroslav in his efforts which will allow us to do something grand!\nWe will allow you to just right click a project and select \u0026ldquo;Build a web app\u0026rdquo;. You will get a self contained app that doesn’t need a server side and would be implemented entirely in JavaScript… You would still be able to use threads and most of the standard things Codename One has to offer, some limitations might apply but you should be able to create a completely portable app!\nOne of the nice things is that due to the architecture of Codename One we belive it would be faster than typical HTML5 framworks since it won’t be suseptible to the reflow problems that typical HTML5 code is suseptible to.\nTo pay for this work we will make this feature enterprise only and\n**\nwould only implemement it if we get 2 annual enterprise subscribers!\n**\nThis will effectively pay for most of the initial effort required to build this feature, if you are interested in this feature make sure to\nsignup for an enterprise account right now\n!\nNotice that since this feature would require an enterprise account anyway sponsoring this work will cost you nothing.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — January 26, 2015 at 6:51 pm (permalink) Anonymous says:\nThis sounds interesting. I looked at bck2brwsr a while ago, but it wasn’t really ready for prime time. I’ve done a lot of work with GWT, and really like it, except for the reliance (like most all Javascript frameworks) on the DOM. GWT has some nice features though, like code splitting.\nI’m wondering what the use case is you see for this ? As CN1 is touch device oriented, would you see the ability to have a keyboard/mouse app ?\nAnonymous — January 26, 2015 at 10:11 pm (permalink) Anonymous says:\nTake a look on Dragome (http://www.dragome.com/)). It’s also a production ready bytecode to js compiler. It can be interesting for you.\nAnonymous — January 27, 2015 at 3:44 am (permalink) Anonymous says:\nCodename One works well with non-touch and we already have a desktop target which pro users are using. Since desktop apps are moving to look more like tablet apps this isn’t a big leap.\nThe main use case is enterprise requirements, sometimes just having a webapp is a starting point and if you don’t have it then its a problem. This can also provide support for niche platforms like Windows Phone, Firefox OS, tizen, Jolla etc. and allow governments/agencies that are required to support \u0026ldquo;everyone\u0026rdquo; to claim that they do.\nAnonymous — January 27, 2015 at 3:46 am (permalink) Anonymous says:\nThanks, there are several. However those guys just use XMLVM for the actual heavy lifting, that’s not a very ideal solution performance wise and doesn’t solve the thread problem that we need solved.\nAnonymous — January 28, 2015 at 6:22 am (permalink) Anonymous says:\nThat sounds like a really good idea! I’m very curious about performance. Unfortunately I can’t afford an enterprise account. Is it maybe a good idea to start some ‘crowdfunding’, to make this available for all subscribers if there’s enough money collected? I will certainly donate!\nAnonymous — January 28, 2015 at 2:53 pm (permalink) Anonymous says:\nCrowdfunding seems unreliable, it works well for those with marketing skills but for something as niche as this I doubt it would provide value.\nPerformance should be good since we won’t have the overhead of reflows but obviously its something we can only prove when its fully operational.\nAnonymous — January 28, 2015 at 7:12 pm (permalink) Anonymous says:\nYes I was not thinking about a crowdfunding platform but hoping that current users would like to contribute. Bit I don’t really know if there are enough users to do such a thing.\nAnonymous — January 28, 2015 at 7:22 pm (permalink) Anonymous says:\nLike Maaike, I can’t justify an enterprise account, but would be prepared to tip in for new features. If you got 50 people contributing, say, $100, that very nearly covers your goal. Maybe you need a \u0026ldquo;Make a Donation\u0026rdquo; button so people can make a one-off contribution that can be used however you see fit.\nAnonymous — January 29, 2015 at 4:04 am (permalink) Anonymous says:\nOrganizing something like that is just not feasible without a platform like kickstarter and doing it in those platforms isn’t viable.\nI understand the cost issue, having reviewed the financials I can’t see any other way we can \u0026ldquo;make this work\u0026rdquo; other than bolstering our enterprise developers. We need more personnel to maintain more platforms and a one time expense just isn’t enough. Having more enterprise developers will allow us to hire more employees and thus maintain this (and other ports).\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/web-app-build-target/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/web-app-build-target/web-app-build-target-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/web-app-build-target/web-app-build-target-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eIn the past we made several attempts at compiling Codename One applications to webapps, these were only partially successful. On the surface this seems relatively simple: just use something like GWT and the Canvas API to generate a web app. However, Codename One requires threads (for the EDT) and that’s just not something you can really hide. GWT is also problematic since it requires the source code rather than the bytecode of the application…\u003c/p\u003e","title":"Web App Build Target"},{"content":"\nIn recent versions of iOS Apple added the ability to\ndistribute\nbeta versions of your application\nto beta testers using tools they got from the testflight acquisition. We now support this with our crash protection pro feature, just use the build argument\nios.testFlight=true and you can then submit your app to the store for beta testing.\nWith iOS 8 Apple also introduced a requirement that’s important for you to be aware of if you use the location API. You need to state why you are using that API in the application meta-data. You can use the\nios.locationUsageDescription build argument to describe the reason you need to obtain the users location data e.g.:\nios.locationUsageDescription\n=Allows us to offer you better deals when you are in the vicinity of our business\nInput in iOS is a bit more complex but I’d say somewhat better than Android since it allows you to scroll while editing by default. However, this input mode triggered some regressions for developers especially in cases where the app places a text field component at the bottom of the screen in a non-scrollable area. The default behavior is to fallback to the old editing mode and just scroll up the entire display which carries some issues with it.\nWe now have a new API on form \u0026quot;\nsetFormBottomPaddingEditingMode\u0026quot; which allows you to hint that in such cases you would want to fallback to padding at the bottom of the form rather than shifting the entire screen. This still allows scrolling the screen as expected while editing. Currently this only has an effect on iOS but we’d like to modernize Android’s input to use similar semantics in the future.\nWe also exposed the previously private stopEditing\nmethod in Display. This method is a companion method to editString and allows you to manually stop the editing in progress. This can be useful for cases such as filling a form where a user types into a field a social security number. You can detect a valid number, stop the editing and instantly move the user to the next relevant field using editString().\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — January 22, 2015 at 5:07 am (permalink) Anonymous says:\nThanks, this setFormBottomPaddingEditingMode is a nice feature, but there seams to be a bug – scrolling works well when the next edited field is opened from keyboard native \u0026ldquo;Next\u0026rdquo; button, but when a lower field editing is opened by clicking on the field, then the field is not scrolled to make room for the keyboard. Interestingly in this case scrolling happens only after clicking on \u0026ldquo;Done\u0026rdquo; button.\nAnonymous — January 22, 2015 at 6:20 am (permalink) Anonymous says:\nI’m sorry for the previous misleading info. Actually the mentioned bug is not related to setFormBottomPaddingEditingMode, it happens always with ios.keyboardOpen=true.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/location-ios-beta-testing-better-input/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/location-ios-beta-testing-better-input/location-ios-beta-testing-better-input-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/location-ios-beta-testing-better-input/location-ios-beta-testing-better-input-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eIn recent versions of iOS Apple added the ability to\u003cbr\u003e\n\u003ca href=\"https://developer.apple.com/library/prerelease/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/BetaTestingTheApp.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\ndistribute\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://developer.apple.com/library/prerelease/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/BetaTestingTheApp.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nbeta versions of your application\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nto beta testers using tools they got from the testflight acquisition. We now support this with our crash protection pro feature, just use the build argument\u003c/p\u003e\n\u003cp\u003eios.testFlight=true and you can then submit your app to the store for beta testing.\u003c/p\u003e\n\u003cp\u003eWith iOS 8 Apple also introduced a requirement that’s important for you to be aware of if you use the location API. You need to state why you are using that API in the application meta-data. You can use the\u003c/p\u003e","title":"Location, iOS Beta Testing \u0026 Better Input"},{"content":"\nThis post we written by\nSteve Hannah\n, one of the newest additions to the Codename One team and a long time community contributor.\nThis is the first in a series of posts about drawing graphics in Codename One. In this tutorial, we will create a rudimentary drawing app to demonstrate how to use the Shape API.\nSome Background\nCodename One has included basic 2D graphics ability since its inception, but until recently, it was missing a few primitives that were required for drawing arbitrary graphics. Most notably, it did not include a general \u0026ldquo;Shape\u0026rdquo; API to draw arbitrary paths. This meant that most graphics were composed of images, a few common geometry primitives such as rectangles and circles, and clever use of tiling and clipping. If you wanted to draw an arbitrary shape composed of lines and bezier curves, you were generally out of luck.\nI ported the\nPisces graphics library\nto Codename One last year in order to provide this type of functionality inside Codename One apps. This provided a 2D drawing API, but it was quite slow. Fine for static drawings, but too slow to be used in most animations.\nThe new CN1 graphics API provides the same types of functionality as the Pisces library, but with drastically improved performance. Finally we can draw complex 2D graphics (and 3D graphics in some platforms) without clogging the rendering pipeline.\nNew Features\nA Shape API for drawing generalized paths on a Graphics context.\nA Transformation API to be able to perform transformations on graphics contexts and shapes. (E.g. rotate, scale, translate, etc…​).\nSupport for 3D transformations. (Currently only available on Android and iOS).\nDevice Support\n(As of writing, this may change in the future as there is demand to backport the functionality to older platforms).\nAPI Simulator Android iOS JME Windows Phone BlackBerry Shapes Yes Yes Yes – – – 2D Transforms Yes Yes Yes – – – 3D Transforms – Yes Yes – – – A 2D Drawing App\nLet’s look at a simple example of a drawing app, that allows the user to tap the screen to draw a contour picture. The app will work by simply keeping a\nGeneralPath\nin memory, and continually add points as bezier curves. Whenever a point is added, the path is redrawn to the screen.\n**\nStep 1: Create a Project\n**\nWe start by creating a standard \u0026ldquo;Hello World\u0026rdquo; project using the \u0026ldquo;Non-visual\u0026rdquo; template (i.e. built with code, not the GUI editor).\n**\nStep 2: Make the Canvas\n**\nThe center of the app is the DrawingCanvas class, which extends\nComponent\n.\nConceptually this is very basic component. We will be overriding the\npaintBackground()\nmethod to draw the path. We keep a reference to a\nGeneralPath\nobject (which is the concrete implementation of the Shape interface in Codename One) to store each successive point in the drawing. We also parametrize the stroke width and color.\nThe implementation of the paintBackground() method (shown above) should be fairly straight forward. It creates a stroke of the appropriate width, and sets the color on the graphics context. Then it calls drawShape() to render the path of points.\nImplementing addPoint()\nThe addPoint method is designed to allow us to add points to the drawing. A simple implementation that uses straight lines rather than curves might look like this:\nWe introduced a couple house-keeping member vars (lastX and lastY) to store the last point that was added so that we know whether this is the first tap or a subsequent tap. The first tap triggers a moveTo() call, whereas subsequent taps trigger lineTo() calls, which draw lines from the last point to the current point.\nA drawing might look like this:\nUsing Bezier Curves\nOur previous implementation of addPoint() used lines for each segment of the drawing. Let’s make an adjustment to allow for smoother edges by using quadratic curves instead of lines.\nCodename One’s GeneralPath class includes two methods for drawing curves:\n[ quadTo() ](/javadoc/com/codename1/ui/geom/GeneralPath.html#quadTo%28float,%20float,%20float,%20float%29) Appends a quadratic bezier curve. It takes 2 points: a control point, and an end point. [ curveTo() ](/javadoc/com/codename1/ui/geom/GeneralPath.html#curveTo%28float,%20float,%20float,%20float,%20float,%20float%29) Appends a cubic bezier curve, taking 3 points: 2 control points, and an end point. See the\nGeneral Path javadocs\nfor the full API.\nWe will make use of the\nquadTo()\nmethod to append curves to the drawing as follows:\nThis change should be fairly straight forward except, perhaps, the business with the odd variable. Since quadratic curves require two points (in addition to the implied starting point), we can’t simply take the last tap point and the current tap point. We need a point between them to act as a control point. This is where we get the curve from. The control point works by exerting a sort of \u0026ldquo;gravity\u0026rdquo; on the line segment, to pull the line towards it. This results in the line being curved. I use the odd marker to alternate the control point between positions above the line and below the line.\nA drawing from the resulting app looks like:\nDetecting Platform Support\nThe DrawingCanvas example is a bit naive in that it assumes that the device supports the shape API. If I were to run this code on a device that doesn’t support the Shape API, it would just draw a blank canvas where I expected my shape to be drawn. You can fall back gracefully if you make use of the\nGraphics.isShapeSupported()\nmethod. E.g.\nNext Time\nThe next post in this series will cover 2D animations. Stay tuned for more…​\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — January 19, 2015 at 8:15 am (permalink) Anonymous says:\nGood work Steve + team! Looking forward to read more of this tutorial. Perhaps bring back some of the 3D transformations we used to since the LWUIT days? Also more ports for Windows and BB would be nice.\nAnonymous — January 19, 2015 at 9:19 am (permalink) Anonymous says:\nThanks Steve ! Good to know you are part of the cn1 team now, I always told the cn1 guys they are great but need more hands to do such a complex job. About the Shape API, I am eager to use it, but the absence of an Arc2D shape is a killer in many situations, I even wrote a nice whell-like progress component that was not accepted by Shai to be included because it relies on Graphics.drawArc, and the Bezier curves do not deliver an acceptable result in this case either. Also, I believe it should use floating point, it would deliver smoother Shapes, wouldn’t it ?\nAnonymous — January 19, 2015 at 1:07 pm (permalink) Anonymous says:\nI wasn’t involved during the LWUIT days. What 3D transformations are you referring to? We do support full 3D transformations in this pipeline via the Transform class. I’ll be going through that in a later tutorial.\nAnonymous — January 19, 2015 at 1:13 pm (permalink) Anonymous says:\nI agree that drawArc() would be nice. You can implement it currently using a a series of lines or bezier curves, but this wouldn’t be as performant as an actual drawArc() primitive. Please file and issue on this.\nChanging to use floating point wouldn’t be terribly hard to do… It wouldn’t affect shapes drawn with GeneralPath (since that is already using floating point) but could potentially make things more flexible with aggregating multiple shapes and paths together. Please file an issue on this.\nAnonymous — January 19, 2015 at 2:31 pm (permalink) Anonymous says:\nFYI the old Transition3D support: https://www.youtube.com/wat… its around the second minute. Keep in mind this was all running on feature phones with 2mb of RAM.\nAnonymous — January 30, 2015 at 6:51 pm (permalink) Anonymous says:\nFor Steve Hannah:\nI’m teaching my grandsons Java by porting the Raspberry Pi Snake Game from Python to Java. Have it running in Java as an app, but they would really be pumped to get it on an iPad. Hence CN1. The core is some graphics and a game loop timer. Looking forward to your next post on animation. But having problems with your DrawingCanvas app post.\nI made a manual CN1 app in Eclipse. Added DisplayCanvas from your post. Used the straight line version of addPoint(). It turns out lastY is never used and lastX=x; is assigning a float to an int. Fixed the compile by:\nprivate int lastX=-1;\n// private int lastY=-1;\npublic void addPoint(float x, float y){\nif ( lastX == -1 ){\n// this is the first point… don’t draw a line yet\np.moveTo(x, y);\n} else {\np.lineTo(x, y);\n}\nlastX = (int) x;\n// lastY = y;\nrepaint();\n}\nInserted an addComponent(new DrawingCanvas()) right after adding the \u0026ldquo;Hello World\u0026rdquo; label component.\nForm hi = new Form(\u0026ldquo;Hi World\u0026rdquo;);\nhi.addComponent(new Label(\u0026ldquo;Hi World\u0026rdquo;));\nhi.addComponent(new DrawingCanvas());\nhi.show;\nRan it. The simulator opened. It looked just the same as before inserting the addComponent(new DrawingCanvas()). I clicked a couple of points on the screen. Nothing happened. No breakpoint I put in DrawCanvass gets called. QUESTION: Should this work in the simulator?\nSwitched from Drawing Canvas to something dead simple:\npublic class DrawLine extends Component {\npublic DrawLine() {\nsuper();\nsetSize(new Dimension(200, 200));\n}\npublic void paint(Graphics g) {\ng.drawLine(30, 30, 150, 150);\n}\n}\nStill nothing! HELP!!!\nAnonymous — January 30, 2015 at 7:44 pm (permalink) Anonymous says:\nThanks for pointing this out. There, in fact, were a couple of typos in the source. Check out the full sources here:\nhttps://gist.github.com/sha…\nand here\nhttps://gist.github.com/sha…\nAnonymous — January 31, 2015 at 3:45 pm (permalink) Anonymous says:\nStill nothing comes up in the simulator but the \u0026ldquo;Hi World\u0026rdquo; label. And clicking on the screen below the label has no effect. Nothing with either your DrawingCanvas or DrawingCanvasBezier. And breakpoints put at the start of the 3 DrawingCanvas methods are never triggered — nothing in DrawingCanvas is getting called (other than its default constructor).\npublic void start() {\nif(current != null){\ncurrent.show;\nreturn;\n}\nForm hi = new Form(\u0026ldquo;Hi World\u0026rdquo;);\nhi.addComponent(new Label(\u0026ldquo;Hi World\u0026rdquo;));\nhi.addComponent(new DrawingCanvas());\nhi.show;\n}\nAnd I updated the CN1 plugin into my Eclipse just a few days ago.\nAnonymous — January 31, 2015 at 3:48 pm (permalink) Anonymous says:\nStrange. It works fine for me. Keep in mind, nothing should show up until your second click. The first click just marks the start of the line that will be produced by your second click.\nAnonymous — January 31, 2015 at 4:23 pm (permalink) Anonymous says:\nWait, I see the problem. You are using FlowLayout. The DrawingCanvas doesn’t have a preferred size set, it relies completely on the layout manager to size it. If you use a BorderLayout instead, then place the DrawingCanvas in the center, it will work.\nSteve\nAnonymous — January 31, 2015 at 6:16 pm (permalink) Anonymous says:\nThat was it! Many thanks!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-graphics/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-graphics/codename-one-graphics-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/codename-one-graphics/codename-one-graphics-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis post we written by\u003cbr\u003e\n\u003ca href=\"http://sjhannah.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nSteve Hannah\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, one of the newest additions to the Codename One team and a long time community contributor.\u003c/p\u003e\n\u003cp\u003eThis is the first in a series of posts about drawing graphics in Codename One. In this tutorial, we will create a rudimentary drawing app to demonstrate how to use the Shape API.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2\u003e\u003c/h2\u003e\n\u003cp\u003eSome Background\u003c/p\u003e\n\u003cp\u003eCodename One has included basic 2D graphics ability since its inception, but until recently, it was missing a few primitives that were required for drawing arbitrary graphics. Most notably, it did not include a general \u0026ldquo;Shape\u0026rdquo; API to draw arbitrary paths. This meant that most graphics were composed of images, a few common geometry primitives such as rectangles and circles, and clever use of tiling and clipping. If you wanted to draw an arbitrary shape composed of lines and bezier curves, you were generally out of luck.\u003c/p\u003e","title":"Codename One Graphics"},{"content":"\nI’ll be speaking at\nRiga Dev Day\nnext week and I’ve been working on a demo for the conference. Back in my teen years I bought the SoundBlaster 1.0 which was one of the first affordable soundcards for the PC. One of the killer demos that shipped with it was a silly command line AI psychoanalyst by the name of\nDr. Sbaitso\nthat would try to dish out advice in all caps…\nIt was actually surprisingly cool and gave a wide set of answers that were often pretty clever. As a salute to the wonderful developer who built that we created a simple chat demo that is more like the iMessage UI than like Dr. Sbaitso but it does use its signature opening tagline.\nThe demo uses the new Toolbar API and some other cool capabilities such as camera capture, bubble chat, instant search etc. We even added a native interface so it will speak just like the original doctor!\nWe hope to make some videos that cover the new demo and how it works.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/dr-sbaitso-coming-to-riga/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/dr-sbaitso-coming-to-riga/dr-sbaitso-coming-to-riga-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/dr-sbaitso-coming-to-riga/dr-sbaitso-coming-to-riga-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ll be speaking at\u003cbr\u003e\n\u003ca href=\"http://www.rigadevday.lv\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nRiga Dev Day\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nnext week and I’ve been working on a demo for the conference. Back in my teen years I bought the SoundBlaster 1.0 which was one of the first affordable soundcards for the PC. One of the killer demos that shipped with it was a silly command line AI psychoanalyst by the name of\u003cbr\u003e\n\u003ca href=\"http://en.wikipedia.org/wiki/Dr._Sbaitso\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nDr. Sbaitso\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nthat would try to dish out advice in all caps…\u003c/p\u003e","title":"Dr. Sbaitso Coming To Riga"},{"content":"NOTE : The information in this blog post is out of date. Codename One now fully supports the Collection.toArray(T[] arr) method, including the case where arr is an array of size 0.\nA recent issue in the issue tracker on the new iOS VM reminded me of a serious pet peeve and big design mistake in the Java Collections API, something that is just unfixable and wrong yet appears often in code from developers trying to be clever.\nIf you have a collection and you want to convert it to an array you can do something like:\nObject[] myArray = c.toArray();\nUnfortunately, this will always be an array of objects and not of your desired type… So if the collection is one of String you would really want to do something like:\nString[] array = new String[c.size()];\nc.toArray(array);\nThis works great but takes two lines… Which is why you can also do something like this:\nString[] array = (String[])c.toArray(new String[c.size()]);\nSo far so good… The problem is that this also works:\nString[] array = (String[])c.toArray(new String[0]);\nIt will produce an array response that is equal to the size of c and is of type String[] and not Object[]. This will fail on the new iOS VM and should really never be used…\nJava usually takes the approach of \u0026ldquo;fail fast\u0026rdquo;, which means that if code fails it should do so ASAP and not \u0026ldquo;try to recover\u0026rdquo; which might cause bugs to remain hidden. This isn’t such a case.\nIf the array past to the toArray method is too small, the code has a fallback. The problem is that the fallback is REALLY bad!\nIt uses reflection to detect the array type and allocate a whole new array. This is really slow and that essentially means the original allocated array is just completely redundant garbage. And all this just saves a single boilerplate method call:\nString[] array = (String[])c.toArray(new String[\n**\nc.size()\n**\n]);\nDon’t do that, on Java SE/EE either. It has reflection and a better optimizer but even the best optimizer can’t eliminate something this bad…\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nSebastian Sickelmann — January 20, 2016 at 4:32 am (permalink) Sebastian Sickelmann says:\nYou should also read http://shipilev.net/blog/20… and maybe relativize some statements about Java SE and it’s reflection and optimizing possibilities.\nShai Almog — January 20, 2016 at 4:37 am (permalink) Shai Almog says:\nYou are aware I worked for Sun and did quite a bit of JIT development 😉\nI am fully aware of what a high end JIT can do to code that’s repeated often. We are talking AOT mobile device compilation where those aren’t an option… Generally I don’t see a reason to \u0026ldquo;force\u0026rdquo; a JIT to do work, if I can write the original code correctly for the first pass of the JIT rather than just being lazy and passing 0 why not do that?\nNotice that newer versions of the JVM are talking about new language features such as the ability to use generics efficiently with primitives. This would also pose a problem with relying on behaviors like this…\nSebastian Sickelmann — January 20, 2016 at 3:29 pm (permalink) Sebastian Sickelmann says:\nWell just wanted to mention the fairly new article regarding the same programming pattern. And if I get Aleksey right it is actually the other way around. By passing an non empty array you make it harder for the JIT at least for the HotspotVM to deliver best performance. It is totally clear to me that in other VM Implementation or in AOT Optimization scenarios for mobiles it may be the other way around.\nShai Almog — January 21, 2016 at 3:43 am (permalink) Shai Almog says:\nIts interesting to read but I disagree with the conclusion as it hinges on micro-benchmarks which often give a wrong impression especially with a JIT as \u0026ldquo;insane\u0026rdquo; as hotspot.\nOne thing that does make a lot of sense is that toArray without arguments is the fastest and that’s probably the best tip you can get here as it makes sense performance wise.\nSince hotspot takes a while to \u0026ldquo;warmup\u0026rdquo; and would do it for every call you make to toArray() I’m not so sure if this would still perform as nicely in real world scenarios. Every JIT engineer I know would recommend that you write code that is \u0026ldquo;correct\u0026rdquo; rather than optimize to a JIT. To me allocating a 0 size array as a \u0026ldquo;hint\u0026rdquo; is incorrect code and it does perform slower on anything other than a fully optimized hotspot path.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/the-toarraynew-array-antipattern/","summary":"\u003cp\u003e\u003cstrong\u003eNOTE\u003c/strong\u003e : The information in this blog post is out of date. Codename One now fully supports the \u003cstrong\u003eCollection.toArray(T[] arr)\u003c/strong\u003e method, including the case where \u003cstrong\u003earr\u003c/strong\u003e is an array of size \u003cstrong\u003e0\u003c/strong\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/the-toarraynew-array-antipattern/the-toarraynew-array-antipattern-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/the-toarraynew-array-antipattern/the-toarraynew-array-antipattern-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA recent issue in the issue tracker on the new iOS VM reminded me of a serious pet peeve and big design mistake in the Java Collections API, something that is just unfixable and wrong yet appears often in code from developers trying to be clever.\u003c/p\u003e","title":"The toArray(new Array) Antipattern"},{"content":"\nA Codename One community member\nAntonio Mannucci offered\nto release a gaming API that he created a while back. It took him some time but he finally delivered on his promise by\nreleasing a cn1lib for simple 2D games in Codename One\nand a demo game to go with it.\nThe project is still pretty rough in the sense that there is no real documentation or getting started guide. However, there isn’t much that needs saying… Just checkout the code and build the library then run the example demo. The demo has some issues that I’m unclear about but it looks promising.\nThe basic concepts of Sprites, tiles, touch keypad, music \u0026amp; sound effects all seem to be in place. I’m not sure where this is going since gaming isn’t in our core focus, but if you are interested in building a game using Codename One then looking/contributing to this project might be interesting.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/game-on/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/game-on/game-on-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/game-on/game-on-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eA Codename One community member\u003cbr\u003e\n\u003ca href=\"https://groups.google.com/d/msg/codenameone-discussions/wumShzMwUmw/1JAFcEanABAJ\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nAntonio Mannucci offered\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nto release a gaming API that he created a while back. It took him some time but he finally delivered on his promise by\u003cbr\u003e\n\u003ca href=\"https://code.google.com/p/core2d-cn1lib/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nreleasing a cn1lib for simple 2D games in Codename One\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nand a demo game to go with it.\u003c/p\u003e\n\u003cp\u003eThe project is still pretty rough in the sense that there is no real documentation or getting started guide. However, there isn’t much that needs saying… Just checkout the code and build the library then run the example demo. The demo has some issues that I’m unclear about but it looks promising.\u003c/p\u003e","title":"Game On"},{"content":"\nChen spent some time working on some Toolbar effects such as the rich title areas made popular by social network apps such as G+ \u0026amp; Twitter. The new Flickr demo in SVN now shows a really cool ability to fold the title bar as we scroll down and expand it when we scroll up. It also shows an image based title area that can fade out of view during scrolling. Check out the video below to get a taste of the possibilities.\nWe hope to make an update to the plugin this week or the next, it will include the new Toolbar functionality and other fixes.\nOn the new VM front we closed multiple open bugs in the new VM and are considering it a solid beta. We are starting to look into new features that we can enable thanks to its architecture.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — January 5, 2015 at 7:16 pm (permalink) Anonymous says:\nThat’s an interesting demo. I notice that there is no back behaviour (i.e. on Android the hardware back key exits the application, irrespective of which form you are on).\nAnonymous — January 6, 2015 at 7:45 am (permalink) Anonymous says:\nIs it possible to mix SideMenuBar with native android action bar in the same app now? For example one form i might want to use the SideMenuBar, but the next form, I might want to use the android action bar?\nAnonymous — January 7, 2015 at 5:08 am (permalink) Anonymous says:\nYes, should be possible with the Toolbar\nAnonymous — January 7, 2015 at 6:41 am (permalink) Anonymous says:\nThanks Chen, very good work!\nAnonymous — January 7, 2015 at 8:43 am (permalink) Anonymous says:\nWhat a great feature. Will this be available on iOS too? And is it possible to zoom in the cat image when you tensileDrag the container down?\nAnonymous — January 7, 2015 at 6:17 pm (permalink) Anonymous says:\nThis feature is available to all supported platforms.\nZoom in should be possible, I suggest you to check out the new Flickr Demo from the project svn and have a look at the code.\nAnonymous — January 8, 2015 at 5:52 am (permalink) Anonymous says:\nI hear Windows Port in general is still flimsy, not sure what that status is on that but I do notice more Windows Phone support in my country.\nAnonymous — January 19, 2015 at 11:44 pm (permalink) Anonymous says:\nThis toolbar is available now ?, I’m downloaded the netbeans plugin updated in 13-01-2015 and Toolbar class and form.setToolbar not exists… Why ?\nAnonymous — January 20, 2015 at 4:14 am (permalink) Anonymous says:\nRight click the project. Click \u0026ldquo;Preference\u0026rdquo; select the Codename One section and click \u0026ldquo;Update Client Libraries\u0026rdquo;.\nAnonymous — January 24, 2015 at 11:19 am (permalink) Anonymous says:\nIm very interested in this functionality.\nIs this being done via the gui? Or is this something that is hardcoded?\nAnonymous — January 25, 2015 at 6:16 am (permalink) Anonymous says:\nThis is handcoded although you could use a Toolbar in a GUI builder application as well but you would have to handcode that portion in the before form call.\nSanne Graaf — October 15, 2015 at 12:13 pm (permalink) Sanne Graaf says:\nWhere can I find the sourcecode of this exampe?\nShai Almog — October 16, 2015 at 12:54 pm (permalink) Shai Almog says:\nHere: https://github.com/codename…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/cats-in-toolbars/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/cats-in-toolbars/cats-in-toolbars-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/cats-in-toolbars/cats-in-toolbars-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eChen spent some time working on some Toolbar effects such as the rich title areas made popular by social network apps such as G+ \u0026amp; Twitter. The new Flickr demo in SVN now shows a really cool ability to fold the title bar as we scroll down and expand it when we scroll up. It also shows an image based title area that can fade out of view during scrolling. Check out the video below to get a taste of the possibilities.\u003c/p\u003e","title":"Cats in Toolbars"},{"content":"\nWe are closing 2014 which has been a pretty eventful year for us where we finally solidified Codename One, looking into 2015 we have a lot of great plans ahead!\nThe new year seems like a great time to discuss some of our short/long term plans for Codename One as we move forward and our general thoughts. But first I’d like to open with the things we did badly in 2014 and that we should probably improve in 2015:\nWe didn’t release Codename One 3.0 (or 2.5 for that matter). We were so busy with everything that making a stable release got sidetracked. This is something we need to invest more time into!\nWe spent too much focus on big things (new VM, new windows phone pipeline, corporate server) and too little time on small but crucial features. Some of those features were crucial, but speaking to developers it seems most would prefer many small increments to large revolutions.\nWe didn’t invest in design – our themes didn’t see any major change since launch. We need to significantly overhaul that.\nWe didn’t capitalize on some features, e.g. we built new graphics pipelines and didn’t really use the functionality for charts, improved transition etc.\nWe traveled too much in 2014, while it seemed productive initially it didn’t directly map to business success and we probably won’t be doing as much travel/conferences in 2015.\nWe hope to improve on all of those for 2015 and so far its looking very positive. Most of the \u0026ldquo;heavy\u0026rdquo; infrastructure work was done in 2014 which means 2015 will allow us to leap forward with better underlying technology and focus on the surface of things.\nThese are the things we’re very happy about in 2014:\nCommunity cn1lib’s – these started taking off really well! Some great work from many different members of the community as well as a few of our own. I think we will focus on bringing out far more features as cn1libs rather than integrate them in the core. At least initially.\nThe infrastructure work such as improving the build servers, replacing the VM and the rendering pipelines. It was painful and time consuming to do all this work but it is already proving its value.\nWe are very happy with the new Toolbar API and hope to do similar convenience API’s in 2015\nOur presentation and videos have improved significantly, but we didn’t do nearly as much video tutorials as we should have.\nPretty great applications from community members e.g.\nTravel2gether\n,\nyhomework\netc.\nFor 2015 our high level goals are:\nRefinement – We want to make the process of signing up to Codename One, creating an app, paying etc. far more refined and smooth.\nEnterprise functionality – most of the features in Codename One are in the lower grade subscription levels. We are now focused on adding more high end features.\nIntegrations – we are looking to support the top mobile solutions out of the box, so you don’t have to do the integration on your own.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/happy-new-year-looking-back-forward/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/happy-new-year-looking-back-forward/happy-new-year-looking-back-forward-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/happy-new-year-looking-back-forward/happy-new-year-looking-back-forward-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are closing 2014 which has been a pretty eventful year for us where we finally solidified Codename One, looking into 2015 we have a lot of great plans ahead!\u003c/p\u003e\n\u003cp\u003eThe new year seems like a great time to discuss some of our short/long term plans for Codename One as we move forward and our general thoughts. But first I’d like to open with the things we did badly in 2014 and that we should probably improve in 2015:\u003c/p\u003e","title":"Happy New Year – Looking Back \u0026 Forward"},{"content":"\nIts always a challenge to migrate to a new implementation and the new VM is no exception, we ran into several issues and are already hard at work fixing them.\nCurrently resolved are:\n[ Issue 1149 ](https://code.google.com/p/codenameone/issues/detail?id=1149) ios.newVM causes exception on Calender.getTime() [ Issue 1151 ](https://code.google.com/p/codenameone/issues/detail?id=1151) array index out of bounds exception with ios.newVM=true We also fixed several other issues causing the build to be slower/larger and potentially less secure. The two fixes above are already in the build servers and the additional fixes will land tomorrow.\nStill open is:\n[ Issue 1245 ](https://code.google.com/p/codenameone/issues/detail?id=1245) Strange System.currentTimeMillis() behavior with iOS new VM We hope to resolve that soon as well. All VM related issues are getting the most attention possible from us and we currently seem to be on track to a very stable release.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/stabilizing-the-new-vm/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/stabilizing-the-new-vm/stabilizing-the-new-vm-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/stabilizing-the-new-vm/stabilizing-the-new-vm-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eIts always a challenge to migrate to a new implementation and the new VM is no exception, we ran into several issues and are already hard at work fixing them.\u003c/p\u003e\n\u003cp\u003eCurrently resolved are:\u003c/p\u003e\n\u003cdl\u003e\n\u003cdt\u003e[\u003c/dt\u003e\n\u003cdt\u003eIssue 1149\u003c/dt\u003e\n\u003cdt\u003e](\u003ca href=\"https://code.google.com/p/codenameone/issues/detail?id=1149\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttps://code.google.com/p/codenameone/issues/detail?id=1149\u003c/a\u003e)\u003c/dt\u003e\n\u003cdd\u003eios.newVM causes exception on \u003ccode\u003eCalender.getTime()\u003c/code\u003e\u003c/dd\u003e\n\u003cdt\u003e[\u003c/dt\u003e\n\u003cdt\u003eIssue 1151\u003c/dt\u003e\n\u003cdt\u003e](\u003ca href=\"https://code.google.com/p/codenameone/issues/detail?id=1151\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttps://code.google.com/p/codenameone/issues/detail?id=1151\u003c/a\u003e)\u003c/dt\u003e\n\u003cdd\u003earray index out of bounds exception with ios.newVM=true\u003c/dd\u003e\n\u003c/dl\u003e\n\u003cp\u003eWe also fixed several other issues causing the build to be slower/larger and potentially less secure. The two fixes above are already in the build servers and the additional fixes will land tomorrow.\u003c/p\u003e","title":"Stabilizing The New VM"},{"content":"\nNew builds sent for iOS will now use the new iOS VM by default, this will deliver a lot of new features: stack traces, 64 bit, xcode 6+ support, iPhone 6/6+ native resolution, no stall GC etc.\nWe spent a great deal of time stabalizing the new VM but obviously it can’t be as mature as our existing XMLVM backend and so it is quite possible that you would run into issues that occur purely in the new VM. You can test that this is a new VM issue by building against the old VM using the build argument ios.newVM=false, assuming this is indeed a new VM issue please\nfile a bug\nwith a test case immediately.\nThere is currently one known issue with the new VM\nIssue\n1151\n.\nHere is a mini FAQ on how this might affect your app:\n**\nQ: What does the new VM include? What might be affected by the migration?\n**\n**\nA:\n**\nThe VM includes the portion that translates bytecode to C instructions, the garbage collector and the java.* packages of the virtual machine. All of those were rewritten from scratch to create the new VM. The old VM had quite a few bugs and misconceptions related to the threading model so threads would behave differently and more in line with the Java specification.\nThe build server, native API’s etc. weren’t significantly modified for the new VM so for most use cases the transition to the new VM should be seamless.\n**\nQ: What are the technical differences between the old and new VM?\n**\n**\nA:\n**\nThe old VM was based on XMLVM which is a very generic tool that can translate any language/VM to any other language/VM. While this is pretty powerful it had quite a few drawbacks.\nWhen Apple migrated to xcode 5.1 in preparation for 64 bit support they deprecated some assembly relied on by the XMLVM garbage collector. We also had several inherent bugs that were very hard to fix in XMLVM due to its generic architecture and we decided to make a clean break.\nThe XMLVM iOS implementation translates Java bytecode to dex and then translates that into C code, the new VM goes directly to C from bytecode. This has an advantage for the\nGC implementation\n, but since the ARM CPU is register based performance tuning is a bit trickier with the new VM.\nThe old VM supported a very large block of the Java API but did so without proper testing resulting in many pieces that just didn’t work. The new VM uses a very lean implementation of the subset supported by Codename One alone and should be far more efficient for that reason.\nIn most things the performance of the new VM should be superior, however due to the advantages of DEX over the bytecode approach in some cases it might.\n**\nQ: Will native code/libraries be affected?\n**\n**\nA:\n**\nNot by default. Native interfaces will work exactly like they always worked and you should be able to use existing code without changes.\nHowever, if you relied on existing behaviors of XMLVM such as by calling back from native code into the Java code you should read\nthis guide\n.\n**\nQ: Why was the new VM developed? Why not maintain the old XMLVM port? Why not use another 3rd party VM?\nA:\n**\nWe studied all the alternatives and came to the conclusion that any one of them would be the equivalent of moving back rather than forward.\nThey suffer from the problem of translating directly to machine code which is problematic with the frequent changes made by Apple. They also try to target the full Java language specification which is just too big to maintain/test in a reliable way across platforms.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-codename-one-ios-vm-is-now-the-default/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-codename-one-ios-vm-is-now-the-default/new-codename-one-ios-vm-is-now-the-default-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/new-codename-one-ios-vm-is-now-the-default/new-codename-one-ios-vm-is-now-the-default-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eNew builds sent for iOS will now use the new iOS VM by default, this will deliver a lot of new features: stack traces, 64 bit, xcode 6+ support, iPhone 6/6+ native resolution, no stall GC etc.\u003c/p\u003e\n\u003cp\u003eWe spent a great deal of time stabalizing the new VM but obviously it can’t be as mature as our existing XMLVM backend and so it is quite possible that you would run into issues that occur purely in the new VM. You can test that this is a new VM issue by building against the old VM using the build argument ios.newVM=false, assuming this is indeed a new VM issue please\u003cbr\u003e\n\u003ca href=\"http://code.google.com/p/codenameone/issues/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nfile a bug\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nwith a test case immediately.\u003c/p\u003e","title":"New Codename One iOS VM Is Now The Default"},{"content":"\nOne of the common requests we get from users is more customization for the title bar area with more flexibility e.g. placing a TextField for search or buttons in various ways. Chen recently took action on this by introducing the new Toolbar API that replicates some of the native functionality available on Android/iOS and integrates with features such as the side menu to provide very fine grained control over the title area behavior.\nEverything that the toolbar allows was possible in the past with various customizations, the difference is that the Toolbar API makes such use cases much simpler. To get started we can set a Toolbar to a Form using myForm.setToolbar(toolbar).\nAt that point we can add commands to the side menu with most of the existing\nside menu features\n(such as SideComponent), however to add a command to the SideMenu we will need to use toolbar.\naddCommandToSideMenu() instead of the standard add command. We can add commands to 4 locations:\naddCommandToSideMenu – adds to the sidemenu\naddCommandToOverflowMenu – adds the command to an Android style … menu on the top right hand side\naddCommandToRightBar – places the command on the right side of the title\naddCommandToLeftBar – places the command on the left side of the title\nNormally you can just set a title with a String but if you would want the component to be a text field or a multi line label you can use\nsetTitleComponent(Component) which allows you to install any component into the title area.\nAt this time the GUI builder doesn’t include toolbar specific functionality, depending on user requirements we might add this in the future.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — December 22, 2014 at 6:23 pm (permalink) Anonymous says:\nNice! I hope it’s also easier now to change the color of the toolbar. Thanks for adding this!\nAnonymous — January 4, 2015 at 12:35 pm (permalink) Anonymous says:\nHow do you update the plugin to use this toolbar functionality ?\nAnonymous — January 5, 2015 at 4:11 am (permalink) Anonymous says:\nWe will make an update in a week or two.\nAnonymous — February 21, 2015 at 1:42 pm (permalink) Anonymous says:\ni get below error when using this command:\nmainForm.setTitleComponent(titleCmb);\nThe method setTitleComponent(Label) in the type Form is not applicable for the arguments (ComboBox)\nAnonymous — February 22, 2015 at 2:20 am (permalink) Anonymous says:\nUse the method in the Toolbar not in the form.\njames agada — March 24, 2015 at 9:51 pm (permalink) james agada says:\nToolBar only adds to forms right? not to containers.\nShai Almog — March 25, 2015 at 5:06 am (permalink) Shai Almog says:\nYes.\nChidiebere Okwudire — January 25, 2016 at 9:15 am (permalink) Chidiebere Okwudire says:\nHi,\nOn iOS, the toolbar looks pretty native and comparable to the NavigationBar but on Android, the toolbar looks anything but native when compared to the Android Toolbar material design (see section ‘App bar’ here [https://www.google.com/desi…]).\nWhy doesn’t the Android implementation by default comply with these guidelines (height, nav icon size and position, background, etc.)? It’s annoying to have to tweak the toolbar for every single app just to get the default-like look on Android whereas it just works on iOS. Can you fix this issue or am I missing something?\nShai Almog — January 25, 2016 at 12:09 pm (permalink) Shai Almog says:\nI agree we should do it. Generally customizing the toolbar without breaking existing code was pretty hard but for a newly created app the toolbar should come preconfigured and easy to use.\nMatching material design on Android is our #1 priority based on our recent roadmap (together with performance) so this is something we want to do and we do want things to be far more refined than they are right now. Can you file an issue with suggestions e.g. what sort of tweeks you usually do to a project to get it to match?\nChidiebere Okwudire — January 25, 2016 at 2:28 pm (permalink) Chidiebere Okwudire says:\nHi,\nI’m still busy with the app 😉 I’ll file an issue after I’m done with the toolbar customization. That will be next week at the earliest.\nShai Almog — January 25, 2016 at 6:20 pm (permalink) Shai Almog says:\nHi,\nno rush whatsoever. Thanks.\nGareth Murfin — January 15, 2019 at 9:39 pm (permalink) Gareth Murfin says:\ni dont understand how the search bar was added to the toolbar, for me nothing appears\nShai Almog — January 16, 2019 at 4:45 am (permalink) Shai Almog says:\nThis is from 2014, I suggest looking at the Javadocs where there are two separate code samples for search\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/toolbar/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/toolbar/toolbar-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/toolbar/toolbar-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the common requests we get from users is more customization for the title bar area with more flexibility e.g. placing a TextField for search or buttons in various ways. Chen recently took action on this by introducing the new Toolbar API that replicates some of the native functionality available on Android/iOS and integrates with features such as the side menu to provide very fine grained control over the title area behavior.\u003c/p\u003e","title":"Toolbar"},{"content":"\nOur\nprevious attempt at getting the new Lollipop behavior\non Android OS 5 didn’t go as well as we had hoped. While we can’t find any device that failed we got a lot of community reports of various 4.x devices that just stopped working right after we made the changes recommended by Google. We tried to resolve them using several different tricks all of which proved futile. Eventually we just reverted the whole thing and went back to the drawing board, it seems Android fragmentation is worse than we feared.\nWe are now ready for another shot at this. This Tueday we will deploy a second attempt at the Lollipop action bar which will hopefully not break everything. This time the new action bar will only work for newer Android devices and older devices will fallback to the original action bar or old title bar. Make sure to test your apps as much as possible, if you are one of the people who ran into issues with our previous release take extra time to check that we didn’t break things again this Tuesday.\nWe also spent a lot of time working on the new iOS VM and fixed a lot of bugs there, we are rapidly closing the gap with the old VM and seem to be on schedule for the January release. We are still seeing projects that don’t compile and various issues, if you are one of the guys who experienced a problem with the new VM be sure to\nfile an issue right away\n!\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/lollipop-take-2-ios-vm-stability/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/lollipop-take-2-ios-vm-stability/lollipop-take-2-ios-vm-stability-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/lollipop-take-2-ios-vm-stability/lollipop-take-2-ios-vm-stability-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOur\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/blog/static-garbage-lollipop\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nprevious attempt at getting the new Lollipop behavior\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\non Android OS 5 didn’t go as well as we had hoped. While we can’t find any device that failed we got a lot of community reports of various 4.x devices that just stopped working right after we made the changes recommended by Google. We tried to resolve them using several different tricks all of which proved futile. Eventually we just reverted the whole thing and went back to the drawing board, it seems Android fragmentation is worse than we feared.\u003c/p\u003e","title":"Lollipop Take 2 \u0026 iOS VM Stability"},{"content":"\nWhile the\nwebservice wizard\nin Codename One is pretty useful for many things it still requires a proxy and Servlet container which might not be the right choice for everyone. Steve Hannah, created a pretty cool set of tools to map POJO’s (plain old Java objects) to JSON structures by using compile time object mapping. This eliminates the costs/issues of reflection while still delivering a programming experience that is on par with the one we get from Java SE webservice mappings.\nSteve wrote a\npretty thorough tutorial\non this as well as a webcast posted below.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/json-to-pojo-mapping/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/json-to-pojo-mapping/json-to-pojo-mapping-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/json-to-pojo-mapping/json-to-pojo-mapping-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWhile the\u003cbr\u003e\n\u003ca href=\"/how-do-i---access-remote-webservices-perform-operations-on-the-server.html\"\u003e\u003cbr\u003e\nwebservice wizard\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nin Codename One is pretty useful for many things it still requires a proxy and Servlet container which might not be the right choice for everyone. Steve Hannah, created a pretty cool set of tools to map POJO’s (plain old Java objects) to JSON structures by using compile time object mapping. This eliminates the costs/issues of reflection while still delivering a programming experience that is on par with the one we get from Java SE webservice mappings.\u003c/p\u003e","title":"JSON To Pojo Mapping"},{"content":"\nBuilding enterprise mobile apps can be pretty challenging especially when dealing with rapid changes, prototyping and corporate development requirements.\nOne of the tools that has really revolutionized this field is Jenkins and related CI tools that allow developers to instantly track failures back to a specific revision of their code commits with respect to QA work.\nCodename One was essentially built for continuous integration since our build servers are effectively a building block for such an architecture. However, there are several problems with that the first of which is the limitation of server builds. If all users would start sending builds with every commit our servers would instantly become unusable due to the heavy load. To circumvent this we are now introducing CI support but only on the Enterprise level which allows us to stock more servers to cope with the rise in demand related to the feature.\nTo integrate with any CI solution just use our standard Ant targets such as\nbuild-for-android-device\n, build-for-iphone-device etc. Normally, this would be a problem since the build is sent but since it isn’t blocking you wouldn’t get the build result and wouldn’t be able to determine if the build passed or failed. To enable this just edit the build XML and add the attribute automated=\u0026ldquo;true\u0026rdquo; to the codeNameOne tag in the appropriate targets. This will deliver a result.zip file under the dist folder containing the binaries of a successful build. It will also block until the build is completed. This should be pretty easy to integrate with any CI system together with our\nautomated testing solutions\n.\nThis is just a first piece in what would hopefully be a larger piece of the puzzle e.g. running the automated tests on cloud devices using one of the device hosting services available. We will address those pieces based on demand/requirements from our enterprise users.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — December 8, 2014 at 3:40 pm (permalink) Anonymous says:\nThanks, this is a great addition to Codename One, any chances it will have some basic support to Pro users ?\nAnonymous — December 9, 2014 at 11:52 am (permalink) Anonymous says:\nThat is unlikely, too much server load.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/continuous-integration/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/continuous-integration/continuous-integration-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/continuous-integration/continuous-integration-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eBuilding enterprise mobile apps can be pretty challenging especially when dealing with rapid changes, prototyping and corporate development requirements.\u003c/p\u003e\n\u003cp\u003eOne of the tools that has really revolutionized this field is Jenkins and related CI tools that allow developers to instantly track failures back to a specific revision of their code commits with respect to QA work.\u003c/p\u003e\n\u003cp\u003eCodename One was essentially built for continuous integration since our build servers are effectively a building block for such an architecture. However, there are several problems with that the first of which is the limitation of server builds. If all users would start sending builds with every commit our servers would instantly become unusable due to the heavy load. To circumvent this we are now introducing CI support but only on the Enterprise level which allows us to stock more servers to cope with the rise in demand related to the feature.\u003c/p\u003e","title":"Continuous Integration"},{"content":"\nI’ve had a lovely time giving a demo of Codename One at\nCodemotion Tel Aviv\n, one of the things that surprised me about the conference is that the sessions are so short (40 minutes) which gives very little time to actually get into code. So to fit both details about Codename One, Demo etc. and an app I had to narrow this down to the most barebone Codename One demo I could think of that could still be valuable.\nEnter Rounder, its a trivial demo of Codename One that just uses the camera to grab a photo and make it into a round photo. Not exactly useful but it shows the usage of graphics, masking and image capture in a trivial app.\nThe full code is posted below and can help you if you are looking into image masking.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — December 2, 2014 at 7:38 am (permalink) Anonymous says:\nIt would be even super if there is a standard image cropping CodenameOne component where we can crop an image by drawing a square/circle frame over the area of the image to crop.\nAnonymous — December 2, 2014 at 3:10 pm (permalink) Anonymous says:\nYou can use subimage for standard crop and code similar to the one above for shaping. I don’t follow the issue here?\nAnonymous — December 3, 2014 at 4:58 am (permalink) Anonymous says:\nHi Shai, its just a suggestion. What I mean is it would be great if there is a standard CodenameOne component utility class where we can use it to crop the image by selecting the area of the photo visually (see: http://www.ajaxshake.com/en…). If its easy for your team to add such a feature in, that would be very useful, just not sure if this feature crosses the boundaries of what CodenameoOne is suppose to offer, but then again, it wouldn’t hurt to exceed those boundaries a little bit more ;).\nAnonymous — December 4, 2014 at 6:07 am (permalink) Anonymous says:\nI think that’s a bit beyond our scope right now. But you can do it as a cn1lib which is the exact reason why we have them: http://www.codenameone.com/…\nAnonymous — December 4, 2014 at 1:13 pm (permalink) Anonymous says:\nThanks Shai, I think I’ll have a go at it a bit later and perhaps contribute the component to the cn1lib when its done. Right now the first thing comes to mind is having 4 corners implemented as transparent circle buttons that serve as anchor points for the clipping square that can be drawn accordingly when being pinched and expanded. What do you think? Or do you think there is an easier approach? I am not sure if this will be efficient to do in CodenameOne. It would be great if you can point me to classes and methods that will be useful to achieve this outcome. Thanks!\nAnonymous — December 5, 2014 at 3:24 am (permalink) Anonymous says:\nYou can check out the code of ImageViewer which does most of this and also implements pinching/panning etc.\nPersonally I’d just have an image viewer in a layered layout and place a styled overlay for the cropped area with a \u0026ldquo;Crop\u0026rdquo; button below. When the user presses the crop just do it based on the current state of the ImageViewer. The main challenge might be some changes you might need from the image viewer to get its current state.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/round-at-codemotion/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/round-at-codemotion/round-at-codemotion-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/round-at-codemotion/round-at-codemotion-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve had a lovely time giving a demo of Codename One at\u003cbr\u003e\n\u003ca href=\"http://telaviv.codemotionworld.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nCodemotion Tel Aviv\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, one of the things that surprised me about the conference is that the sessions are so short (40 minutes) which gives very little time to actually get into code. So to fit both details about Codename One, Demo etc. and an app I had to narrow this down to the most barebone Codename One demo I could think of that could still be valuable.\u003c/p\u003e","title":"Round At Codemotion"},{"content":"\nOne of the problems in cross platform development is availability of functionality on one platform that is missing on another. Case in point sending an SMS message.\nAndroid, Blackberry \u0026amp; J2ME support sending SMS’s in the background without showing the user anything. They even support a form of intercepting incoming SMS’s to one degree or another (but that’s rather problematic).\niOS \u0026amp; Windows Phone just don’t have that ability, the best they can offer is to launch the native SMS app with your message already in that app.\nUnfortunately our sendSMS API ignored that difference and simply worked interactively on iOS/Windows Phone while sending in the background for the other platforms.\nIn the next update we will add the API getSMSSupport which will return one of the following options:\nSMS_NOT_SUPPORTED – for desktop, tablet etc.\nSMS_SEAMLESS – sendSMS will not show a UI and will just send in the background\nSMS_INTERACTIVE – sendSMS will show an SMS sending UI\nSMS_BOTH – sendSMS can support both seamless and interactive mode, this currently only works on Android\nAnd we updated the sendSMS method to: sendSMS(String phoneNumber, String message, boolean interactive)\nThe last argument will be ignored unless SMS_BOTH is returned from\ngetSMSSupport\nat which point you would be able to choose one way or the other. The default behavior (when not using that flag) is the background sending which is the current behavior on Android.\n**\nCustomizing Commands In Runtime\n**\nCommands are abstracted so we can integrate deeply into the native platform. E.g. the default behavior on Android is to add commands to the action bar which is what we would assume in the case of Android.\nIf commands are drawn by us and not native (e.g. if you use the side menu bar or running on iOS etc.) you can easily customize the style of the commands using the \u0026ldquo;TouchCommand\u0026rdquo; and \u0026ldquo;Command\u0026rdquo; UIID’s. However, what happens when you want one command to have a different style (e.g. for a delete command). There are many ways to solve this especially with the SideMenuBar where you can use a custom component or quite a few other features. However, none of them are trivial.\nTo solve that we added the ability to assign a UIID to a command which will be applied to the element if applicable, just use:\nform.getMenuBar().setCommandUIID(cmd, \u0026quot;MyUIID\u0026quot;);\nThis will work in runtime and should implicitly refresh the UI.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — November 27, 2014 at 5:37 am (permalink) Anonymous says:\nHey Shai, great features! I just want to know if its possible to have one form to present a component in a side menu, and another form to have the native action bar to present the commands?\nAnonymous — November 28, 2014 at 4:18 pm (permalink) Anonymous says:\nYou can have a regular title bar without the side menu for a form if you don’t add too many commands. However, it won’t be an action bar on Android since that is overriden by the side menu and the override is global.\nThis isn’t trivial since commands need to be routed in a very different way to work with the action bar.\nAnonymous — November 29, 2014 at 12:28 am (permalink) Anonymous says:\nNice one.\nIs it possible to intercept sms in those possible platform using codenameone?\nAnonymous — November 29, 2014 at 3:31 am (permalink) Anonymous says:\nOnly thru native code. Its too different.\nAlso Android is changing the way in which it intercepts SMS so its not really useful as it was before.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/sms-custom-commands/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/sms-custom-commands/sms-custom-commands-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/sms-custom-commands/sms-custom-commands-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the problems in cross platform development is availability of functionality on one platform that is missing on another. Case in point sending an SMS message.\u003c/p\u003e\n\u003cp\u003eAndroid, Blackberry \u0026amp; J2ME support sending SMS’s in the background without showing the user anything. They even support a form of intercepting incoming SMS’s to one degree or another (but that’s rather problematic).\u003c/p\u003e\n\u003cp\u003eiOS \u0026amp; Windows Phone just don’t have that ability, the best they can offer is to launch the native SMS app with your message already in that app.\u003c/p\u003e","title":"SMS \u0026 Custom Commands"},{"content":"\nAs\nwe wrote before\nour new Garbage Collector is designed for amazing speed an never locks, this worked really well for most cases but we started running into weird crashes that took us deep into the seemingly simple GC code and exposed flaw in our \u0026ldquo;no locking\u0026rdquo; approach. It seems that our assumption that we can just mark all the static objects was flawed since a thread might mutate the static (global) object while the GC is running.\nSo we ended up creating a rather elaborate patch that marks the statics over again when cycling over all the threads. This slows the GC thread slightly but should have no impact on app performance.\nWe also introduced new support for the Lollipop action bar and some other cool new features. As part of that change we will soon start building Android apps with target set to API level 21. One of the reasons we held back on that change was that some code relied on the older version and we didn’t want to break that code, if you notice things acting differently in your builds please let us know. Notice that this means that the target SDK not the minimum SDK is 21 hence everything should still work all the way back to cupcake.\nTo customize the colors of the ActionBar on Lollipop define a colors.xml file in the native/android directory of your project. It should look like this:\nWe considered adding this as a build argument but there are a few more customizations Google allows and this might just become painful to maintain as a build argument.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/static-garbage-lollipop/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/static-garbage-lollipop/static-garbage-lollipop-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/static-garbage-lollipop/static-garbage-lollipop-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAs\u003cbr\u003e\n\u003ca href=\"https://www.voxxed.com/blog/2014/10/beating-the-arc/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nwe wrote before\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nour new Garbage Collector is designed for amazing speed an never locks, this worked really well for most cases but we started running into weird crashes that took us deep into the seemingly simple GC code and exposed flaw in our \u0026ldquo;no locking\u0026rdquo; approach. It seems that our assumption that we can just mark all the static objects was flawed since a thread might mutate the static (global) object while the GC is running.\u003c/p\u003e","title":"Static Garbage \u0026 Lollipop"},{"content":"\nI’ve talked with many end users about their badly written apps\ngrievances\nand I’ve come to the conclusion that it isn’t a matter of native vs. cross platform or even HTML. Its a frustration issue, driven by unintuitive apps (hidden gestures etc.) and slow performance.\nThe slow performance bit is the most misunderstood, there is a \u0026ldquo;feeling\u0026rdquo; of sluggishness that people complain about but when users complain about performance its usually not related to that but rather something far more mundane… When users complain about performance its often over the infinite rotating wheel covering the entire UI (InfiniteProgress dialog in Codename One), which makes them stand around like idiots waiting for their phone to let them touch it again!\nThis is annoying, frustrating and I can name quite a few native apps that do this for routine data!\nWhen we added the InfiniteProgress dialog it was intended for use only with truly blocking operations e.g. login. However, looking back I can see that we too abused this capability in our demos and this might have inspired some developers to do the same.\nOne of the advantages native apps have is the ability to cache everything, we can always show locally cached data and fetch in the background. We can indicate the data is stale in some way or that we haven’t connected when working with live data but we shouldn’t block the user when possible. You can do something trivial to indicate progress e.g.:\nThis is naturally trivial but we can go much further than this by caching data locally and writing code that works seamlessly when running online/offline. Classes such as\nURLImage\nand ImageDownloadService can become very handy since they seamlessly handle such cases.\nYou can display a \u0026ldquo;stale\u0026rdquo; indicator on top of a component to show that you are in offline mode or that the component contains changes that weren’t yet synchronized to the server, a trick we sometimes do is to place an InfiniteScroll on top of a component to indicate that it is being synchronized. Its important not to overdo this since the InfiniteScroll triggers repaints that will slow the responsiveness of your application!\nE.g:\nEven if your application is very server bound, you can show the last UI forms from the last server connection. This is crucial since often a user would check his device to see the last thing that was open and if the application was suspended since the last run he wouldn’t like to restart the process of digging deeper into the device.\nThis isn’t a new concept, the Palm Pilot was remarkably successful thanks to its amazing performance despite having relatively weak hardware even compared to its contemporaries. Palm demanded that the software act like hardware, when you press a physical button you expect instant gratification and they wanted apps to act in the same way (admittedly apps at that time usually didn’t do networking).\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nJavier Anton — August 17, 2020 at 8:15 am (permalink) Javier Anton says:\nI will add here my 2 cents… blocking the UI of a BrowserComponent will result in the underlying JS being stopped by Safari. So it is very bad to block a Form containing a BrowserComponent on iOS\nIt has taken me a long time to realise this… and from my own tests I can see that Apple has restricted the bg JS even more recently\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/dont-block-the-ui/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/dont-block-the-ui/dont-block-the-ui-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/dont-block-the-ui/dont-block-the-ui-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve talked with many end users about their badly written apps\u003c/p\u003e\n\u003cp\u003egrievances\u003c/p\u003e\n\u003cp\u003eand I’ve come to the conclusion that it isn’t a matter of native vs. cross platform or even HTML. Its a frustration issue, driven by unintuitive apps (hidden gestures etc.) and slow performance.\u003c/p\u003e\n\u003cp\u003eThe slow performance bit is the most misunderstood, there is a \u0026ldquo;feeling\u0026rdquo; of sluggishness that people complain about but when users complain about performance its usually not related to that but rather something far more mundane… When users complain about performance its often over the infinite rotating wheel covering the entire UI (InfiniteProgress dialog in Codename One), which makes them stand around like idiots waiting for their phone to let them touch it again!\u003c/p\u003e","title":"Don't Block The UI"},{"content":"\nThe\nlast time we talked about the EDT\nwe covered some of the basic ideas, such as call serially etc. We left out two major concepts that are somewhat more advanced.\n**\nInvoke And Block\n**\nWhen we write typical code in Java we like that code to be in sequence as such:\ndoOperationA();\ndoOperationB();\ndoOperationC();\nThis works well normally but on the EDT it might be a problem, if one of the operations is slow it might slow the whole EDT (painting, event processing etc.). Normally we can just move operations into a separate thread e.g.:\ndoOperationA();\nnew Thread() {\npublic void run() {\ndoOperationB();\n}\n}).start();\ndoOperationC();\nUnfortunately, this means that operation C will happen in parallel to operation C which might be a problem… E.g. instead of using operation names lets use a more \u0026ldquo;real world\u0026rdquo; example:\nupdateUIToLoadingStatus();\nreadAndParseFile();\nupdateUIWithContentOfFile();\nNotice that the first and last operations must be conducted on the EDT but the middle operation might be really slow!\nSince updateUIWithContentOfFile needs readAndParseFile to be before it doing the new thread won’t be enough. Our automatic approach is to do something like this:\nupdateUIToLoadingStatus(); new Thread() { public void run() { readAndParseFile(); updateUIWithContentOfFile(); } }.start(); But updateUIWithContentOfFile should be executed on the EDT and not on a random thread. So the right way to do this would be something like this:\nupdateUIToLoadingStatus(); new Thread() { public void run() { readAndParseFile(); Display.getInstance().callSerially(new Runnable() { public void run() { updateUIWithContentOfFile(); } }); } }.start(); This is perfectly legal and would work reasonably well, however it gets complicated as we add more and more features that need to be chained serially after all these are just 3 methods!\nInvoke and block solves this in a unique way you can get almost the exact same behavior by using this:\nupdateUIToLoadingStatus(); Display.getInstance().invokeAndBlock(new Runnable() { public void run() { readAndParseFile(); } }); updateUIWithContentOfFile(); Invoke and block effectively blocks the current EDT in a legal way. It spawns a separate thread that runs the run() method and when that run method completes it goes back to the EDT. All events and EDT behavior still works while invokeAndBlock is running, this is because invokeAndBlock() keeps calling the main thread loop internally.\nNotice that this comes at a slight performance penalty and that nesting invokeAndBlocks (or over using them) isn’t recommended. However, they are very convenient when working with multiple threads/UI.\n**\nWhy Would I Invoke callSerially when I’m on the EDT already?\n**\nWe discussed callSerially in the previous post but one of the misunderstood topics is why would we ever want to invoke this method when we are still on the EDT. The original version of LWUIT used to throw an IllegalArgumentException if callSerially was invoked on the EDT since it seemed to make no sense.\nHowever, it does make some sense and we can explain that using an example. E.g. say we have a button that has quite a bit of functionality tied to its events e.g.:\n1. A user added an action listener to show a Dialog.\n2. A framework the user installed added some logging to the button.\n3. The button repaints a release animation as its being released.\nHowever, this might cause a problem if the first event that we handle (the dialog) might cause an issue to the following events. E.g. a dialog will block the EDT (using invokeAndBlock), events will keep happening but since the event we are in \u0026ldquo;already happened\u0026rdquo; the button repaint and the framework logging won’t occur. This might also happen if we show a form which might trigger logic that relies on the current form still being present.\nOne of the solutions to this problem is to just wrap the action listeners body with a callSerially. In this case the callSerially will postpone the event to the next cycle (loop) of the EDT and let the other events in the chain complete. Notice that you shouldn’t use this normally since it includes an overhead and complicates application flow, however when you run into issues in event processing I suggest trying this to see if its the cause.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — March 2, 2015 at 7:34 pm (permalink) Anonymous says:\nHi,\njust want to inform that this page is containing typo mistake..which may lead to wrong assumption for new developers..\nIts here:\n\u0026ldquo;Unfortunately, this means that operation C will happen in parallel to operation C which might be a problem…\u0026rdquo;\nI think one of the C should be B\nPlease don’t take it wrong, just wanted to make CN1 cleanNshine.\nThanks\nAnonymous — March 3, 2015 at 2:02 am (permalink) Anonymous says:\nThanks for the catch!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/callserially-the-edt-invokeandblock-part-2/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/callserially-the-edt-invokeandblock-part-2/callserially-the-edt-invokeandblock-part-2-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/callserially-the-edt-invokeandblock-part-2-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/callserially-the-edt-invokeandblock-part-2/callserially-the-edt-invokeandblock-part-2-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eThe\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/blog/callserially-the-edt-invokeandblock-part-1\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nlast time we talked about the EDT\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nwe covered some of the basic ideas, such as call serially etc. We left out two major concepts that are somewhat more advanced.\u003c/p\u003e\n\u003cp\u003e**\u003cbr\u003e\nInvoke And Block\u003cbr\u003e\n**\u003c/p\u003e\n\u003cp\u003eWhen we write typical code in Java we like that code to be in sequence as such:\u003c/p\u003e\n\u003cp\u003edoOperationA();\u003c/p\u003e\n\u003cp\u003edoOperationB();\u003c/p\u003e\n\u003cp\u003edoOperationC();\u003c/p\u003e\n\u003cp\u003eThis works well normally but on the EDT it might be a problem, if one of the operations is slow it might slow the whole EDT (painting, event processing etc.). Normally we can just move operations into a separate thread e.g.:\u003c/p\u003e","title":"CallSerially The EDT \u0026 InvokeAndBlock (Part 2)"},{"content":"\nChen’s been busy with some customers on a feature that is often requested:\nmailbox\nlike swipes. This effectively allows you to swipe a component to the side in order to reveal capabilities underneath e.g. edit, delete etc.\nUsing this capability is really trivial just use something like a a MultiButton and place it in a SwipeableContainer with the bottom Container which includes the various actions as such:\nSwipeableContainer swip = new SwipeableContainer(bottom, top);\nYou then add the swipeable container probably into a BoxLayout Y container such as in this case, see the demo video below.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — November 5, 2014 at 10:47 am (permalink) Anonymous says:\nNice feature, I was looking for this feature for awhile 🙂\nHowever from the video it looks like you need to swipe from left, to right.. But IOS 7 is default swipe from right to left, is it possible to change direction 🙂 ?\nAnonymous — November 5, 2014 at 12:36 pm (permalink) Anonymous says:\nYou can swipe in both directions, it was added after Chen made the video.\nAnonymous — November 5, 2014 at 6:53 pm (permalink) Anonymous says:\nPerfect timing. We have a need for something like this to support an app feature currently in our dev queue. This will allow us to get the feature done a little quicker – thanks!\nAnonymous — November 20, 2014 at 8:20 pm (permalink) Anonymous says:\nThanks for doing this as you have promised. I love that feature. Will this work in list\nAnonymous — November 21, 2014 at 3:23 am (permalink) Anonymous says:\nThis won’t work on a List because of the way the list is built.\nAnonymous — December 1, 2014 at 4:36 pm (permalink) Anonymous says:\nWhere would I find the JavaDocs for this new class?\nAnonymous — December 2, 2014 at 5:04 am (permalink) Anonymous says:\nIts not yet in the javadoc but should appear in the IDE code completion with docs.\nAnonymous — December 2, 2014 at 8:42 am (permalink) Anonymous says:\nI have Netbeans 8.0.2 and codename one plugin 1.0.80 but Netbeans does not recognize the SwipeableContainer. Even if I copy-paste the code and fix the imports. Do I need to manually update to get the feature?\nAnonymous — December 2, 2014 at 3:10 pm (permalink) Anonymous says:\nGo to the project properties in the Codename One section and press the update client libraries button.\nAnonymous — December 2, 2014 at 3:57 pm (permalink) Anonymous says:\nThanks for the reply. I misunderstood the instructions at first. I only right-clicked the project and selected Refresh libs. I now understand that applies to downloaded CN1 libs.\nAnonymous — December 3, 2014 at 5:43 am (permalink) Anonymous says:\nIt works! This is a really great feature.\nAnonymous — December 5, 2014 at 7:40 am (permalink) Anonymous says:\nHi !\nWhere I can find the code ?\nThank\nAnonymous — December 6, 2014 at 1:58 pm (permalink) Anonymous says:\nAll our code is available in our google code project here: http://code.google.com/p/co…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/side-swipe/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/side-swipe/side-swipe-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/side-swipe/side-swipe-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eChen’s been busy with some customers on a feature that is often requested:\u003cbr\u003e\n\u003ca href=\"http://www.mailboxapp.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nmailbox\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nlike swipes. This effectively allows you to swipe a component to the side in order to reveal capabilities underneath e.g. edit, delete etc.\u003c/p\u003e\n\u003cp\u003eUsing this capability is really trivial just use something like a a MultiButton and place it in a SwipeableContainer with the bottom Container which includes the various actions as such:\u003c/p\u003e","title":"Side Swipe"},{"content":"\nRam (the developer of\nyhomework\n), wanted to improve his ad revenue on Android/iOS thru interstitial (full screen) ads and integrated those using native interfaces. Kindly enough he contributed these changes back and Chen packaged this as a cn1lib which you can now easily use to add support for\nfull screen ads to your Android/iOS apps\n.\nOn a different subject a long time RFE has been the ability to customize the tabs using a more powerful API. The main blocker for that has been the hardcoding of Buttons (or really radio buttons) as tabs in the Tabs component.\nWith the upcoming version of Codename One you will be able to replace the usage of Button with just about anything by overriding a set of protected methods in the Tabs component. These effectively allow the Tabs class to understand the structure of your potentially complex class and communicate the requirements of the component. In the relatively simplistic implementation below I just used a layered layout to place a close button in the right side of every tab. This is code I used in the kitchen sink demo to test this effect.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/admob-interstitial-ads-supertabs/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/admob-interstitial-ads-supertabs/admob-interstitial-ads-supertabs-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/admob-interstitial-ads-supertabs/admob-interstitial-ads-supertabs-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eRam (the developer of\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/featured-yhomework.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nyhomework\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n), wanted to improve his ad revenue on Android/iOS thru interstitial (full screen) ads and integrated those using native interfaces. Kindly enough he contributed these changes back and Chen packaged this as a cn1lib which you can now easily use to add support for\u003cbr\u003e\n\u003ca href=\"https://code.google.com/p/admobfullscreen-codenameone/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nfull screen ads to your Android/iOS apps\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n.\u003c/p\u003e\n\u003cp\u003eOn a different subject a long time RFE has been the ability to customize the tabs using a more powerful API. The main blocker for that has been the hardcoding of Buttons (or really radio buttons) as tabs in the Tabs component.\u003c/p\u003e","title":"Admob Interstitial Ads \u0026 Supertabs"},{"content":"\nOne of the nice effects in the Android material design is the morphing effect where an element from the previous form (activity) animates to become a different component on a new activity. We’ve had a morph effect in the Container class since the original beta of Codename One but it didn’t work as a transition between forms and didn’t allow for multiple separate components to transition at once.\nTo support this behavior we are adding a MorphTransition class which will be available in the next Codename One update, it allows you to use this effect without much of a hassle. To demonstrate this we made a few changes to the Kitchen Sink demo where we added a Label containing the icon/name of the demo to the top of each demo form, this allows us to morph the icon being clicked into that label. See the video here:\nSince the transition is created before the form exists we can’t reference explicit components within the form when creating the morph transition (in order to indicate which component becomes which) so we need to refer to them by name. This means we need to use setName(String) on the components in the source/destination forms so the transition will be able to find them.\nAs you can see from the code above incorporating the morph transition is pretty trivial, we just added a new Label to which the button from the demo will morph and gave it a hardcoded name. Notice we needed to give the demo button a dynamic name based on the demo name. The reason is that in the specific demo there will be only one target but in the main form there are multiple demos.\nThen we installed the new transition on the main form and on the demo form, notice that we used the same order of from-to in both cases. The transition will play in reverse when going back so the from-to will be implicitly reversed by the back command.\nAlso notice the structure of the MorphTransition command, create accepts the time in milliseconds (3000 for a slow transition) then you can chain as many morph commands as you want (one for each component pair) to indicate which component should become which.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — October 27, 2014 at 4:31 pm (permalink) Anonymous says:\nThat’s very neat. Nice effect.\nAnonymous — November 1, 2014 at 1:27 pm (permalink) Anonymous says:\nGreat one! you guys are doing a great job keeping up with everything that matters.\nAnonymous — November 27, 2014 at 10:54 pm (permalink) Anonymous says:\nKool\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/mighty-morphing-components/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/mighty-morphing-components/mighty-morphing-components-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/mighty-morphing-components/mighty-morphing-components-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the nice effects in the Android material design is the morphing effect where an element from the previous form (activity) animates to become a different component on a new activity. We’ve had a morph effect in the Container class since the original beta of Codename One but it didn’t work as a transition between forms and didn’t allow for multiple separate components to transition at once.\u003c/p\u003e","title":"Mighty Morphing Components"},{"content":"\nApple Just announced they will mandate 64 bit for all new submissions starting February 2015, luckily we are very prepared for that and we already support 64 bit builds in our new VM.\nThis is a huge triumph for the architecture of our new VM which is very resilient to changes Apple might make in the future thanks to its pure C architecture. Our old XMLVM based approach is limited in that regard since it relies on the Boehm garbage collector which in turn relies on low level assembler and memory layouts heavily. Our new VM is both faster and more portable; now its also open source!\nIn fact, the only portion that posed a slight challenge was porting the native libzbar which we use for QR/barcode reading. Everything related to the VM itself ported easily and works with the new high resolution devices as well as arm64.\nIf you want to try your app with the new VM just submit a build with the build argument ios.newVM=true. We are now actively seeking bug reports, crashes and compilation errors with the new VM in order to be able to transition it into the default VM by January. If you get an error please reproduce it as a standalone project we can compile and attach it to an issue in the issue tracker describing the problem.\nWe just committed the current beta of the new VM into SVN, its still not production grade but its now open source under the GPL + Class Path Exception. You can see the source under the VM directory of our SVN tree where you should see two projects. One is the bytecode translator and the other is the Java API implementation.\nBasically the architecture is very simple, it statically parses the bytecode using ASM and generates C source/header files that pretty much represent the bytecode as it is in Java. It has a rudimentary optimizer but nothing too shabby.\nThe main focus in the future would be removing some of the stack operations in the bytecode by possibly converting the bytecode on the fly to something that would be more efficient on the device. We will probably stay with the stack based approach rather than go completely register based like DEX has for two major reasons:\n1. Similarity to the source bytecode which makes it relatively simple to locate the relevant section.\n2. The stack based approach is very powerful when combined with our GC so we will need it for the GC to work correctly.\nOn a slightly unrelated note, IAP version 3.0 is now up on the build servers. We made a few corrections to the post from last week containing a discussion of the changes needed so if you use it please\ncheck out the revised post\n.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — November 10, 2014 at 8:13 am (permalink) Anonymous says:\nI got an error when I tried to build with the new vm\nAnonymous — November 26, 2014 at 8:14 am (permalink) Anonymous says:\nCan you post on the forum with more details e.g. build error log?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/64-bit-oss-vm/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/64-bit-oss-vm/64-bit-oss-vm-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"64bit\" loading=\"lazy\" src=\"/blog/64-bit-oss-vm/64-bit-oss-vm-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eApple Just announced they will mandate 64 bit for all new submissions starting February 2015, luckily we are very prepared for that and we already support 64 bit builds in our new VM.\u003c/p\u003e\n\u003cp\u003eThis is a huge triumph for the architecture of our new VM which is very resilient to changes Apple might make in the future thanks to its pure C architecture. Our old XMLVM based approach is limited in that regard since it relies on the Boehm garbage collector which in turn relies on low level assembler and memory layouts heavily. Our new VM is both faster and more portable; now its also open source!\u003c/p\u003e","title":"64 bit \u0026 OSS VM"},{"content":"\nWe last explained some of the concepts behind the EDT in 2008 so its high time we wrote about it again, there is a section about it in the developer guide as well as in the courses on Udemy but since this is the most important thing to understand in Codename One it bares repeating.\nOne of the nice things about the EDT is that many of the concepts within it are similar to the concepts in pretty much every other GUI environment (Swing/FX, Android, iOS etc.). So if you can understand this explanation this might help you when working in other platforms too.\nCodename One can have as many threads as you want, however there is one thread created internally in Codename One named \u0026ldquo;EDT\u0026rdquo; for Event Dispatch Thread. This name doesn’t do the thread justice since it handles everything including painting etc.\nYou can imagine the EDT as a loop such as this:\nwhile(codenameOneRunning) {\nperformEventCallbacks();\nperformCallSeriallyCalls();\ndrawGraphicsAndAnimations();\nsleepUntilNextEDTCycle();\n}\nThe general rule of the thumb in Codename One is: Every time Codename One invokes a method its probably on the EDT (unless explicitly stated otherwise), every time you invoke something in Codename One it should be on the EDT (unless explicitly stated otherwise).\nThere are a few notable special cases:\n1. NetworkManager/ConnectionRequest – use the network thread internally and not the EDT. However they can/should be invoked from the EDT.\n2. BrowserNavigationCallback – due to its unique function it MUST be invoked on the native browser thread.\n3. Displays invokeAndBlock/startThread – create completely new threads.\nOther than those pretty much everything is on the EDT. If you are unsure you can use the Display.isEDT method to check whether you are on the EDT or not.\n**\nEDT Violations\n**\nYou can violate the EDT in two major ways:\n1. Call a method in Codename One from a thread that isn’t the EDT thread (e.g. the network thread or a thread created by you).\n2. Do a CPU intensive task (such as reading a large file) on the EDT – this will effectively block all event processing, painting etc. making the application feel slow.\nLuckily we have a tool in the simulator: the EDT violation detection tool. This effectively prints a stack trace to suspect violations of the EDT. Its not fool proof and might land your with false positives but it should help you with some of these issues which are hard to detect.\nSo how do you prevent an EDT violation?\nTo prevent abuse of the EDT thread (slow operations on the EDT) just spawn a new thread using either new Thread(), Display.startThread or invokeAndBlock (more on that later).\nThen when you need to broadcast your updates back to the EDT you can use callSerially or callSeriallyAndWait.\n**\nCallSerially\n**\ncallSerially invokes the run() method of the runnable argument it receives on the Event Dispatch Thread. This is very useful if you are on a separate thread but is also occasionally useful when we are on the EDT and want to postpone actions to the next cycle of the EDT (more on that next time).\ncallSeriallyAndWait is identical to call serially but it waits for the callSerially to complete before returning. For obvious reasons it can’t be invoked on the EDT.\nIn the second part of this mini tutorial I will discuss invokeAndBlock and why we might want to use callSerially when we already are on the EDT.\n**\nUpdate:\n**\nYou can read part 2 of this post\nhere\n.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/callserially-the-edt-invokeandblock-part-1/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/callserially-the-edt-invokeandblock-part-1/callserially-the-edt-invokeandblock-part-1-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/callserially-the-edt-invokeandblock-part-1-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/callserially-the-edt-invokeandblock-part-1/callserially-the-edt-invokeandblock-part-1-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eWe last explained some of the concepts behind the EDT in 2008 so its high time we wrote about it again, there is a section about it in the developer guide as well as in the courses on Udemy but since this is the most important thing to understand in Codename One it bares repeating.\u003c/p\u003e\n\u003cp\u003eOne of the nice things about the EDT is that many of the concepts within it are similar to the concepts in pretty much every other GUI environment (Swing/FX, Android, iOS etc.). So if you can understand this explanation this might help you when working in other platforms too.\u003c/p\u003e","title":"CallSerially The EDT \u0026 InvokeAndBlock (Part 1)"},{"content":"\n**\nUpdated:\n**\nOriginally this article referred to a system based on Display.setProperty for distinguishing consumable types. This turned out to be an issue in beta testing and was replaced with either a naming convention or build argument.\nGoogle announced a couple of weeks ago that Android’s In App Purchase 2.x API will be retired soon and all code should be migrated to version 3.0 of the API. Unfortunately version 3.0 is a big departure from version 2.0 which we currently support and its difficult for us to support both so unlike the normal case where we try to maintain compatibility with build arguments we will make a clean break to 3.0.\nImportant: if you have a project that relies on in-app-purchase and you are about to make a release we will flip the switch in one week from now! This means that you will have to migrate version 3.0 if you build a version next week, so if you have a release pending you might want to get it out ASAP.\nThe Codename One purchase API remains unchanged and will work in exactly the same way, however due to integration with the way Google handles various things you might need to tune this a bit:\n1. You must have the android.licenseKey build hint set or the build will fail. You can get the license key from the Services \u0026amp; API section in the Google play store.\n2. In the 3.0 API products are consumable by default, if you want a product to be non-consumable you will need to explicitly declare it either by making the SKU end with the word\nnonconsume (e.g. MySKU001_nonconsume) or by setting the build argument android.nonconsumable=itema,itemb,itemc\nApple explains the difference between consumable/non-consumable products as such:\n**\nConsumable products\n**\n– Items that get used up over the course of running your app. Examples include minutes for a Voice over IP app and one-time services such as voice transcription.\n**\nNon-consumable products\n**\n– Items that remain available to the user indefinitely on all of the user’s devices. They’re made available to all of the user’s devices. Examples include content, such as books and game levels, and additional app functionality.\n3. With the version 3 support we now have subscriptions on Android. However, Google’s API doesn’t allow unsubscribing from code so that functionality isn’t available. Users have the ability to unsubscribe via the portal.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/migrating-to-androids-in-app-purchase-30/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/migrating-to-androids-in-app-purchase-30/migrating-to-androids-in-app-purchase-30-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Google Play In-App-Purchase\" loading=\"lazy\" src=\"/blog/migrating-to-androids-in-app-purchase-30/migrating-to-androids-in-app-purchase-30-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e**\u003cbr\u003e\nUpdated:\u003cbr\u003e\n**\u003cbr\u003e\nOriginally this article referred to a system based on Display.setProperty for distinguishing consumable types. This turned out to be an issue in beta testing and was replaced with either a naming convention or build argument.\u003c/p\u003e\n\u003cp\u003eGoogle announced a couple of weeks ago that Android’s In App Purchase 2.x API will be retired soon and all code should be migrated to version 3.0 of the API. Unfortunately version 3.0 is a big departure from version 2.0 which we currently support and its difficult for us to support both so unlike the normal case where we try to maintain compatibility with build arguments we will make a clean break to 3.0.\u003c/p\u003e","title":"Migrating To Androids In-App-Purchase 3.0"},{"content":"\nI just published a\nLinkedIn article\ndiscussing the financials of a JavaOne booth, if you are a startup/vendor looking at conference booths I hope this provides some much needed transparency. I know that when we researched the issue the lack of information was very problematic.\niOS 8 introduced a few regressions into Codename One which should now be mostly resolved. This is mostly due to Apple discarding support for some features that were previously deprecated but they didn’t offer any alternative for those features which is a bit of a problem. As a result of this the behavior of the picker component is somewhat different on iPhone’s running iOS 8.\nOn an unrelated note we finished a process of migrating our Mac servers to Mavericks which is hugely important since it will allows us to migrate to xcode 6 for the new VM builds.\nWe also moved all our AWS hosted servers to\nDigital Ocean\n(notice that is a reference link that will give you some credit to try it), generally we found them to be more affordable and FAR easier to manage than AWS which is ridiculously obtuse.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — October 16, 2014 at 12:01 am (permalink) Anonymous says:\nHey Shai, can’t seem to find your article on LinkedIn… Do you have a link?\nAnonymous — October 16, 2014 at 9:21 am (permalink) Anonymous says:\nSome changes in the CMS made links almost invisible. Not sure why… The words linkedin article are a link to this: https://www.linkedin.com/pu…\nAnonymous — October 16, 2014 at 2:10 pm (permalink) Anonymous says:\nOh, ok. I was also trying to find it via the CodenameOne group on LinkedIn, but I can only see the posts Chen did (last one was \u0026ldquo;Showcase your app at JavaOne\u0026rdquo; a month ago. You should probably link it there as well for increased visibility!\nAnonymous — October 17, 2014 at 3:06 pm (permalink) Anonymous says:\nHi Shai,\nI will like to ask if Picker component is now working on iOS 8? Is there some code I have to add to my project?\nAnonymous — October 17, 2014 at 10:28 pm (permalink) Anonymous says:\nJust send a new build, no code changes required.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/javaone-booth-ios-8-issues-more/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/javaone-booth-ios-8-issues-more/javaone-booth-ios-8-issues-more-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/javaone-booth-ios-8-issues-more-large-2.jpg\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/javaone-booth-ios-8-issues-more/javaone-booth-ios-8-issues-more-1.jpg\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eI just published a\u003cbr\u003e\n\u003ca href=\"https://www.linkedin.com/pulse/article/20141013104245-87574-is-a-booth-at-javaone-worth-the-expense\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nLinkedIn article\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\ndiscussing the financials of a JavaOne booth, if you are a startup/vendor looking at conference booths I hope this provides some much needed transparency. I know that when we researched the issue the lack of information was very problematic.\u003c/p\u003e\n\u003cp\u003eiOS 8 introduced a few regressions into Codename One which should now be mostly resolved. This is mostly due to Apple discarding support for some features that were previously deprecated but they didn’t offer any alternative for those features which is a bit of a problem. As a result of this the behavior of the picker component is somewhat different on iPhone’s running iOS 8.\u003c/p\u003e","title":"JavaOne Booth, iOS 8 Issues \u0026 More"},{"content":"\nThis is going to be a radically different trip report, we weren’t just talking at Java One this year we were actually presenting with our own booth and would probably do so again next year. Last year we tried to purchase a booth as well but were unable to get in contact with the right person at Oracle before the conference sold out (which was a shame, I understand some pavilion space went for free). This year we were ready though and were able to secure a small space but it turned out to be a great conference to us and we got the word out far/wide. On the right you can check out Chen \u0026amp; Myself at our booth just as it was setup.\nI\nwrote already about our first session on NetBeans day with James Gosling\n, the room was so packed that Steve Hannah couldn’t get in (standing room only).\nIf you haven’t been to San Francisco its truly a unique microcosm within the USA, a beautiful city with painful poverty and noble ideas. Here are some unique pictures that represent that city perfectly in my mind.\nIf you haven’t been to JavaOne in recent years (since it left Moscone) then you need to check out \u0026ldquo;Taylor st. Cafe\u0026rdquo;. Oracle literally closes a portion of Taylor street that passes next to the Hilton and sets up a coffee shop in the middle of the streets (the whole thing is carpeted and perimetered very efficiently). The effect is pretty amazing and on Sunday we had the first \u0026ldquo;official\u0026rdquo; JavaOne party over there which was pretty cool. I spoke with some interesting people and had a blast.\nOn Monday thru Wednesday we spent all day in the booth talking to people and telling them about Codename One, by our estimates we pitched to about 700 different individuals in the 3 pavilion days so we didn’t get to see any sessions other than our own (a first for me at JavaOne). We did get to go to the parties at night if we could drag ourselves after running around pitching all day e.g. on the first night there was an empire of the sun concert. We didn’t know the band beforehand but they were pretty great and gave an amazing show filled with pyrotechnics which were damn impressive.\nSince the booth work was so busy we don’t have that much pictures other than this one taken by Geertjan (on the left you see Chen, Steve Hannah \u0026amp; me), we did give away all of the suitcase load full of shirts and brochures we brought to JavaOne and we also had a raffle to win a Moto 360 smartwatch Geertjan graciously did the name draw among the contestants and Chen handed the watch to the winner, in all the excitement we completely forgot to write down his name or details but we have his picture and the draw below.\nThursday was full with meetings, gift purchasing for the kids and our session. The session was literally in the last time slot at JavaOne and I saluted everyone in attendance for staying until the end. It was a tough session to do since my abstract was flawed and the session had multiple separate premises to it that weren’t clear, I think I handled it reasonably well and people laughed at my stupid jokes which is normally a good sign.\nI did the entire session from my iphone which was a mistake in retrospect since the display preview was too small and the display kept locking the screensaver (which never happened with the ipad), but I wanted to demo Codename One apps running on a real device which was pretty sweet.\nThis post is actually going live from India where I just landed the other day, Namaste.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/javaone-2014-trip-report/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/javaone-2014-trip-report/javaone-2014-trip-report-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/javaone-2014-trip-report-large-16.jpg\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Shai \u0026amp; Chen\" loading=\"lazy\" src=\"/blog/javaone-2014-trip-report/javaone-2014-trip-report-1.jpg\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eThis is going to be a radically different trip report, we weren’t just talking at Java One this year we were actually presenting with our own booth and would probably do so again next year. Last year we tried to purchase a booth as well but were unable to get in contact with the right person at Oracle before the conference sold out (which was a shame, I understand some pavilion space went for free). This year we were ready though and were able to secure a small space but it turned out to be a great conference to us and we got the word out far/wide. On the right you can check out Chen \u0026amp; Myself at our booth just as it was setup.\u003c/p\u003e","title":"JavaOne 2014 Trip Report"},{"content":"\nShortly after introducing\nMirah support for Codename One\n, Steve is back with something that is arguably even more impressive. Over the weekend Steve released a tool called\nCN1ML\nwhich is an HTML subset markup language that allows you to effectively build Codename One UI’s with HTML. This isn’t another embedded webbrowser or HTMLComponent, this is a tool that statically translates HTML syntax into Codename One components. The benefit here is that you can keep all the advantages of using Codename One widgets (portability, performance, customizability etc.) with the HTML like syntax.\nWhen we were at Sun, our manager Yoav Barel was heavily on our case for building exactly that and we effectively convinced him that its not feasible to do this since its too much work. I guess we should have known about Steve back then!\nI think this is a very interesting idea and direction, one of the things I’d really like to see here is proper box model spanning behavior (float etc.) which is very tricky to do in Codename One today. Amazingly this is also very tricky to do natively in iOS/Android so we are all on the same boat…\nJava One We are here in the lovely city of San Francisco and having a blast, we have a pretty amazing announcement to make but until the contract is signed we’ll keep that low key.\nI’ll do a more detailed report on the complete trip, the parties and the booth but for now I’ll leave you with a few pictures I grabbed and some tags.\nNetBeans party, small room crowded like a phone booth with great guys, food and beer NetBeans party left to right: Geertjan Wielenga, Shai Almog (me), Sean Phillips \u0026amp; Jens Deters Our booth just after buildup on Sunday Crowd at our session UGF8907: James Gosling, Robots, the Raspberry Pi and Small Devices The stage our session UGF8907: James Gosling, Robots, the Raspberry Pi and Small Devices. Left to right Chen Fishbein, Shai Almog, James Gosling, José Pereda \u0026amp; Jens Deters Me and James Gosling on stage taken by Chen Fishbein The selfi with James queue stretches down the stage Typical San Francisco: spinning class in the middle of a busy street with loud yelling and pedaling Highlight of the keynote, the kids of devoxxx4kids nailed it Notice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — September 30, 2014 at 11:40 am (permalink) Anonymous says:\nThis is really cool Steve, congratz ! 🙂\nAnonymous — September 30, 2014 at 1:25 pm (permalink) Anonymous says:\nI was wondering if someone would do something like that specially because I’ve seen some apps that converts html5+css+javascript into smartphones apps.\nI’m really glad I found codenameone, specially because everything I found generated apps for Android, and I was searching form something cross plataform oriented. Gladly I found codenameone – I’m still suffering to learn, but I just need to write the app once.\nAs a matter of fact I want to thank Shei, Chen and Eric for this great work, and now, thank Steve for this implementation that will help me a great deal because I’m very used to HTML.\nRegards.\nAnonymous — October 19, 2014 at 10:44 am (permalink) Anonymous says:\nwow steve you are a god. im getting started immediately.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/cn1ml-javaone/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/cn1ml-javaone/cn1ml-javaone-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"CN1ML\" loading=\"lazy\" src=\"/blog/cn1ml-javaone/cn1ml-javaone-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eShortly after introducing\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/blog/mirah-for-codename-one\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nMirah support for Codename One\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, Steve is back with something that is arguably even more impressive. Over the weekend Steve released a tool called\u003cbr\u003e\n\u003ca href=\"http://sjhannah.com/blog/?p=345\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nCN1ML\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nwhich is an HTML subset markup language that allows you to effectively build Codename One UI’s with HTML. This isn’t another embedded webbrowser or HTMLComponent, this is a tool that statically translates HTML syntax into Codename One components. The benefit here is that you can keep all the advantages of using Codename One widgets (portability, performance, customizability etc.) with the HTML like syntax.\u003c/p\u003e","title":"CN1ML \u0026 JavaOne"},{"content":"\nAt JavaOne/Oracle Open World the wristband allows you to attend the \u0026quot;\nappreciation event\n\u0026quot; featuring Aerosmith, Macklemore \u0026amp; Ryan Lewis and Spacehog. Unfortunately Oracle employees don’t get the wristband that allows everyone to attend that event!\nSo I’m personally giving away my wristband and we might get some additional wristband donations to give away to Oracle employees so if you are an Oracle employee just retweet\nour tweet representing this article\nand/or share this via Facebook (publicly) then drop by our booth to log your name/email.\nWe will hold the raffle on Wednesday at 3pm in our booth\nbe sure to be there in order to claim the wristband or we will have to give it to someone else.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/second-annual-wristband-donation-for-oracle-employees/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/second-annual-wristband-donation-for-oracle-employees/second-annual-wristband-donation-for-oracle-employees-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/second-annual-wristband-donation-for-oracle-employees/second-annual-wristband-donation-for-oracle-employees-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAt JavaOne/Oracle Open World the wristband allows you to attend the \u0026quot;\u003cbr\u003e\n\u003ca href=\"https://www.oracle.com/openworld/bands/index.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nappreciation event\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n\u0026quot; featuring Aerosmith, Macklemore \u0026amp; Ryan Lewis and Spacehog. Unfortunately Oracle employees don’t get the wristband that allows everyone to attend that event!\u003c/p\u003e\n\u003cp\u003eSo I’m personally giving away my wristband and we might get some additional wristband donations to give away to Oracle employees so if you are an Oracle employee just retweet\u003cbr\u003e\n\u003ca href=\"https://twitter.com/Codename_One/status/514638244076466177\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nour tweet representing this article\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nand/or share this via Facebook (publicly) then drop by our booth to log your name/email.\u003c/p\u003e","title":"Second Annual Wristband Donation For Oracle Employees"},{"content":"\nOne of our pro users alerted us to an issue with iOS 8 that might trigger a case where apps can’t be installed OTA (Over the air, via QR or email links) and only installed via itunes. We didn’t experience this issue ourselves but it seems to be affecting many developers (not Codename One specific). This is due to caching of package bundle ID’s and he provided some resources here that might be of interest:\nhttps://buildozer.io/ios8\nhttp://stackoverflow.com/questions/25887805/ios-8-gm-cant-install-ipa\nhttp://stackoverflow.com/questions/25772664/enterprise-app-update-distribution-on-ios-8\nhttp://support.hockeyapp.net/discussions/problems/26683-not-able-to-download-apps-ios8-beta-5-autoupdate-manually-etc#comment_34327687\nOn an unrelated subject the\npull to refresh\nfunctionality was a bit uncustomizable up until now, this all changed with the latest release and should now be far more customizable. To replace the icon you can define the theme constant pullToRefreshImage to the right image. To customize the appearance of the text etc. you can now use the PullToRefresh UIID and to customize the text just define the following constants in the localization bundle:\npull.release (defaults to \u0026ldquo;Release to refresh…\u0026rdquo;) \u0026amp; pull.down (defaults to \u0026ldquo;Pull down do refresh…\u0026rdquo;).\nAs you may have noticed we are deep into the last minute JavaOne preparations so everything we do is around that work. During the weekend of Friday the 26th both Chen and myself will be in transit to San Francisco and so we will not be able to address support queries or answer forum questions during that time. During that entire week we will have relatively limited forum presence due to our workload at that time.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — October 7, 2014 at 7:02 pm (permalink) Anonymous says:\nThe solution to the iOS8 issue seems to be to put some random characters into the bundle ID of the plist file. As this is managed by CN1 can you enable this at your end? Its affecting me for my installs as I usually run on Linux and therefore don’t have (or want) iTunes just to install.\nAnonymous — October 7, 2014 at 11:24 pm (permalink) Anonymous says:\nThat is exactly why we have the ios.plistInject build argument.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/ios-8-installs-customizing-the-pull-to-refresh/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/ios-8-installs-customizing-the-pull-to-refresh/ios-8-installs-customizing-the-pull-to-refresh-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/ios-8-installs-customizing-the-pull-to-refresh/ios-8-installs-customizing-the-pull-to-refresh-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of our pro users alerted us to an issue with iOS 8 that might trigger a case where apps can’t be installed OTA (Over the air, via QR or email links) and only installed via itunes. We didn’t experience this issue ourselves but it seems to be affecting many developers (not Codename One specific). This is due to caching of package bundle ID’s and he provided some resources here that might be of interest:\u003c/p\u003e","title":"IOS 8 Installs \u0026 Customizing the Pull To Refresh"},{"content":"\nJavaZone\nis winding down as I’m starting to write this although I’ll probably post this after the videos are up to reference some of the interesting sessions I saw. Unfortunately JavaZone doesn’t post workshop videos so my workshop won’t be available, but frankly it wouldn’t have worked well in video since it was relatively interactive hence there was no presentation flow. You can see the gist of the workshop in the video I posted\na couple of weeks ago\n. The next few paragraphs are about JavaZone itself and the trip, if you want to read about the session highlights just scroll down…\nOn the right you can see a picture of me on the\n\u0026ldquo;Game Of Code\u0026rdquo;\nthrone, its hard to make out the details with my awful Nexus camera but these are actually quite a few real keyboards dyed in silver that are used to form a chair.\nJavaZone started for me with the great\nspeakers dinner, got to meet lots of great guys and eat some of the great JavaZone fair which deserves a paragraph of its own…\nThe real star of JavaZone is the food though, its hard to say this but I finally think JavaZone broke me… There was literally too much and it was all good. I totally pigged out!\nJavaZone doesn’t have meals it has continuous food integration (or continuous delivery, frankly it felt like a waterfall). This effectively means that there are no lunches/dinners. Food starts pouring out around 10 and just doesn’t stop until 4-6pm, so you can just walk around all day picking something here and there whenever you feel like it. Just to give you a sense of the available foods:\nPizza, freshly made check out the photo. Some people say that there is no such a thing as bad pizza, I strongly disagree. But this was good pizza which is pretty amazing for conference fair.\nOther than that:\nSushi, Burgers, Sausages (in bun), Tacos with choice of meats, Cababs with lafas (type of pita), Indian style curries and rice, local foods (shrimps, mushrooms, potatoes), ice cream bar, soft serve icecream, mini-cupcakes, smoothy stand, juice bar, a molecular cuisine stand that made things like foie gra with carbonated nuts and fresh ice cream from liquid nitrogen!\nAmazingly I’m sure I’m missing quite a lot as I’m writing all this from memory!\nThe guys and gals running the show are all pretty cool people as is evidence by all of the above, unfortunately this year there was no new JavaZone t-shirt (although they gave a great waterbottle which my spouse immediately confiscated for her own use) so I stopped by their booth and they gave me this t-shirt.\nThat shirt is amazingly cooler than the one they we\nre wearing themselves, no wonder they kept it hidden!\nThe party and trip after the conference are also cool things but I couldn’t go on the trip and was so exhausted I barely functioned at the party. Although it was at a great club and the band was good.\nThe Sessions There were many great sessions and speakers this year, I can’t possibly cover everything and I was running around so much I barely had time to see it all (despite the overflow room which is the greatest concept in any Java conference!).\nYou can check out the videos of all the sessions here:\n[\n](http://vimeo.com/album/3031533)\nHere are the ones I went to mostly in order of appearance:\nCliff Click (great name for the tech industry) gave on the first talks in the conference: \u0026quot;\nBuilding A Big Data Machine Learning Platform\n\u0026ldquo;. I was highly conflicted between this and the Docker talk and eventually picked this talk. Normally its less of a subject I care about since we have our big data App Engine backend but the talk was really interesting, the way in which the data is held in memory and partitioned across devices/VM’s is fascinating. Normally I thought in-memory DB’s were limited by machine RAM and it seems this is untrue.\n|\n\u0026mdash;|\u0026mdash;\nNeal Ford had a talk titled \u0026quot;\nContinuous Delivery for Architects\n\u0026ldquo;. His talk was great and very complimentary to the talk given by his colleague Sam Newman later on. His presentation visualizes a lot of the complexities of dealing with hugely complex architectures, which is something I don’t really run into as much so while it was very interesting it was mostly on an academic level.\nI did enjoy this presentation tremendously as a guide for \u0026ldquo;how to present a highly technical set of ideas visually\u0026rdquo;. I’m a less visual person by my nature so these presentations help me present in a way other people understand.\nNeal has a\nnew presentation book\nwith Nathaniel Schutta and Matthew McCullough. All 3 are amazing speakers with remarkably different speaking techniques which makes the collaboration very interesting… I just bought the Kindle version and have started reading thru it (reading slowly since I’m too busy preparing for JavaOne will probably have some time on my trips to the states/India). The premise of the book is very strong and it was probably a bad idea to pick it up just before I have to give a presentation (at JavaOne) since its really making me want to fix some things about it… I’ll post a more detailed book review later but I can already recommend buying it.\n|\n\u0026mdash;|\u0026mdash;\nSam Newman practically had me rolling on the floor laughing at \u0026quot;\nPractical Considerations For Microservice Architectures\n\u0026ldquo;, over his joke in the first few minutes (maybe its the dry British humor I like so much). I’m still conflicted about how practical it is for our type of organization to adopt such an architecture, but as we grow up this does seem like a reasonable approach.\n|\n\u0026mdash;|\u0026mdash;\nI missed most of the talk \u0026quot;\n50 new features of Java EE 7\n\u0026quot; from Arun Gupta and only got the end of it, that’s OK because I’ll probably be able to check the full thing at JavaOne. I’m checking out the full talk on Vimeo right now just in case JavaOne has bad scheduling (JavaZone is so great in that regard). Check out the talk to learn about Java EE 7 or better yet check out his book on\nJava EE 7\n.\n|\n\u0026mdash;|\u0026mdash;\nProbably the highlight of the show was\nKent Beck\n. If you don’t know who that is then go to your library, hopefully \u0026ldquo;Design Patterns\u0026rdquo; is there… When you have a chance to listen to someone who had such an impact on the industry give a talk you should take it no matter what the subject is and I was quite happy I did.\nThe talk was a bit too high level dealing with design as an overly abstract word, but his basic axioms were non-religious about the position of design and a lot of his insights were spot on and enlightening.\n|\n\u0026mdash;|\u0026mdash;\nKen Sipe gave a talk titled \u0026quot;\nFuture of Development and the Cloud\n\u0026quot; where he talked about\nmesos\n, which I haven’t heard about before and mostly came because the session had Docker in the abstract.\nI’m blissfully unaware of some of the complexity involved in this field thanks to Google App Engine (or because of?), so some of this went right over my head. Still the talk was interesting and it gave me a lot to think about regarding our future directions.\n|\n\u0026mdash;|\u0026mdash;\nNathaniel Schutta is someone you should see talk, he gives these fluid hilarious presentations that are always fun to watch even if you disagree. He makes the talk seem effortless which it might be with that level of experience. His talk this year was titled \u0026quot;\nMind the Gap: Architecting UIs in the Era of Diverse Devices\n\u0026quot; and had talked about the difficulty of dealing with all these devices.\nWisely Nate doesn’t leave time for Q\u0026amp;A but that was not something I was willing to accept so I grabbed him immediately after for a long hard talk about Codename One and getting rid of his JavaScript obsession. I don’t think his armor is cracked but judging from the obvious pain and suffering that shows thru his presentation he has no choice but to pickup Codename One eventually.\n(Check out the new book he published with Neal Ford \u0026amp;\nMatthew McCullough, see above) |\n\u0026mdash;|\u0026mdash;\nRafael Wintherhalter gave a talk titled:\nUnderstanding Java byte code.\nHe is the author of\nByteBuddy\nwhich I didn’t know of prior to this, it seems like a really cool tool with great syntax. Unfortunately it seems to be designed for server use which is less applicable for our very unique use cases.\nThe talk\nis a pretty great introduction to the Java VM bytecode, for me the talk was a bit too basic since this is something I’ve been deep into for years. However, he explains the subject with great slides and examples so that video is going right into my bookmarks when training new recruits on the inner workings of our VM code and getting them up to speed on bytecode!\nIf you don’t know those things you should watch that talk to understand what Java does underneath the hood.\n|\n\u0026mdash;|\u0026mdash;\nJim Webber had a couple of interesting talks including a full day workshop on day 1 which was too much for me. Especially given that we already have a database architecture and the thought of replacing it is just too painful. But Neo4j is pretty interesting and querying complex graph DB’s really brings up the hacker in me, hes a pretty talented, fluid speaker with a great sense of humor in his presentation (maybe its the dry British humor that I liked). So I really enjoyed his talk\nA Little Graph Theory for the Busy Developer\n. |\n\u0026mdash;|\u0026mdash;\nHandling complexity through configurability: Erex – an energy settlement solution for the railways of tomorrow\n.\nI met Gareth in the Speakers dinner and decided to checkout his talk, its pretty relevant to me as well since I have a success story style session pending for JavaOne and its always interesting to see how someone else handles this sort of session. Gareth \u0026amp; Ragnar did well trying to convey some of the complexity of a huge project with a lot of inherited decisions that just can’t be changed, this is hugely challenging when conveying something like this to an outside audience.\nI think they had some good ideas on how the scale can be conveyed via slides \u0026amp; UML zoom out.\n|\n\u0026mdash;|\u0026mdash;\nThe only downside of going to the session above was the fact that I couldn’t attend Brian McCallister’s session:\nI-Tier: Breaking Up the Monolith\n.\nI did check it online in Vimeo later (great thing about JavaZone) and its really interesting. We’re coming from the opposite side of a cloud architecture that is trying to normalize whereis Groupon has a far different approach. I’m not a fan of the node.js\narchitecture but its interesting hearing real world experiences with modularity which is something we all need.\n|\n\u0026mdash;|\u0026mdash;\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — September 18, 2014 at 11:53 pm (permalink) Anonymous says:\nI know I said the same thing last year, but thank you for your trip report. It’s really nice to have that kind of feedback about these big events!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/javazone-trip-report1/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/javazone-trip-report1/javazone-trip-report1-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/javazone-trip-report1/javazone-trip-report1-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://2014.javazone.no/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nJavaZone\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nis winding down as I’m starting to write this although I’ll probably post this after the videos are up to reference some of the interesting sessions I saw. Unfortunately JavaZone doesn’t post workshop videos so my workshop won’t be available, but frankly it wouldn’t have worked well in video since it was relatively interactive hence there was no presentation flow. You can see the gist of the workshop in the video I posted\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/blog/build-mobile-ios-apps-in-java-using-codename-one-on-youtube\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\na couple of weeks ago\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n. The next few paragraphs are about JavaZone itself and the trip, if you want to read about the session highlights just scroll down…\u003c/p\u003e","title":"JavaZone Trip Report"},{"content":"\niOS 8 and iPhone 6/6+ are nearly upon us and Codename One is ready for both!\nWe’ve just added device skins for iOS 6 and 6+, notice that due to the very high resolution you might want to disable scrolling. Notice that those skins are ridiculously large and as such might trigger an out of memory error when you try to run. To fix this just go to the project properties and select the run section. In it select the VM options and configure -Xmx128m or even higher.\nThe 6+ device will use the HD level DPI so you should make sure to have graphics at that resolutions in order to truly make use of that device.\nThe build servers will now take\n10 screenshots instead of 7\nfor iOS devices, these include the 6 the 6+ and the landscape version of 6+.\nThe file names are:\nDefault-667h@2x.png – 750 x 1334\nDefault-736h@3x.png - 1242 x 2208\nDefault-736h-Landscape@3x.png – 2208 x 1242\nYou will notice that on stage Apple claimed that the device is 1080p which is true, but graphics for it is raised by a multiple of 3 then downscaled by hardware to simplify the programming model.\nWe are also running the latest gold master version of iOS 8 which seems to support Codename One applications just as well as iOS 7 without any changes required.\nWe’ll write more about the JavaZone conference trip soon.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/8-to-6/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/8-to-6/8-to-6-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/8-to-6-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/8-to-6/8-to-6-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eiOS 8 and iPhone 6/6+ are nearly upon us and Codename One is ready for both!\u003c/p\u003e\n\u003cp\u003eWe’ve just added device skins for iOS 6 and 6+, notice that due to the very high resolution you might want to disable scrolling. Notice that those skins are ridiculously large and as such might trigger an out of memory error when you try to run. To fix this just go to the project properties and select the run section. In it select the VM options and configure -Xmx128m or even higher.\u003c/p\u003e","title":"8 to 6+"},{"content":"\nThis represents JavaZone to me\nI’ll be flying to Oslo this morning to speak at JavaZone and meet with some local community members, I’m very excited about this! If you are attending JavaZone and haven’t yet signed up for the workshop please do so now.\nWe also updated our home page and gallery with some up to date statistics\nWe just pushed out new build servers for Android/Blackberry \u0026amp; J2ME that\nuse SSD disks to speed up compilation even further, since the build on these platforms is already pretty fast I’m not sure you will see a noticeable difference but we are concerned that we might have mistakes in the setup of the new server images. If you get suspicious build failures on those 3 platforms that only happen sometimes let us know.\nWe also pushed out an experimental fix for a long standing\nIDEA issue that has been around for a while, if you are one of the developers affected by the issue please let us know if this is still happening and if so please provide a log for this so we can debug it.\nChen has made some interesting performance improvements for the graphics pipelines, they are still not up on the build servers but hopefully they will be noticeable. We also added a new API to get all the contacts in one go, this works much faster on Android then extracting the contacts one by one but is still pretty expensive so a thread is still essential. This new API effectively consists of two methods in Display:\nContact[] getAllContacts(boolean withNumbers, boolean includesFullName, boolean includesPicture, boolean includesNumbers, boolean includesEmail, boolean includeAddress);\nisGetAllContactsFast();\nYou might not want to invoke this method unless\nisGetAllContactsFast() returns true, otherwise it will fallback to code that effectively loops all the contacts to create an array.\nWe also added a callback method to ConnectionRequest: protected void cookieReceived(Cookie c)\nThis should make cookie handling much simpler.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/servers-javazone-more/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/servers-javazone-more/servers-javazone-more-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/servers-javazone-more-large-2.jpg\"\u003e\u003cbr\u003e\n\u003cimg alt=\"JavaZone Picture\" loading=\"lazy\" src=\"/blog/servers-javazone-more/servers-javazone-more-1.jpg\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eThis represents JavaZone to me\u003c/p\u003e\n\u003cp\u003eI’ll be flying to Oslo this morning to speak at JavaZone and meet with some local community members, I’m very excited about this! If you are attending JavaZone and haven’t yet signed up for the workshop please do so now.\u003c/p\u003e\n\u003cp\u003eWe also updated our home page and gallery with some up to date statistics\u003c/p\u003e\n\u003cp\u003eWe just pushed out new build servers for Android/Blackberry \u0026amp; J2ME that\u003c/p\u003e","title":"Servers, JavaZone \u0026 More"},{"content":"\nSteve Hannah of new iOS pipeline fame (as well as a ton of open source Codename One libraries and projects you can\nsee here\n), has just announced one of his more ambitious undertaking:\nMirah support for Codename One\n.\nMirah\nis effectively Ruby without the performance penalty of an overly dynamic language, its compiled to bytecode and can thus be compiled with the Codename One build servers.\nIf you are a fan of Ruby you now have an easy option of writing mobile applications for all devices without going into Java and without paying a performance penalty!\nYou can learn more about all of this in Steve’s\ndetailed blog post and video\n.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — September 6, 2014 at 5:39 am (permalink) Anonymous says:\nAs a ruby developer i can say this was a really pleasant surprise. I have to say it’s great to see open minded people experimenting with technologies like this.\nAnonymous — September 6, 2014 at 1:44 pm (permalink) Anonymous says:\nIt was always our intention to support additional languages thru Codename One. Our Java focus is mostly due to constrained resources, ideally as we grow we will see more diversity in this project.\nAnonymous — September 30, 2014 at 5:40 pm (permalink) Anonymous says:\nawesome feature. Good work!!!!!!!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/mirah-for-codename-one/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/mirah-for-codename-one/mirah-for-codename-one-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/mirah-for-codename-one/mirah-for-codename-one-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eSteve Hannah of new iOS pipeline fame (as well as a ton of open source Codename One libraries and projects you can\u003cbr\u003e\n\u003ca href=\"https://github.com/shannah\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nsee here\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n), has just announced one of his more ambitious undertaking:\u003cbr\u003e\n\u003ca href=\"http://sjhannah.com/blog/?p=331\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nMirah support for Codename One\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n.\u003cbr\u003e\n\u003ca href=\"http://www.mirah.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nMirah\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nis effectively Ruby without the performance penalty of an overly dynamic language, its compiled to bytecode and can thus be compiled with the Codename One build servers.\u003c/p\u003e","title":"Mirah for Codename One"},{"content":"\nThis material is out of date by now. We recommend checking out the Codename One Academy.\nWe’ve uploaded the full course video cast as a youtube playlist, just go thru the parts and in an hour and some change you should understand the basics of creating a simple Codename One client server application that runs on all mobile devices.\nThe Udemy course is\nstill there\nand probably useful if you live in a region where youtube is blocked. The source code to accompany the course can be viewed in SVN here:\nhttps://code.google.com/p/codenameone/source/browse/trunk/Demos/PhotoShare/\nFor your convenience you can also download the projects as a zip\n__Download\nTo learn more about Codename One we suggest checking out our\ngetting started page\n.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — October 9, 2014 at 7:24 am (permalink) Anonymous says:\nHello Shai,\nI want to follow this tutorial but I am not sure if it is only for iOS or can also be ussed for android.\nThank you\nAnonymous — October 9, 2014 at 1:21 pm (permalink) Anonymous says:\nYes its for all platforms. The main reason for iOS in the title is the mindshare/SEO aspect of this but its applicable for everything.\nAnkit Mathur — April 7, 2015 at 9:30 am (permalink) Ankit Mathur says:\nIts all working perfectly… But still I have two questions.\n1. How to change the form programmatically?\n2. Can we use the JAR files to create some graphs / some drawings / capture locations as in android. and many more devices.\nShai Almog — April 7, 2015 at 7:21 pm (permalink) Shai Almog says:\nCheck out additional examples that would answer your questions here: https://www.udemy.com/learn…\n1. Wasn’t this demonstrated in the demo? form.show etc.?\n2. You can use cn1libs: http://codenameone.com/cn1l… Notice that graphs are builtin to Codename One: http://www.codenameone.com/… as is location support etc.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/build-mobile-ios-apps-in-java-using-codename-one-on-youtube/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/build-mobile-ios-apps-in-java-using-codename-one-on-youtube/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis material is out of date by now. We recommend checking out the \u003ca href=\"/blog/launching-codename-one-academy.htmls\"\u003eCodename One Academy\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eWe’ve uploaded the full course video cast as a youtube playlist, just go thru the parts and in an hour and some change you should understand the basics of creating a simple Codename One client server application that runs on all mobile devices.\u003c/p\u003e\n\u003cp\u003eThe Udemy course is\u003cbr\u003e\n\u003ca href=\"https://www.udemy.com/build-mobile-ios-apps-in-java-using-codename-one/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nstill there\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nand probably useful if you live in a region where youtube is blocked. The source code to accompany the course can be viewed in SVN here:\u003c/p\u003e","title":"Build Mobile iOS Apps In Java Using Codename One On Youtube"},{"content":"\nAs you know we will be presenting Codename One in our booth at JavaOne and would be using several community applications to demonstrate what you have achieved using the tool we built. We think you are our best spokes persons and we think we can provide a platform to expose your application to more people.\nIf you created an outstanding app that we can demo in our booth at JavaOne, please be sure to submit it to the gallery.\nThanks for your help.\nOn an unrelated subject we recently added a\nvideos\nsection to the website that you might want to checkout, we also added a new\nUdemy course\nbased on the JavaZone workshop I’ll be giving. We will also be uploading the videos of that course to youtube for easier viewing.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — August 29, 2014 at 4:25 am (permalink) Anonymous says:\nYou’re welcome to promote https://play.google.com/sto… and https://itunes.apple.com/be… at your Booth.\nWim\nAnonymous — September 3, 2014 at 4:27 am (permalink) Anonymous says:\nwhat is preferred format? can i simply send apks? I have a few you can look at.\nAnonymous — September 3, 2014 at 4:21 pm (permalink) Anonymous says:\nYou need to submit here: http://www.codenameone.com/…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/showcase-your-codename-one-app-at-javaone/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/showcase-your-codename-one-app-at-javaone/showcase-your-codename-one-app-at-javaone-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/showcase-your-codename-one-app-at-javaone/showcase-your-codename-one-app-at-javaone-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eAs you know we will be presenting Codename One in our booth at JavaOne and would be using several community applications to demonstrate what you have achieved using the tool we built. We think you are our best spokes persons and we think we can provide a platform to expose your application to more people.\u003c/p\u003e\n\u003cp\u003eIf you created an outstanding app that we can demo in our booth at JavaOne, please be sure to submit it to the gallery.\u003c/p\u003e","title":"Showcase Your Codename One App at JavaOne"},{"content":"\nAfter a while with several new features being off by default we are officially flipping the switch on newer functionality in the build arguments. Notice that you can always disable this new functionality by explicitly defining the appropriate build argument, however you should probably let us know what isn’t working for you.\nWe are turning on the new Android/iOS graphics pipelines by default which should mean the new shape/transform API’s should now \u0026ldquo;just work\u0026rdquo;. To disable the Android pipeline use android.asyncPaint=false and to disable the iOS pipeline use ios.newPipeline=false\nWe are also switching on a virtual keyboard change for iOS which provides a more \u0026ldquo;native’ feel for the iOS keyboard, it still has some unique edge cases but we feel it provides a better default experience overall. This virtual keyboard mode keeps the keyboard open once you start editing even if you scroll the form, its generally more like the native editing functionality in iOS. You can disable it using ios.keyboardOpen=false.\nYou’ll notice that the new VM still isn’t the default, we feel it hasn’t reached the maturity level of the current VM and with JavaOne looming we don’t want to disrupt the code stability too much.\nWe did find a new and exciting way to generate stack traces on iOS. If you use our standard logging mechanism using Log.e() you can now get full stack traces on iOS devices (not including line numbers) even for the older VM. The traces would look a bit \u0026ldquo;weird\u0026rdquo; but they are readable and can be used to locate the source of a problem.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — August 28, 2014 at 8:46 am (permalink) Anonymous says:\nWhy is it that sometimes when you open a webview on android and it has a form, the virtual keyboard does not open on focus of an input element even when there is no other focus component on the form. Some times it works, other times it doesn’t.\nAnonymous — August 28, 2014 at 4:13 pm (permalink) Anonymous says:\nThat’s unrelated to the post. You should use the discussion forum http://www.codenameone.com/… or stack overflow for such questions which will also allow the community members to notice them.\nThis is an Android bug that we worked around once but it keeps resurfacing for some cases. We aren’t aware of a workaround for that.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/stacks-flipping-switches/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/stacks-flipping-switches/stacks-flipping-switches-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/stacks-flipping-switches-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/stacks-flipping-switches/stacks-flipping-switches-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eAfter a while with several new features being off by default we are officially flipping the switch on newer functionality in the build arguments. Notice that you can always disable this new functionality by explicitly defining the appropriate build argument, however you should probably let us know what isn’t working for you.\u003c/p\u003e\n\u003cp\u003eWe are turning on the new Android/iOS graphics pipelines by default which should mean the new shape/transform API’s should now \u0026ldquo;just work\u0026rdquo;. To disable the Android pipeline use \u003ccode\u003eandroid.asyncPaint=false\u003c/code\u003e and to disable the iOS pipeline use \u003ccode\u003eios.newPipeline=false\u003c/code\u003e\u003c/p\u003e","title":"Stacks \u0026 Flipping Switches"},{"content":"\nI’ve been working on demos for JavaZone and built something small that has been asked a few times. Some developers were looking for\nURLImage\nsupport in image viewer but that’s not a very good approach since URLImage expects images to be at a specific resolution and is thus very bad for images with unknown dimensions. However, ImageViewer thrives on showing and zooming full sized images.\nThere was a bit of a community hack with ImageDownloadService a while back but it was a bit in-elegant and wasn’t\nwhat I was looking for, so I created a simple list model that just streams images, you can use it with image viewer like this:\nImageViewer viewer = new ImageViewer(imageList.getItemAt(offset));\nviewer.setImageList(imageList);\nThe list model is just a plain old list model that expects the placeholder image to be an encoded image you have already loaded. This implementation expects images to have an ID which we use in the createImageURL method. Notice we could just use the image index but since that might change (user deletes images etc.) we needed to have ID’s generated by the server. We’ll have the full demo up with the server side code for JavaZone:\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/image-viewer-from-the-web/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/image-viewer-from-the-web/image-viewer-from-the-web-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/image-viewer-from-the-web/image-viewer-from-the-web-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been working on demos for JavaZone and built something small that has been asked a few times. Some developers were looking for\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/3/post/2014/03/image-from-url-made-easy.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nURLImage\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nsupport in image viewer but that’s not a very good approach since URLImage expects images to be at a specific resolution and is thus very bad for images with unknown dimensions. However, ImageViewer thrives on showing and zooming full sized images.\u003c/p\u003e","title":"Image Viewer From The Web"},{"content":"\nJavaZone\njust released their traditional annual clip which is especially amusing for fans of the Song Of Ice \u0026amp; Fire series (or the Game Of Thrones TV adaptation). If you haven’t seen the clips from these guys before you MUST check them out\nhere\n, including spoofs of house of cards and breaking bad (not to mention years of hilarious clips)!\nVery cool.\nWe are hard at work for my workshop at JavaZone which will teach the creation of a Codename One application from start to finish, if you haven’t signed up you should. JavaZone is one of the best produced conference I’ve attended and its loads of fun with great humor, music, food and alcohol. Definitely worth the trip.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — August 19, 2014 at 5:19 pm (permalink) Anonymous says:\nHey Shai, can you please post the link to sign up for the CN1 workshop? thanks.\nAnonymous — August 20, 2014 at 2:34 am (permalink) Anonymous says:\nThat’s the session http://2014.javazone.no/pre… its in JavaZone in Oslo.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/game-of-code/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/game-of-code/game-of-code-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/game-of-code/game-of-code-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://2014.javazone.no/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nJavaZone\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\njust released their traditional annual clip which is especially amusing for fans of the Song Of Ice \u0026amp; Fire series (or the Game Of Thrones TV adaptation). If you haven’t seen the clips from these guys before you MUST check them out\u003cbr\u003e\n\u003ca href=\"https://www.youtube.com/channel/UC1s3pFsMZv37NAxIIW90MGw\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nhere\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, including spoofs of house of cards and breaking bad (not to mention years of hilarious clips)!\u003c/p\u003e\n\u003cp\u003eVery cool.\u003c/p\u003e","title":"Game Of Code"},{"content":"\nDealing with the new Mavericks release of Mac OS has proved to be remarkably challenging but hopefully this is finally behind us and we can slowly upgrade our machines to the new Mac OS. This required some overhaul of our build process but should simplify the process of procuring more servers. iOS builds should now spend less time in the queued state, this might be less noticeable during August (which has far fewer builds than most months) but you would probably notice it soon enough.\nOne of the side benefits of all this work is that we were able to significantly shorten the Mac Desktop build times from 10 minutes to under 1 minute thanks to a better hosting option.\nSummer months have been a bit slow with updates with kids being on summer vacation but we did manage to get a few improvements thru never the less. Tabs now have a new setSelectedIndex() method that allows us to animate to the new selection rather than pop to it immediately.\nImageViewer now has an option to fill the screen with the base zoom level. This might work for some use cases but keep in mind that due to logical constraints some images might remain cropped if you choose to use this option.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/mavericks-signing/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/mavericks-signing/mavericks-signing-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/mavericks-signing/mavericks-signing-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eDealing with the new Mavericks release of Mac OS has proved to be remarkably challenging but hopefully this is finally behind us and we can slowly upgrade our machines to the new Mac OS. This required some overhaul of our build process but should simplify the process of procuring more servers. iOS builds should now spend less time in the queued state, this might be less noticeable during August (which has far fewer builds than most months) but you would probably notice it soon enough.\u003c/p\u003e","title":"Mavericks Signing"},{"content":"\nDespite quite a few regressions with the new VM we were finally able to make some major improvements to its performance and bring it on-par with native. Its still not as fast as it could be but coupled with the far improved GC and far superior synchronization its probably a better choice in terms of performance than the old VM. We are still heavily improving it to make it even better.\nOn that note, one of the major goals of this VM was in reducing build times. This took a turn to the worse this week with builds in excess of 16 minutes which effectively ground our servers to a halt. Turns out that the LLVM compiler used by Apple is pretty fast for most state of the art C/Objective-C but is downright awful for a simple #define statement. We used a lot of macros to simplify some of the generated code, but apparently the compiler chocked on them so badly it just took up all the CPU.\nThis was remarkably hard to track down since we have hundreds of thousands of lines of generated code in a typical application and benchmarking the compiler is pretty much a process of trial and error.\nThe servers are now up to date with a faster VM and we are also bringing in additional servers to handle the excess load and reduce the time spent in queued mode during build. This should make build times noticeably shorter regardless of whether you use the new VM or not.\nNotice that we are now rolling out our first Mac servers based on Mavericks (new Mac OS version) which broke some things in our build scripts. We made some fixes but this might trigger some regressions in the next few days as we adjust our scripts.\nOn the code side of things Chen made some improvements to the image viewer and Tabs component which include improved animations and additional image sizing options.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/faster-builds-performance/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/faster-builds-performance/faster-builds-performance-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/faster-builds-performance/faster-builds-performance-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eDespite quite a few regressions with the new VM we were finally able to make some major improvements to its performance and bring it on-par with native. Its still not as fast as it could be but coupled with the far improved GC and far superior synchronization its probably a better choice in terms of performance than the old VM. We are still heavily improving it to make it even better.\u003c/p\u003e","title":"Faster Builds \u0026 Performance"},{"content":"\nMicrobenchmarks are often derided in the Java community with some good reason, they show edge cases that either present the JIT in a bad light or show it as ridiculously (unrealistically) fast. However, with static compilers and translation tools microbenchmarks can give us insight into performance problems that normal profilers might not provide insight into.\nWe’ve been tracking performance issues with the new iOS VM for the past couple of weeks and had a very hard time pinpointing the issues, finally thanks to microbenchmarks we see some of the performance issues and already eliminated quite a few bottlenecks in the code that bring the optimization level closer to native speed. E.g. our getter/setters are now practically free.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/microbenchmarks/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/microbenchmarks/microbenchmarks-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/microbenchmarks/microbenchmarks-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eMicrobenchmarks are often derided in the Java community with some good reason, they show edge cases that either present the JIT in a bad light or show it as ridiculously (unrealistically) fast. However, with static compilers and translation tools microbenchmarks can give us insight into performance problems that normal profilers might not provide insight into.\u003c/p\u003e\n\u003cp\u003eWe’ve been tracking performance issues with the new iOS VM for the past couple of weeks and had a very hard time pinpointing the issues, finally thanks to microbenchmarks we see some of the performance issues and already eliminated quite a few bottlenecks in the code that bring the optimization level closer to native speed. E.g. our getter/setters are now practically free.\u003c/p\u003e","title":"Microbenchmarks"},{"content":"\n**\nNotice:\n**\nthe original version of this post incorrectly specified the property as AppArgs instead of AppArg. This is now fixed. For Android you would probably also want to add the build argument android.xactivity=android:exported=\u0026quot;false\u0026quot;.\nA common trick in mobile application development, is communication between two unrelated applications. In Android we have intents which are pretty elaborate and can be used via Display.execute, however what if you would like to expose the functionality of your application to a different application running on the device. This would allow that application to launch your application.\nThis isn’t something we builtin to Codename One, however we did expose enough of the platform capabilities to enable that functionality rather easily on Android.\nOn Android we need to define an intent filter which we can do using the android.xintent_filter build argument, this accepts the XML to filter whether a request is relevant to our application:\nandroid.xintent_filter=\u0026lt;intent-filter\u0026gt; \u0026lt;action android_name=\u0026quot;android.intent.action.VIEW\u0026quot; /\u0026gt; \u0026lt;category android_name=\u0026quot;android.intent.category.DEFAULT\u0026quot; /\u0026gt; \u0026lt;category android_name=\u0026quot;android.intent.category.BROWSABLE\u0026quot; /\u0026gt; \u0026lt;data android_scheme=\u0026quot;myapp\u0026quot; /\u0026gt; \u0026lt;/intent-filter\u0026gt;\nThis is taken from this\nstack overflow question\n, to bind the myapp:// URL to your application. So if you will type myapp://x into the Android browser your application will launch.\nSo how do you get the \u0026ldquo;launch arguments\u0026rdquo;, passed to your application?\nDisplay.getInstance().getProperty(\u0026quot;AppArg\u0026quot;) should contain the value of the URL that launched the app or would be null if it was launched via the icon.\niOS is practically identical with some small caveats, iOS’s equivalent of the manifest is the plist. So we allow injecting more data into the plist thru the\nios.plistInject build argument.\nSo the equivalent in the iOS side would be:\nios.plistInject=\u0026lt;key\u0026gt;CFBundleURLTypes\u0026lt;/key\u0026gt; \u0026lt;array\u0026gt; \u0026lt;dict\u0026gt; \u0026lt;key\u0026gt;CFBundleURLName\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;com.yourcompany.myapp\u0026lt;/string\u0026gt; \u0026lt;/dict\u0026gt; \u0026lt;dict\u0026gt; \u0026lt;key\u0026gt;CFBundleURLSchemes\u0026lt;/key\u0026gt; \u0026lt;array\u0026gt; \u0026lt;string\u0026gt;myapp\u0026lt;/string\u0026gt; \u0026lt;/array\u0026gt; \u0026lt;/dict\u0026gt; \u0026lt;/array\u0026gt; On a separate unrelated note the guys from Java Code Geeks announced the winners of\nour raffle of two tickets\n, yesterday. Congratulations to both winners!\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nFrancesco Galgani — August 12, 2017 at 10:56 am (permalink) Francesco Galgani says:\nIt seems an old post. I’m interested in intercepting URLs on iOS \u0026amp; Android because an use case like this:\n1. The server sends a verification code to a given phone number by sms\n2. Because Codename One cannot receive sms, the verification code can be taken by the app when the user tape the url inside the sms.\nOf course I can have different use cases, all with the purpose to pass one or more arguments to my app from an external app (native sms app, other sms/messaging apps like Signal or Whatsapp, browsers, etc.).\nSo, my questions are if this post is still update and if it’s correctly formatted (it’s not clear if the build arguments for Android and iOS are in only one row).\nI suppose that the build arguments are the ones described in \u0026ldquo;Sending Arguments To The Build Server\u0026rdquo;, is it right?\nhttps://www.codenameone.com…\nThank you.\nShai Almog — August 13, 2017 at 5:32 am (permalink) Shai Almog says:\nThis post is in the developer guide too (I think under the misc section). Everything is in one row since that’s how build hints work. Since it’s XML it doesn’t matter.\nSMS and URL interception are very different things. If you look at apps like banking apps, uber, whatsapp etc. in all of them SMS activation is done by typing in the value you get from the native SMS app. Some rare apps catch the incoming SMS on Android but since this requires some pretty scary sounding permissions a lot of apps just give up on that feature and work the same way as they do on iOS.\nThis can be done easily in Codename One and is done by the JAT app.\nFrancesco Galgani — July 11, 2018 at 6:22 pm (permalink) Francesco Galgani says:\nAt the begging of this post, you wrote: «For Android you would probably also want to add the build argument android.xactivity=android:exported=\u0026ldquo;false\u0026rdquo;». Indeed this build hint cannot be used, because it causes that Android cannot start the app, giving the error: \u0026ldquo;The app is not installed\u0026rdquo;. The reason is explained here: https://stackoverflow.com/a…\nShai Almog — July 12, 2018 at 5:39 am (permalink) Shai Almog says:\nI don’t recall this at all, it’s been 4 years since I wrote that so no idea…\nThis isn’t mentioned in the developer guide section though: https://www.codenameone.com…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/intercepting-urls-on-ios-android/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/intercepting-urls-on-ios-android/intercepting-urls-on-ios-android-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/intercepting-urls-on-ios-android/intercepting-urls-on-ios-android-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e**\u003cbr\u003e\nNotice:\u003cbr\u003e\n**\u003cbr\u003e\nthe original version of this post incorrectly specified the property as AppArgs instead of AppArg. This is now fixed. For Android you would probably also want to add the build argument \u003ccode\u003eandroid.xactivity=android:exported=\u0026quot;false\u0026quot;\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eA common trick in mobile application development, is communication between two unrelated applications. In Android we have intents which are pretty elaborate and can be used via Display.execute, however what if you would like to expose the functionality of your application to a different application running on the device. This would allow that application to launch your application.\u003c/p\u003e","title":"Intercepting URL's On iOS \u0026 Android"},{"content":"\nRuntime.exec is pretty familiar to Java developers (and the process builder in later versions), however for mobile applications we usually don’t have access to an executable. The solution is to invoke a URL which is bound to a particular application, this works rather well assuming the application is installed and you can activate quite a few things e.g. this is a partial list of\nURL’s that work on iOS\n. (notice that a lot of these are redundant since we have builtin portable functionality to address those features).\nNormally on iOS you would do something like\ncanOpenURL followed by openURL assuming the can message returned true. However, Android et al doesn’t have anything quite like that. To enable this at least for iOS if not elsewhere we added a Display.canExecute() method to go with the Display.execute() method. However, canExecute returns a Boolean instead of a boolean which allows us to support 3 result states:\n1. Boolean.TRUE – the URL can be executed.\n2. Boolean.FALSE – the URL can be executed.\n3. null – we have no idea whether this will work on this platform.\nWe’ve added an experimental BigInteger/BigDecimal implementation to the util package. This is a very basic implementation lifted from the Bouncy Castle work, but these are big omissions in our current code which should allow more business/scientific code to be ported.\nWe also have an experimental (deprecated) port of the MiG layout in place. We ported it due to a long standing RFE but it doesn’t seem to be working as expected, its hard to tell the source of the problem and we aren’t sure if we want to go in that direction. If this is something that is interesting to you let us know and also check out if you can spot our mistakes in the port.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — September 18, 2014 at 5:18 am (permalink) Anonymous says:\nIs Can execute also usable on Android? If so, is there somewhere a list of Android specific urls?\nWim\nAnonymous — September 18, 2014 at 3:27 pm (permalink) Anonymous says:\nNo, Android doesn’t really have anything quite like that. It has something potentially more powerful: intents. Which you can invoke via the execute call and also receive a response from said intent.\nSince everything in Android is an Intent there isn’t so much a list of them as much as just googling the intent for whatever you want.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/can-execute/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/can-execute/can-execute-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/can-execute/can-execute-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eRuntime.exec is pretty familiar to Java developers (and the process builder in later versions), however for mobile applications we usually don’t have access to an executable. The solution is to invoke a URL which is bound to a particular application, this works rather well assuming the application is installed and you can activate quite a few things e.g. this is a partial list of\u003cbr\u003e\n\u003ca href=\"http://wiki.akosma.com/IPhone_URL_Schemes\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nURL’s that work on iOS\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n. (notice that a lot of these are redundant since we have builtin portable functionality to address those features).\u003c/p\u003e","title":"Can Execute"},{"content":"\nBefore we launched our\nrecent promotion\nfor JavaOne tickets with\nJava Code Geeks\nwe sought out guides/tutorials about running such a promotion, unfortunately we didn’t find anything useful so we had to improvise and work by instinct. This post will also cover some of the statistical results about the Java community so if this is the reason you are reading this post skip down for some interesting takeaways.\n**\nRunning a promotion tips \u0026amp; tricks\n**\nThe idea started when one of our talks got accepted to JavaOne, suddenly we had two extra tickets (we got 3 tickets with the booth) so we could give away two tickets. From our experience we came to the conclusion that most developers don’t know about Codename One yet and that is probably the most important thing we need to improve in our outreach. So here are a few conclusions we came to in no particular order:\n1. We need a partner to handle the giveaway – this removed the bias from us. We have an incentive to give the tickets to our best customers so we can’t really be fair. That’s why we picked\nJava Code Geeks\n.\n2. We picked\nJava Code Geeks\nas a partner – we needed a partner who is focused on Java (check), who has a big enough audience (check), whose audience isn’t already familiar with our product (check). This is probably the most important step, most of our contestant came from Java Code Geeks and as you can see from the chart to the right. Most of the people who entered our contest didn’t know about Codename One in advance and were happy to find out about us.\n3. We created incentives to social share – most of the people who would read\nJava Code Geeks\nare probably up to date with the latest technology, but their friends (and friends of friends) might not be. The true value of the promotion is social share which is why we made the contest require sharing. Initially we wanted the person with the most retweets/shares to \u0026ldquo;win\u0026rdquo; but\nByron from Java Code Geeks\nobjected to this approach (in hindsight I think he was right to object) claiming that it would rule out people who don’t have many friends. It would also have promoted cheating which is a huge problem.\n4. We created very detailed rules for the competition – yes, most people didn’t read them (as is obvious by some of the submissions we got) but there are now rules that the raffle itself should follow. We used Google docs to collect details and signups which allowed us to collect a lot of structured data.\nWe included an entirely optional survey and 99% of submitters answered questions within the survey despite the optionality!\n5. We promoted the giveaway in our respective newsletters which is usually the most effective way to get people to signup. However, a single retweet by @java is probably more valuable than an 18k strong mailing list.\n6. We used Facebook, Twitter and adsense ads – all charged us and delivered literally nothing. Facebook charged for clicks that Google Analytics didn’t show. Normally I would chuck this as a Google analytics omission however we saw a lot of clicks on the Facebook side and no submissions to the contest form… This seems to indicate that Facebook is charging for fraudulent clicks!\nResults We asked developers which operating system they were using and were pretty shocked by the results. We see Macs all over JavaOne and all the conferences I go to, but it seems that Macs are a minority to Linux!\nThe IDE of choice brought a pretty predictable result although much closer than we would have thought as the number of answers grew the distance between the IDE’s grew as well with NetBeans surpassing IDEA and Eclipse growing in strength. However, the race between the IDE’s is still very real and despite Eclipse lead its position seems very assailable in the market. Our decision to support all 3 IDE’s seems like an excellent decision in this light.\nAnother shocker is the Java platform of choice. I always get the sense that all developers working with Java have migrated to Java EE. This doesn’t seem to be the case entirely, there are plenty of developers still working with Java SE. I’m actually surprised there are still 10% of developers that are working on Java ME.\nWhat is your preferred Java news source, here we excluded Java Code Geeks since we assumed unreasonable bias in the results (according to other stats it would probably occupy well over 50%). Notice that while some outlets (e.g. dzone) are clearly dominant there is no true leader. When targeting the Java community we literally need to be everywhere.\nDo Java developers use other languages besides Java?\nHonestly we should have asked what for? JavaScript/CoffeScript took the lead but do developers use it for HTML or do they use server JavaScript e.g. NodeJS?\nThe main motivation behind asking this question was potential support for other languages in Codename One especially JVM languages e.g. JRuby, Scala etc.\nWe probably should have phrased a few different questions to get refined answers.\nFinal thoughts I hope you found these results useful and illuminating. For the next contest/survey we will run we picked up the following lessons:\n1. Better limits on the goals of the question – e.g. with the languages besides Java we didn’t quite get an answer. I would probably ask, are you interested in other languages? Would you prefer another language?\n2. We would not waste a cent on Advertising.\n3. Partner selection is critical – Java Code Geeks delivered!\n4. As pleased as we were with the work done by the guys at Java Code Geeks, it was crucial for us to come prepared. We phrased the contest terms and defined most of the conditions/questions. Your partner can be very helpful but only you can define your own expectations and results.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — July 10, 2014 at 5:30 am (permalink) Anonymous says:\nFrom the company where I am working, they analyzed many mobile cross platform development tools. The assessors know your product, but one of the biggest critiques on your product is they experience more inconsistency and adjusting for cross platforms, especially Windows and BB 10 where there are some growing demand from our clients. So instead, they opted for other tools which offers more consistency and fortunately is also favorable with our development team’s programming expertise. They don’t think your tool is bad, just more inconsistent and tedious to use than some of the others they have tried. Perhaps its not just that people don’t know CodenameOne, but also run into the issues we also encountered and therefore not using it and would rather invest in expertise for other tools? Anyway its just an honest opinion and suggestion from what I observed from our team and perhaps we are the only few.\nAnonymous — July 10, 2014 at 6:35 am (permalink) Anonymous says:\nThanks for the feedback, I’d really like to know more about the evaluation and whether the person responsible had any contact with us.\nOne point I’d like to clarify is that we know for a fact that our reach is to blame. Since our product is cloud based we can \u0026ldquo;see\u0026rdquo; the retention statistics rather easily and they exceed industry standards. The chart above showing the number of people who haven’t heard about Codename One in a survey directed at our community as well is a pretty strong indicator of that fact.\nAbout Windows Phone and BB10 you do have a point. We have a couple of users to whom BB10 is a target and they found the Android bridge to be sufficient. I’m not aware of any major company in our field doing native BB10 development, it doesn’t seem viable with the Android support.\nThe Windows Phone port is a disappointment to us as well. There are technical difficulties due to very poor architectural decisions made by the developers at MS and after 3-4 different rewrites we aren’t much better off. I’m not aware of any cross platform tool that works well with Windows Phone, Cordova (HTML5) is bearable with its obvious caveats. Hopefully we will able to take a shortcut there as well: http://gigaom.com/2014/07/0…\nI’m not sure I understand the other comment related to the option you eventually took but we’d be happy if you raise some of the issues you’ve experienced in the discussion forum. Even if we don’t have an answer or can’t improve something good feedback is how we improve the product.\nAnonymous — July 10, 2014 at 7:32 am (permalink) Anonymous says:\nThe team decided develop webapps for now, but is busy assessing whether to just hire skills for specific platforms for native development in the future. Since there are many top apps developed for Windows Phone, why is CodenameOne having difficulty? Is it better to develop apps for Windows Phone from scratch reusing some of the source done by CodenameOne? Are you still planning to improve Windows support? Anyway, I’ll have a word with the assessors and see if they want to describe the issues they are having in your forum, but it seems its all about getting the product out on time for now.\nAnonymous — July 10, 2014 at 11:17 am (permalink) Anonymous says:\nI explained some of the issues we had with Windows Phone here: http://www.codenameone.com/…\nIt helps to understand how Codename One works and why its so portable http://www.codenameone.com/…\nWe’d love to have a better Windows Phone port, we already invested into 3 rewrites attempting to improve the situation.\nAnonymous — July 10, 2014 at 12:40 pm (permalink) Anonymous says:\nOne of the product our assessors looked at is called: Xamarin (www.xamarin.com), which is similar in concept to yours except the development code is done in C# and not Java. The downside is our development team is not C# centric, but it looks promising for people that are.\nAnonymous — July 11, 2014 at 1:34 am (permalink) Anonymous says:\nXamarin isn’t a Write Once Run Anywhere solution. It effectively allows you to write your application in C# but you invoke native device API’s. This means you have some common business logic but your UI (roughly 50% of the code) would be platform specific.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/developer-promotion-practical-guide-statistics-about-the-java-echo-system/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/developer-promotion-practical-guide-statistics-about-the-java-echo-system/developer-promotion-practical-guide-statistics-about-the-java-echo-system-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/developer-promotion-practical-guide-statistics-about-the-java-echo-system-large-7.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/developer-promotion-practical-guide-statistics-about-the-java-echo-system/developer-promotion-practical-guide-statistics-about-the-java-echo-system-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eBefore we launched our\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/blog/codename-one-java-code-geeks-are-giving-away-free-javaone-tickets-worth-3300\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nrecent promotion\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nfor JavaOne tickets with\u003cbr\u003e\n\u003ca href=\"http://javacodegeeks.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nJava Code Geeks\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nwe sought out guides/tutorials about running such a promotion, unfortunately we didn’t find anything useful so we had to improvise and work by instinct. This post will also cover some of the statistical results about the Java community so if this is the reason you are reading this post skip down for some interesting takeaways.\u003c/p\u003e","title":"Developer Promotion – practical guide \u0026 statistics about the Java ecosystem"},{"content":"\nOver the weekend\nSteve\nposted a really cool demo showing off some of his work on the new iOS graphics pipeline, specifically the perspective transform. Perspective transform allows us to rotate elements in a 3 dimensional space to create pretty nifty effects. Right now this is only supported on iOS devices (since Java SE doesn’t really support it, only thru FX) we are still looking into the Android implementation\n. Running this code on our simulator will not produce the same effect and in order to actually see this on the device you will need to build using the new pipeline build argument: ios.newPipeline=true\nRight now this code is pretty low level stuff (and very platform specific) we intend to abstract a lot of this logic via the component layer so you can use perspective transforms in transitions and various effects.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — August 27, 2014 at 12:54 pm (permalink) Anonymous says:\nNice work. How can this be use on form or container but preferably forms\nAnonymous — August 27, 2014 at 2:16 pm (permalink) Anonymous says:\nIt should be. Ideally we’d offer this as a custom transition.\nAnonymous — February 18, 2015 at 6:43 pm (permalink) Anonymous says:\nHi does this tutorial work on simulator and Android now?\nAnonymous — February 19, 2015 at 3:53 am (permalink) Anonymous says:\nAndroid yes, simulator not quite. Its problematic since the Java2D API doesn’t include support for perspective transform.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/perspective-transform/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/perspective-transform/perspective-transform-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Perspective Transform\" loading=\"lazy\" src=\"/blog/perspective-transform/perspective-transform-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOver the weekend\u003cbr\u003e\n\u003ca href=\"http://sjhannah.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nSteve\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nposted a really cool demo showing off some of his work on the new iOS graphics pipeline, specifically the perspective transform. Perspective transform allows us to rotate elements in a 3 dimensional space to create pretty nifty effects. Right now this is only supported on iOS devices (since Java SE doesn’t really support it, only thru FX) we are still looking into the Android implementation\u003c/p\u003e","title":"Perspective Transform"},{"content":"\nCodename One inherited basic layout concepts from Swing which in turn inherited them from AWT. We modernized and adapted them quite a bit by removing various behaviors and adding others, but a key to sizing and placing components is the preferred size.\nEvery component calculates its own preferred size in the calcPreferredSize() method. This calculation takes into account the font, icon, padding and theme to\nproduce the space required by the given component but sometimes that’s not good enough.\nPreferred size is just one of the values the layout managers take into account when placing components; so you can use layout managers in pretty much any way you want to achieve the desired placement. However, there was one use case that was remarkably elusive for us with this approach: sizing a group of components to have the same size.\nNormally, we would do this by finding the largest preferred size in the group then invoke setPreferredSize on all the various components. This is hugely problematic since its both a hassle and changes to the theme, text etc. of a component in the group wouldn’t be reflected. Now we have a solution: Component.setSameWidth(Component… c); \u0026amp; setSameHeight(Component… c)\nSo we can effectively do something like Component.setSameWidth(cmp1, cmp2, cmp3, cmp4); and they would all have the same preferred width that will be maintained even if we change the text of one of the components. Since that is the biggest use case for setPreferredSize()/W()/H() we are effectively deprecating these methods. Its generally bad practice to use them and would restrict the portability of your code so we highly recommend you use an alternative means for sizing components.\nOne of our enterprise developers pointed out functionality in iOS7 that allows swiping back a form to the previous form. This is pretty hard to accomplish in Codename One because we expect transitions to be non-interactive. However, we decided to pick up that challenge since we want to upgrade transitions for iOS/Android to more closely match the new designs (e.g. Material) so we added a new API to enable back swipe transition: SwipeBackSupport.bindBack(Form currentForm, LazyValue\u0026lt;Form\u0026gt; destination);\nThat one command will enable swiping back from currentForm. LazyValue is a new interface that we will probably use quite often moving forward, its defined as:\npublic interface LazyValue\u0026lt;T\u0026gt; { public T get(Object… args); } Which effectively allows us to pass a form and only create it as necessary (e.g. for a GUI builder app we don’t have the actual previous form instance),\nnotice that the arguments aren’t used for this case but will be used in other cases (and are used in some new capabilities in the motion).\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — July 3, 2014 at 5:38 am (permalink) Anonymous says:\nHi Shai,\nYou mention many nice new features in your blogs, but unfortunately sometimes, they get lost especially for new comers using your framework. Summarizing these features into your news letters are nice but still they get lost. Is it possible to have a section in the CodenameOne users manual on these critical fundamentals you talk about in your blog so it won’t be easily forgotten? You don’t have to rewrite, just a short description and a link to the blog post so we can refer to it further.\nThanks.\nAnonymous — July 3, 2014 at 11:25 am (permalink) Anonymous says:\nHi,\nWhen making a point release we refresh the PDF for the developer guide with the various posts from the blog so they won’t get lost moving forward.\nUpdating the guide continuously is both tedious and problematic since things often change too fast and by the time we reach a point release a specific post might no longer be relevant.\nAnonymous — July 6, 2014 at 6:25 pm (permalink) Anonymous says:\nIn my ListCellRenderer’s I quite often have:\nint h = Display.getInstance().convertToPixels(8, false);\nsetPreferredH(h);\nto set each cell to a comfortable height for selecting a row. If this method is to be deprecated, how should I do this ?\nAnonymous — July 7, 2014 at 2:51 am (permalink) Anonymous says:\nsetPreferredH/W are particularly bad since they rely on the existing preferred height/width which might create unintended results.\nYour approach would be problematic since the font size might be very different between various platforms (e.g. TV/Watch have very different font/DPI densities).\nYou need to define a rendering prototype for a list (which will also make it faster) that includes the exact type of data that will give it the right size e.g. the text XXXXXXXXXXXXX and this will be used to calculate the height of the list element to match the text/images that you provide.\nAnonymous — July 7, 2014 at 3:11 am (permalink) Anonymous says:\nThis is the render constructor:\npublic OptionsRenderer(Resources res) {\nint h = Display.getInstance().convertToPixels(8, false);\nsetPreferredH(h);\ntitle = new Label();\ntitle.setUIID(\u0026ldquo;MyLabel\u0026rdquo;);\nsetLayout(new BorderLayout());\naddComponent(BorderLayout.WEST, title);\nsetUIID(\u0026ldquo;Underline\u0026rdquo;);\nfocus = new Label(\u0026quot;\u0026quot;);\nfocus.setUIID(\u0026ldquo;UnderlineSelected\u0026rdquo;);\n}\nI want every cell to be 8mm (or thereabouts) high. I thought convertToPixels took account of DPI etc ?\nAnonymous — July 7, 2014 at 11:20 am (permalink) Anonymous says:\nIt takes account of DPI (when applicable) but keep in mind that DPI != font size. E.g. TV is at least 40 inches thus even though its theoretically HD its really low DPI since you sit very far from it. A watch has a ridiculously high DPI on the other hand.\nHardcoding 8 might not look good in all the ranges you want to size these things based on the content and the content is determined by the renderingPrototype. Your renderer wouldn’t matter and you won’t need to change the preferred size, it would \u0026ldquo;just work\u0026rdquo;.\nAnonymous — July 7, 2014 at 6:24 pm (permalink) Anonymous says:\nI take on board what you say, but what I’m trying to achieve is a minimum list cell height so that the list cells are easy to select. If a list cell has only a label, the height is obviously determined by the font/DPI etc, but on a regular sized phone, the cells are not big enough to be easily selected and I’d like some way to make sure they are atleast 8mm high.\nAnonymous — July 7, 2014 at 6:25 pm (permalink) Anonymous says:\nFYI – each time I press \u0026ldquo;Submit\u0026rdquo; here I get this message:\n\u0026ldquo;There was an error submitting your comment. Please try again\u0026rdquo;\nAnonymous — July 8, 2014 at 1:47 am (permalink) Anonymous says:\nOdd. I’m not getting that error.\nYou can have an entry occupy two lines not just one line, this depends on the content of your prototype. You can also add padding to the UIID.\nGenerally one line will indeed be smaller than 8mm. However, 8mm on a watch is an entirely different thing from 8mm on a television so its probably not a good idea to code something like this to the height of the row. If it were just padding this wouldn’t be a big deal but for actual row height you would get cut off rows etc.\nAnonymous — July 8, 2014 at 2:50 am (permalink) Anonymous says:\nI’ve changed my code to do this:\ndesc = new Label();\nint h = Display.getInstance().convertToPixels(8, false);\nsetPreferredH(desc.getPreferredH() \u0026lt; h ? h : desc.getPreferredH());\nwhich should be OK for all except perhaps watches.\nAnonymous — July 8, 2014 at 11:53 am (permalink) Anonymous says:\nThis can work. Just to be clear, we have no intention of removing those methods. Just discouraging their use which we always deemed problematic at best.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/same-size-back-swipe/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/same-size-back-swipe/same-size-back-swipe-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/same-size-back-swipe/same-size-back-swipe-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One inherited basic layout concepts from Swing which in turn inherited them from AWT. We modernized and adapted them quite a bit by removing various behaviors and adding others, but a key to sizing and placing components is the preferred size.\u003c/p\u003e\n\u003cp\u003eEvery component calculates its own preferred size in the calcPreferredSize() method. This calculation takes into account the font, icon, padding and theme to\u003c/p\u003e\n\u003cp\u003eproduce the space required by the given component but sometimes that’s not good enough.\u003c/p\u003e","title":"Same Size \u0026 Back Swipe"},{"content":"\nWould you like to go to\nJavaOne\n? Besides being a cool conference its loads of fun with shows and events thru-out the city.\nNow you have a chance,\nCodename One\nand\nJava Code Geeks\nhave teamed up to give away TWO full passes (worth $1,650 each) and to win all you need to do is:\n– Retweet this tweet:\n[\n@Codename_One \u0026amp; @javacodegeeks are giving away full @JavaOneConf passes (worth $1650 each) retweet and click http://t.co/DPWni36AaU to win — Java Code Geeks (@javacodegeeks) June 30, 2014\n](https://twitter.com/javacodegeeks/statuses/483499905978490880)\nand/or\n– Share this Facebook post:\n[\nCodename One and Java Code Geeks are giving away free Java One passes worth $1,650 each! To win share this post and follow the instructions here: http://t.co/DPWni36AaU Posted by Java Code Geeks on Sunday, June 29, 2014 ](https://www.facebook.com/javacodegeeks/posts/690259861009205)\nFinally fill out the form\nhere\n(notice only fill it once and don’t cheat or you will be disqualified!).\nWe will hold a random draw based on the rules listed in the form then publish the results on July 15th 2014. Tickets will be handed out by the end of July.\nGood Luck!\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — July 9, 2014 at 7:17 am (permalink) Anonymous says:\nTweeted, Facebooked –\u0026gt; Tickets pleaaase 🙂\nAnonymous — July 9, 2014 at 11:37 am (permalink) Anonymous says:\nIf you submitted the form then its up to the guys at Java Code Geeks to raffle based on the rules highlighted in the contest form.\nAnonymous — July 9, 2014 at 7:22 pm (permalink) Anonymous says:\nHi Shai,\nWill you be holding a stall anywhere else apart from the conference? I saw that the tickets are very expensive. I recently moved to SF and would like to meet the code name one team. Do let me know if you guys are holding stalls anywhere else.\nThanks,\nNikhil Dahake\nAnonymous — July 10, 2014 at 1:41 am (permalink) Anonymous says:\nHi,\nI don’t think there is an option to do that and we will practically be flying in/out right away so we won’t spend much time in the states.\nHowever, J1 has a discover pass that doesn’t allow much and should cost roughly $50. It allows you to see the pavilion booths and the big announcements/general sessions (if I remember correctly). I’m not sure if this is something you can buy via Oracles site, if not we might be able to provide you with access to such a pass.\nAnonymous — July 10, 2014 at 2:36 pm (permalink) Anonymous says:\nHi Shai,\nWould the discover pass allow me to visit the CN 1 booth? The pass is retailing for $50 currently.\nThanks,\nNikhil\nAnonymous — July 11, 2014 at 1:35 am (permalink) Anonymous says:\nI think so. I never had such a pass since I always had a speaker pass. You should check that it provides pavilion access which is where the booths should be.\nAnonymous — July 11, 2014 at 9:21 pm (permalink) Anonymous says:\nYes, the disover pass allows you access to the exhibition hall and thats where the booth will be. I got myself a discover pass. Will visit your booth 🙂\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-java-code-geeks-are-giving-away-free-javaone-tickets-worth-3300/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-java-code-geeks-are-giving-away-free-javaone-tickets-worth-3300/codename-one-java-code-geeks-are-giving-away-free-javaone-tickets-worth-3300-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"JavaOne 2014 exhibiting\" loading=\"lazy\" src=\"/blog/codename-one-java-code-geeks-are-giving-away-free-javaone-tickets-worth-3300/codename-one-java-code-geeks-are-giving-away-free-javaone-tickets-worth-3300-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWould you like to go to\u003cbr\u003e\n\u003ca href=\"https://www.oracle.com/javaone/index.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nJavaOne\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n? Besides being a cool conference its loads of fun with shows and events thru-out the city.\u003c/p\u003e\n\u003cp\u003eNow you have a chance,\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nCodename One\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nand\u003cbr\u003e\n\u003ca href=\"http://www.javacodegeeks.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nJava Code Geeks\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nhave teamed up to give away TWO full passes (worth $1,650 each) and to win all you need to do is:\u003c/p\u003e\n\u003cp\u003e– Retweet this tweet:\u003cbr\u003e\n[\u003c/p\u003e","title":"Codename One \u0026 Java Code Geeks are giving away free JavaOne Tickets (worth $3,300)!"},{"content":"\nWe’ve been spending an excessive amount of time tuning our garbage collection and memory management of the new iOS VM based on profiler output. This is one of the cool features in the approach we took (translating Java to C rather than going directly to machine code), we can use Apple’s nifty profiling tools to see where the CPU/GPU spend their time.\nAfter quite a few profiling sessions it became apparent that the GC is the main reason for the performance overhead. Further digging showed that mutexes were the real issue here.\nOur GC is non-blocking and concurrent which means it runs in a separate thread and never stops the world during collection. However, in order to track all the memory we use a wrapper around malloc which has to be threadsafe and stores all the objects allocated. This allows our memory sweep algorithm to remove all objects that are no longer used, the problem is that access to this global pool must be synchronized…\nTo solve this problem we rethought the basic concept behind this, now the pool is managed by a single thread that stores/removes elements. Every thread has a set of objects that it allocated since the last GC and every time a GC runs it copies the newly created objects to the global sweep pool and wipes the slate. This effectively removes all synchronization from the very expensive allocation process which is pretty cool.\nOn a separate subject our Codename One workshop for\nJavaZone\njust got accepted, that is pretty cool!\nI really\nenjoyed JavaZone last year\nand felt it exceeded JavaOne in many aspects. This would actually be a workshop session where you can learn Codename One programming from me in person, it would be great seeing Codename One developers there.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/garbage/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/garbage/garbage-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/garbage/garbage-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve been spending an excessive amount of time tuning our garbage collection and memory management of the new iOS VM based on profiler output. This is one of the cool features in the approach we took (translating Java to C rather than going directly to machine code), we can use Apple’s nifty profiling tools to see where the CPU/GPU spend their time.\u003c/p\u003e\n\u003cp\u003eAfter quite a few profiling sessions it became apparent that the GC is the main reason for the performance overhead. Further digging showed that mutexes were the real issue here.\u003c/p\u003e","title":"Garbage Collection"},{"content":"\nWhen we introduced the idea of the EDT from Swing (and pretty much any modern UI toolkit) into what eventually became Codename One, one of the chief benefits was modal dialogs. Its the ability to block the executing thread in order to ask the user a question, that’s a very powerful tool for a developer. As a result of that we defined modal dialogs the way Swing/AWT defined them: stopping the execution of the code.\nHowever, there is another definition… Dialogs that block the rest of the UI…\nIn that regard all dialogs in Codename One are modal; they block the parent form since they are really just forms that show the \u0026ldquo;parent\u0026rdquo; in their background as a simple image. A while back we showed you how to\n\u0026ldquo;fake\u0026rdquo; a dialog\n, which is pretty cool. We ended up using this technique a few times until eventually we asked ourselves: \u0026ldquo;Shouldn’t this be a part of the framework?\u0026rdquo;.\nWell, now it is. We just added InteractionDialog to Codename One which tries to be very similar to Dialog in terms of API but unlike dialog it never blocks anything. Not the calling thread or the UI.\nIts really just a container that is positioned within the layered pane. Notice that because of that design you can have only one such dialog at the moment and if you add something else to the layered pane you might run into trouble.\nUsing the interaction dialog is be pretty trivial and very similar to dialog:\nfinal InteractionDialog dlg = new InteractionDialog(\u0026#34;Hello\u0026#34;); dlg.setLayout(new BorderLayout()); dlg.addComponent(BorderLayout.CENTER, new Label(\u0026#34;Hello Dialog\u0026#34;)); Button close = new Button(\u0026#34;Close\u0026#34;); close.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { dlg.dispose(); } }); dlg.addComponent(BorderLayout.SOUTH, close); Dimension pre = dlg.getContentPane().getPreferredSize(); dlg.show(0, 0, Display.getInstance().getDisplayWidth() – (pre.getWidth() + pre.getWidth() / 6), 0); This will show the dialog on the right hand side of the screen, which is pretty useful for a floating in place dialog.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — June 25, 2014 at 1:50 am (permalink) Anonymous says:\nIs my understanding correct: the ‘fake’ dialog is the component with focus, so no events got to the parent form, but because the parent form is ‘live’ under the dialog, the UI of the parent form can be updated from the dialog ? (Unlike in ‘real’ dialogs where the parent form is just a static ‘background’ to to the dialog).\nIf there is no need to update the parent form is there any particular reason to prefer one over the other ?\nAnonymous — June 25, 2014 at 1:19 pm (permalink) Anonymous says:\nIs there something that we need to do apart from refreshing libs. I am not able to add this code snnipet and test it as InteractionDialog is not available.\nAnonymous — June 25, 2014 at 4:21 pm (permalink) Anonymous says:\nWith current Dialogs the dialog takes over the entire screen so you can’t drag a widget from a dialog to the form beneath it or some other unique use cases.\nFor 98% of the cases I’d just use dialogs, this is a special case tool.\nAnonymous — June 25, 2014 at 4:22 pm (permalink) Anonymous says:\nYou will need to use Update Client Libs (not refresh libs which is something else) when this is updated. Since we didn’t update the plugin yet this is only available by building the source right now. The plugin will probably be refreshed sometime next week.\nAnonymous — July 13, 2014 at 6:58 am (permalink) Anonymous says:\nGood! However, is there a way the interaction dialog can listen to events like if outside of the bounds of the dialog is clicked/touched so the dialog can animate or close. Can we determine if the interaction dialog is showing? For example dialog.isShowing(). I see some interesting use cases like in the new google plus app.\nAnonymous — July 13, 2014 at 11:46 am (permalink) Anonymous says:\nJust add a pointer listener to the parent form to see. A dialog is showing method would probably be useful, feel free to file an RFE on that into the issue tracker.\nAnonymous — December 1, 2014 at 10:33 pm (permalink) Anonymous says:\nPointer pressed not solvingthat because the pointer press is also passed through the InteractionDialog to the parent form\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/not-a-dialog-again/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/not-a-dialog-again/not-a-dialog-again-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/not-a-dialog-again/not-a-dialog-again-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen we introduced the idea of the EDT from Swing (and pretty much any modern UI toolkit) into what eventually became Codename One, one of the chief benefits was modal dialogs. Its the ability to block the executing thread in order to ask the user a question, that’s a very powerful tool for a developer. As a result of that we defined modal dialogs the way Swing/AWT defined them: stopping the execution of the code.\u003c/p\u003e","title":"Not A Dialog – Again"},{"content":"\nSome features we have in Codename One are a bit hidden behind the surface, we add them as a patch for a developer and don’t have the proper place to document them so they get buried. Case in point is the ability in Android to use the search magnifier icon instead of the done button. To get that functionality you can just set a client property on the relevant text field as such:\nDisplay.getInstance().putClientProperty(\u0026quot;searchField\u0026quot;, Boolean.TRUE);\nThis also allows other options such as sendButton \u0026amp; goButton.\nOn an unrelated note we are now making some progress on the new\nAndroid graphics pipeline\nimplementation which should hopefully allow us to scale our graphics further. We also made quite a few improvements to the new Codename One VM on iOS squashing quite a few bugs. However, more issues and performance penalties remain so we are still actively improving this. If you have test cases and issues specific to the VM please let us know so we can address them and move this new VM to a production quality product.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — October 30, 2014 at 3:16 pm (permalink) Anonymous says:\nHow do i listen to the done or search event when the user presses either the search button or send. I want to capture the event. Also, instead of the search icon, can I set the text to something like \u0026ldquo;create\u0026rdquo;?\nAnonymous — October 30, 2014 at 9:53 pm (permalink) Anonymous says:\ngoButton instead of searchButton might produce something that’s closer to what you want.\nYou can just use action listener to get the event of text input completion.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/keyboard-keys-android-pipeline/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/keyboard-keys-android-pipeline/keyboard-keys-android-pipeline-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/keyboard-keys-android-pipeline/keyboard-keys-android-pipeline-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eSome features we have in Codename One are a bit hidden behind the surface, we add them as a patch for a developer and don’t have the proper place to document them so they get buried. Case in point is the ability in Android to use the search magnifier icon instead of the done button. To get that functionality you can just set a client property on the relevant text field as such:\u003c/p\u003e","title":"Keyboard Keys \u0026 Android Pipeline"},{"content":"\nWe neglected to mention in our last post about the new graphics pipeline that it was authored by Steve Hannah who did a splendid job there! He just updated the shaders for the implementation to be far more efficient bringing performance back to the current levels. The true value of this architecture is that now we will be able to manipulate shaders for very complex effects at relatively low cost.\nWe are also integrating some improvements into the Android drawing pipeline which should incorporate some of these features in the new Android pipeline architecture. Notice that the new pipeline is only in effect for Android 3.x or higher and seamlessly uses a legacy pipeline for 2.x devices.\nThe\nnative map implementation\nhad an issue with detecting pointer events, since its a\npeer component\nyou couldn’t necessarily monitor the standard pointer events. So we added a new API allowing you to addTapListener to a map that would broadcast an event from a native map with an x/y location.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/performance-map-taps/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/performance-map-taps/performance-map-taps-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/performance-map-taps/performance-map-taps-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe neglected to mention in our last post about the new graphics pipeline that it was authored by Steve Hannah who did a splendid job there! He just updated the shaders for the implementation to be far more efficient bringing performance back to the current levels. The true value of this architecture is that now we will be able to manipulate shaders for very complex effects at relatively low cost.\u003c/p\u003e","title":"Performance \u0026 Map Taps"},{"content":"\nFinally the new graphics pipeline is starting to trickle into the JavaSE port and the iOS port \u0026amp; once we iron those two out it should make its way into the Android port.\nWith this in place we are finally at a point of functionality similar to JavaFX but without the overhead and performance implications that FX carries with it.\nThe new pipeline includes new API’s for shapes, affine/perspective transforms and more. Notice that unless you are a graphics geek these things won’t mean much to you, but these things allow us to expose complex features (e.g. high performance charts, special effects) thru the high level API’s. Since not all devices will support these capabilities we they each include an is*Supported method in Graphics and if your painting code needs access to that capability it should test that availability and provide a reasonable fallback. Right now most of the capabilities should be supported for iOS and Java SE with Android support arriving later.\nNotice that even when supported some features can’t be exposed on all platforms, e.g. perspective transform isn’t available on our current JavaSE port and might not be available in the future since Java2D doesn’t support that. JavaFX introduced some form of perspective transform but this effectively means rewriting a great deal of code to use the JavaFX API’s which is a non-trivial task. Hopefully this will be easier to integrate on the Android front.\nTo enable the new pipeline on iOS you will need to use the build argument ios.newPipeline=true\nIts currently off by default to maximize compatibility and prevent regressions, however we recommend that you test your apps with this flag even if you don’t currently need this feature so we can be ready for flipping the default state for this switch.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — June 12, 2014 at 9:14 pm (permalink) Anonymous says:\nDoes the Android version use Opengl for drawing or draws in Canvas? How suitable is this for intense animations or games?\nAnonymous — June 13, 2014 at 2:44 am (permalink) Anonymous says:\nNo. We use different things based on the version of Android since performance changed completely between 2.x and 4.x.\nWe generally draw on canvas since we need integration with native widgets that might be problematic if we use OpenGL. We might provide an OpenGL API in the future for gaming purposes.\nOur current focus is on apps and to a lesser degree on lightweight games. If you have a need for intense animations or high framerate animations you would probably need to use native code at this time.\nAnonymous — June 16, 2014 at 9:00 am (permalink) Anonymous says:\nSounds great, thanks!\nIs there some discussion (javadoc or methods list) regarding the API released with this new graphics pipeline ?\nThank you !\nAnonymous — June 16, 2014 at 1:08 pm (permalink) Anonymous says:\nNot much, but the Graphics class and the geom package should contain all the relevant methods/classes.\nAnonymous — June 17, 2014 at 11:46 am (permalink) Anonymous says:\nThanks, I will have a look.\nDoes this new graphic pipeline has any impact regarding the need to change the gradiant definition of a background by a picture (for permance issues) ?\nthanks\nAnonymous — June 17, 2014 at 4:49 pm (permalink) Anonymous says:\nNot yet. However, since we use shaders many special effects can be moved into the pipeline such as gradients, shaped clipping, etc. We are reserving these to future incremental enhancements based on user feedback.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-graphics-pipeline/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-graphics-pipeline/new-graphics-pipeline-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/new-graphics-pipeline/new-graphics-pipeline-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eFinally the new graphics pipeline is starting to trickle into the JavaSE port and the iOS port \u0026amp; once we iron those two out it should make its way into the Android port.\u003c/p\u003e\n\u003cp\u003eWith this in place we are finally at a point of functionality similar to JavaFX but without the overhead and performance implications that FX carries with it.\u003c/p\u003e\n\u003cp\u003eThe new pipeline includes new API’s for shapes, affine/perspective transforms and more. Notice that unless you are a graphics geek these things won’t mean much to you, but these things allow us to expose complex features (e.g. high performance charts, special effects) thru the high level API’s. Since not all devices will support these capabilities we they each include an is*Supported method in Graphics and if your painting code needs access to that capability it should test that availability and provide a reasonable fallback. Right now most of the capabilities should be supported for iOS and Java SE with Android support arriving later.\u003c/p\u003e","title":"New Graphics Pipeline"},{"content":"\nOne of the things we’ve been missing is a simple \u0026ldquo;navigate\u0026rdquo; feature that allows you to launch the devices native navigation software with a fixed destination. This was relatively simple to hack together using Display.execute but that’s not the same as an official API. Chen just added two methods to Display that should really help in this process: isOpenNativeNavigationAppSupported \u0026amp; openNativeNavigationApp(lat, lon). This should launch the device navigation software (e.g. Google Maps) with the given destination.\nAs you might recall building an iOS native app requires 7 screenshots, this slows the build a bit (depends on your apps functionality though), to slightly speed up your build you can use the build argument ios.fastbuild=true which will use hardcoded splash screen images (notice that this will only work for debug builds not for appstore builds). For the kitchen sink this shaves roughly 15 seconds from the startup time, but it might shave minutes off your build for a complex app.\nWe have some pretty big changes that landed last week, but we’ll write about them later this week.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — June 20, 2014 at 4:17 am (permalink) Anonymous says:\nThanks for including this feature. Tested on Android and iOS and it worked perfectly. I will like to know if this functionality will work on windows phone by opening Here Drive or similar navigator?\nAnonymous — June 20, 2014 at 1:31 pm (permalink) Anonymous says:\nAt the moment this isn’t supported on Windows Phone.\nAnonymous — June 21, 2014 at 8:58 am (permalink) Anonymous says:\nTried it on Nokia X device running Android OS, it works perfectly by opening Nokia Here Drive. Hopefully it will work on Windows Phone. Thanks once again for this feature…I have been waiting for it\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/navigate-faster-builds/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/navigate-faster-builds/navigate-faster-builds-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/navigate-faster-builds/navigate-faster-builds-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the things we’ve been missing is a simple \u0026ldquo;navigate\u0026rdquo; feature that allows you to launch the devices native navigation software with a fixed destination. This was relatively simple to hack together using Display.execute but that’s not the same as an official API. Chen just added two methods to Display that should really help in this process: isOpenNativeNavigationAppSupported \u0026amp; openNativeNavigationApp(lat, lon). This should launch the device navigation software (e.g. Google Maps) with the given destination.\u003c/p\u003e","title":"Navigate \u0026 Faster Builds"},{"content":"\nSimplified webservice access has long been on our todo list and we now finally have a tool that significantly simplifies server communications in Codename One to a method call level. We just posted a\nHow Do I? video\nfor this feature and will launch it with the plugin update next week. The feature is remarkably simple in concept, you define a set of methods and get a client class coupled with some server classes so you can invoke server functionality directly from the mobile.\nIn order to support SOAP/REST and other standard protocols just use the far superior Java EE webservice capabilities and use the webservice merely as a proxy for that purpose. Since the calls are binary their overhead is remarkably low both on the wire and don’t require any real parsing resulting in much faster communications when compared to SOAP, REST \u0026amp; even to GWT’s RPC.\nIf you are familiar with GWT’s RPC you should feel pretty much at home, although we did simplify some concepts. One of the cool features we offer in contrast to GWT is the ability to invoke methods synchronously thanks to the fact that we do have access to threads. This makes RPC logic far more intuitive and transactional.\nThanks to all of you who sent valuable feedback in regards to this feature!\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — June 8, 2014 at 5:57 pm (permalink) Anonymous says:\nMost of my apps use a REST interface to a PHP/MySQL backend.\nI use GZConnectionRequest and read JSON back from the server – sometimes this JSON is quite heavy like 300-400kb other times its 1kb or even less.\nIs there any advantage to adding this system in between that communication and running a java server for this? Or is it just really additional complexity in this case?\nAnonymous — June 9, 2014 at 2:17 am (permalink) Anonymous says:\nIts hard to tell. REST is relatively efficient but the overhead of gzip/parsing might be significant. OTOH a proxy might also pose an overhead.\nI suggest testing this with just one API and benchmarking.\nOur goal here wasn’t just to make things faster, it was mostly to make things simpler. Since you already implemented the REST calls tht goal should be less of an issue.\nAnonymous — June 9, 2014 at 6:32 pm (permalink) Anonymous says:\nSimpler is good though. I don’t think I’ll refactor a working project at this stage, but will try this out on new projects.\nAnonymous — July 1, 2014 at 6:00 am (permalink) Anonymous says:\nJust tried this out. Very slick. Well done !\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/webservice-wizard/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/webservice-wizard/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eSimplified webservice access has long been on our todo list and we now finally have a tool that significantly simplifies server communications in Codename One to a method call level. We just posted a\u003cbr\u003e\n\u003ca href=\"/how-do-i---access-remote-webservices-perform-operations-on-the-server.html\"\u003e\u003cbr\u003e\nHow Do I? video\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nfor this feature and will launch it with the plugin update next week. The feature is remarkably simple in concept, you define a set of methods and get a client class coupled with some server classes so you can invoke server functionality directly from the mobile.\u003c/p\u003e","title":"Webservice Wizard"},{"content":"\nWriting native code in Codename One is pretty simple, however one piece is relatively vague and that is the ability to call back from native code into the Java code. The reason we left this relatively vague is due to the complexity involved in exposing/documenting this across multiple OS’s/languages so we chose to document this on a case by case basis.\nA common trick for calling back is to just define a static method and then trigger it from native code. This works nicely for Android, J2ME \u0026amp; Blackberry however mapping this to iOS requires some basic understanding of how the iOS VM works. Worse, due to the changes we made in the new VM if you are using such code you will need to adapt it as we migrate to the new VM or your code will stop working.\nFor the purpose of this explanation lets pretend we have a class called NativeCallback in the src hierarchy under the package com.mycompany that has the method: public static void callback().\nSo if we want to invoke that method from Objective-C we normally would have just done the following. Added an include as such:\n#include \u0026ldquo;com_mycompany_NativeCallback.h\u0026rdquo;\nThen when we want to trigger the method just do:\ncom_mycompany_NativeCallback_callback__();\nThis will not compile with the new VM. The new VM now passes the thread context along method calls to save on API calls (thread context is heavily used in Java for synchronization, gc and more). However, to keep code compatible we added a few macros that allow us to maintain XMLVM/newVM portability and they are defined as blank when running under XMLVM. So to do something like this in the new VM all we need to do is add an include for CodenameOne_GLViewController.h as such:\n#include \u0026ldquo;CodenameOne_GLViewController.h\u0026rdquo;\nThen we can invoke the method like this:\ncom_mycompany_NativeCallback_callback__(CN1_THREAD_STATE_PASS_SINGLE_ARG);\nBut what if we defined the method as such: public static void callback(int arg)\nThis would map under XMLVM to something like this:\ncom_mycompany_NativeCallback_callback___int(intValue);\n(notice the extra _ before int). You can adapt this for the new VM like this:\ncom_mycompany_NativeCallback_callback___int(CN1_THREAD_GET_STATE_PASS_ARG intValue);\nNotice that there is no comma between the CN1_THREAD_GET_STATE_PASS_ARG and the value! This is important since under XMLVM CN1_THREAD_GET_STATE_PASS_ARG is defined as nothing, yet under the new VM it will include the necessary comma. Its not an ideal solution but it solves the portability issue as we slowly migrate to the new VM.\nMany of you have been passing string values to the Java side, or really NSString* which is iOS equivalent. So assuming a method like this: public static void callback(String arg)\nYou would need to convert the NSString value you already have to a java.lang.String which the callback expects. We used to do this as such:\ncom_mycompany_NativeCallback_callback___int(fromNSString(nsStringValue));\nHowever, the from NSString method also needs this special argument so you will need to modify the method as such:\ncom_mycompany_NativeCallback_callback___int(CN1_THREAD_GET_STATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG nsStringValue));\nAnd finally you might want to return a value from callback as such: public static int callback(int arg)\nThis is tricky since we had to change the method signatures to support covariant return types and so the signature of that method under XMLVM would be:\ncom_mycompany_NativeCallback_callback___int(intValue);\nBut under the new VM it is:\ncom_mycompany_NativeCallback_callback___int_R_int(intValue);\nThe upper case R allows us to differentiate between void callback(int,int) and int callback(int). Unfortunately portability here isn’t trivial so ifdef’s are the only way. What we do is something like this:\n#ifdef NEW_CODENAME_ONE_VM\nJAVA_INT val = com_mycompany_NativeCallback_callback___int_R_int(intValue);\n#else\nJAVA_INT val = com_mycompany_NativeCallback_callback___int(intValue);\n#endif\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — October 22, 2014 at 4:14 am (permalink) Anonymous says:\nShould public static void callback(String arg) translate to\ncom_mycompany_NativeCallback_callback___java_lang_String(CN1_THREAD_GET_STATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG nsStringValue));\nand not\ncom_mycompany_NativeCallback_callback___int(CN1_THREAD_GET_STATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG nsStringValue));\n?\nAnonymous — October 23, 2014 at 12:30 am (permalink) Anonymous says:\nThanks, yes I missed that one. Sorry.\nAnonymous — December 4, 2014 at 12:27 pm (permalink) Anonymous says:\nFor me it is unclear, when should be used\nCN1_THREAD_STATE_PASS_ARG\nand when\nCN1_THREAD_GET_STATE_PASS_ARG\n?\nIt is clear, that when threadStateData is not available in current context, then we have to use CN1_THREAD_GET_STATE_PASS_ARG, but do we need it also when threadStateData is available?\nFor example in iOSPort/nativeSources/CodenameOne_GLViewController.m line 334 is like this:\nstr = com_codename1_ui_plaf_UIManager_localize___java_lang_String_java_lang_String_R_java_lang_String(CN1_THREAD_STATE_PASS_ARG obj, fromNSString(CN1_THREAD_GET_STATE_PASS_ARG @\u0026ldquo;next\u0026rdquo;), fromNSString(CN1_THREAD_GET_STATE_PASS_ARG @\u0026ldquo;Next\u0026rdquo;));\ndoes it mean, that sometimes we need to use CN1_THREAD_GET_STATE_PASS_ARG even when threadStateData variable is available in current context?\nAnonymous — December 5, 2014 at 3:26 am (permalink) Anonymous says:\nThe defines are:\n#define CN1_THREAD_STATE_PASS_ARG threadStateData,\n#define CN1_THREAD_GET_STATE_PASS_ARG getThreadLocalData(),\nObviously the former will fail if there is no threadStateData variable in the current context (e.g. if you are in a callback from native). In most cases when writing a native interface you will need to use the latter form.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/native-ios-code-callbacks/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/native-ios-code-callbacks/native-ios-code-callbacks-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/native-ios-code-callbacks/native-ios-code-callbacks-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWriting native code in Codename One is pretty simple, however one piece is relatively vague and that is the ability to call back from native code into the Java code. The reason we left this relatively vague is due to the complexity involved in exposing/documenting this across multiple OS’s/languages so we chose to document this on a case by case basis.\u003c/p\u003e\n\u003cp\u003eA common trick for calling back is to just define a static method and then trigger it from native code. This works nicely for Android, J2ME \u0026amp; Blackberry however mapping this to iOS requires some basic understanding of how the iOS VM works. Worse, due to the changes we made in the new VM if you are using such code you will need to adapt it as we migrate to the new VM or your code will stop working.\u003c/p\u003e","title":"Native iOS Code Callbacks"},{"content":"\nWe are making good progress on our new iOS VM and are starting to test a much wider range of apps. The VM is still experimental however many features that didn’t work such as native interfaces, build flags etc. should now function as expected and perform well.\nBuild times are still longer than Android build times and this can be attributed in a large part to\nthe screenshot process\nand the fact that we still have a lot to compile. The compilation is not as fast as we would like it to be due to the overhead of reference counting and GC both of which are compiled directly into the code. This means more lines of code and thus more complexity for the compiler to tackle. However, the performance is still much better and the compile times are already shorter than the original XML VM backend.\nOur team is currently in the process of generating a simplified webservices API/wizard that would allow you to easily invoke server side functionality within your own custom server. We are currently thinking about something very similar to the GWT request response however unlike the GWT approach we plan to offer both synchronous and asynchronous API’s (which GWT can’t offer). This would mean that in order to use this API you will need a proxy server to intercept client calls then forward them to your actual webservice functionality (notice that if you use Java on the server this just means adding a servlet and some classes that we will generate for you. We are soliciting feedback for this so if you have a strong opinion/view on this now is the time to speak up!\nOn a completely different subject we added some error handling API’s to the ImageDownloadService which is a frequent RFE.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — May 29, 2014 at 1:26 am (permalink) Anonymous says:\nVery cool. Have you already decided when will you open-source the new iOS VM?\nAnonymous — May 29, 2014 at 2:51 am (permalink) Anonymous says:\nYes, I wrote in a previous post that we intend to open source it once the work is done.\nAnonymous — June 4, 2014 at 5:29 am (permalink) Anonymous says:\nHi,\nThis new VM seems very interesting. However, every time we compiled with the new VM for iOS, we got an error.\nI am not sure where I should send it to you, so I pasted the link below.\nhttps://codename-one.appspo…\nThank you.\nKind regards,\nAnonymous — June 4, 2014 at 2:27 pm (permalink) Anonymous says:\nHi,\nthanks for the report. We broke some things a few days ago with some changes to the Facebook functionality. This should now work as expected.\nAnonymous — June 4, 2014 at 7:21 pm (permalink) Anonymous says:\nHi.\nThank you.\nUnfortunately, the code I sent is still building (more than 2 hours now).\nAnonymous — June 5, 2014 at 12:25 am (permalink) Anonymous says:\nDid you try canceling and resending the build?\nAnonymous — June 5, 2014 at 1:22 am (permalink) Anonymous says:\nHi.\nThank you for your answer.\nI did it after your post. It’s now building since 30 minutes.\nThank you.\nAnonymous — June 5, 2014 at 2:10 am (permalink) Anonymous says:\nMake sure your project binaries aren’t too large (do you have many images/resources). If you used include source uncheck that feature, from the looks of it your build exceeded App Engines size quotas.\nAnonymous — June 5, 2014 at 3:36 am (permalink) Anonymous says:\nThank you for your very prompt answer.\nYes, our theme.res file’s size is more than 80 MB. We do not checked the sources’s option.\nThe problem is we need these pictures (and we have only imported half of them for now).\nIs there a way to delete the smaller resolutions ?\nOr any other advices ?\nThanks again.\nAnonymous — June 5, 2014 at 7:15 am (permalink) Anonymous says:\nOk, I think we will manage with different solutions.\nThank you.\nHow can I change the optipng’s path / file ?\nThanks again.\nAnonymous — June 6, 2014 at 4:29 am (permalink) Anonymous says:\nA theme above 2mb might impact performance and above 10mb would seriously impact performance. A binary over 50mb will not install on Android devices (due to google play limitations).\nYou should dynamically download the images and store them in the local filesystem or storage after application install.\nOptipng can be configured in the advanced menu. You can remove the unnecessary DPI’s from the image advanced menu too.\nAnonymous — June 6, 2014 at 4:32 am (permalink) Anonymous says:\nHi,\nThank you for your advices and precisions.\nI have seen for optipng but I would like to change the path I choose for it the first time. I have tried to remove and re-install my Netbeans Plug-in but I am not able to find where to change this path.\nThank you.\nAnonymous — June 6, 2014 at 1:46 pm (permalink) Anonymous says:\nHi,\nWhat is the technical reason regarding the impact of the theme’s size on the performance ?\nCould we store the pictures inside the executable but not inside the theme (without adding too many weight)?\nOr the only good way to proceed is to download all the images ?\nThank you.\nAnonymous — June 6, 2014 at 3:38 pm (permalink) Anonymous says:\nYou can create multiple res files and also add images to the root.\nSince a resource file is always loaded in its entirety that means all the images will be loaded when you load the theme. So its pretty heavy if you don’t intend to use most of them right away.\nI would still suggest keeping the executable smaller for faster build times and you would still have the 50mb limit.\nAnonymous — June 17, 2014 at 11:32 am (permalink) Anonymous says:\nHi Shai,\nWe have significantly reduced the weight of our executable. And it does compile with the new VM and the new graphic pipeline.\nBut unfortunately, the app crashes (with or without the new graphic pipeline) just after the iOS splash screen.\nexited abnormally with signal 11: Segmentation fault: 11\nAlso, on the simulator and on Android devices, transition between forms is now very very very slow.\nThank you.\nAnonymous — June 17, 2014 at 4:52 pm (permalink) Anonymous says:\nWe made an improvement to the new VM today which might help. If not try isolating functionality to pinpoint the crash and build a test case we can inspect.\nAnonymous — June 17, 2014 at 5:26 pm (permalink) Anonymous says:\nThank you.\nIt’s still not working so we will try to isolate more precisely the crash.\nAnonymous — June 20, 2014 at 5:49 am (permalink) Anonymous says:\nHi Shai,\nWe have started with an empty project. This project is build and we can launch it on our iPhone 5S without any issue.\nOtherwise, as soon as we add URLImage.createToStorage inside the post Show method of the selected form, we only got a black screen.\nThe app didn’t crash but the screen is entirely black.\nI can send you this test project if you want to have a look.\nI develop on a Mac Book Pro, with Mavericks, and Netbeans 7.4. We test the result on iPhone 5S iOS 7.1.1.\nThank you.\nAnonymous — June 20, 2014 at 1:52 pm (permalink) Anonymous says:\nIf you have a test case you can file an issue in the issue tracker here: http://code.google.com/p/co…\nWe only accept code from pro accounts or higher and then after exhausting other options to track the issue.\nAnonymous — June 21, 2014 at 4:21 pm (permalink) Anonymous says:\nI will, thank you.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/vm-updates-webservices/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/vm-updates-webservices/vm-updates-webservices-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/vm-updates-webservices/vm-updates-webservices-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are making good progress on our new iOS VM and are starting to test a much wider range of apps. The VM is still experimental however many features that didn’t work such as native interfaces, build flags etc. should now function as expected and perform well.\u003c/p\u003e\n\u003cp\u003eBuild times are still longer than Android build times and this can be attributed in a large part to\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/3/post/2014/03/the-7-screenshots-of-ios.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nthe screenshot process\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nand the fact that we still have a lot to compile. The compilation is not as fast as we would like it to be due to the overhead of reference counting and GC both of which are compiled directly into the code. This means more lines of code and thus more complexity for the compiler to tackle. However, the performance is still much better and the compile times are already shorter than the original XML VM backend.\u003c/p\u003e","title":"VM Updates \u0026 Webservices"},{"content":"\nThe Facebook native SDK for iOS and Android is difficult. It layers a great deal of complex permissions and concepts that seem obvious for engineers in Facebook but not so obvious for the casual observer. In the past Facebook allowed you to just request a write permission and you would receive such a permission, however recent SDK’s force you to request a read only permission which you then need to elevate to a write permission.\nNot the most intuitive approach although understandable in terms of data security,\nbut it is badly implemented and to make matters worse its horribly broken in some SDK versions (Chen spent the day just because the version we used happened to be such a version). Regardless, we now have the ability to elevate Facebook permissions as part of the Facebook connect API in the social package. You just need to ask for publish permissions and once the callback is invoked with a success message you can write to the Facebook wall.\nA simpler approach is usually to just use the Share button which requires no special permissions so if you just want to share something we would recommend doing that. It maps to native iOS/Android functionality and is pretty powerful since it can map to Twitter and other apps installed on the device too.\nOn a different subject, localization is a pretty easy task in Codename One thanks to the\ni18n support\nbuiltin to our tools. Our i18n tools are unique since they don’t require you to implement anything in the code and you can instantly start localizing without wide sweeping changes. However, the Android APK doesn’t detect our localization as part of your application and might incorrectly assume the APK contains a single language. To combat that we are introducing the build argument: android.locales=local;local;locale\nWhere you can specify the supported languages for the APK, locale can be any 2 letter language code such as fr for French, en for English etc. Notice that these are standard combinations based on an iso standard.\nWe also allow specifying the default language of a Windows Phone app using the win.locale=en-US build argument where you can customize the locale to any one you would like.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/facebook-publish-android-localization/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/facebook-publish-android-localization/facebook-publish-android-localization-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/facebook-publish-android-localization/facebook-publish-android-localization-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe Facebook native SDK for iOS and Android is difficult. It layers a great deal of complex permissions and concepts that seem obvious for engineers in Facebook but not so obvious for the casual observer. In the past Facebook allowed you to just request a write permission and you would receive such a permission, however recent SDK’s force you to request a read only permission which you then need to elevate to a write permission.\u003c/p\u003e","title":"Facebook Publish \u0026 Android Localization"},{"content":"\nWe just updated the build servers with the latest version of the Codename One iOS VM. This is still a work in progress and there is no guarantee your application will work. However, you can start playing with this right now and you might enjoy some of the benefits including proper stack traces, faster builds, smaller code size \u0026amp; faster performance.\nTo try this just define the build argument ios.newVM=true\nAt some point we will flip this to be the default but for now this will still be off.\nNotice that some behaviors such as native interfaces will only be enabled in a few days and other features defined by build arguments might not yet work. However, we are looking for some bugs and crash reports for this functionality so if you run into an issue here feel free to let us know here or on the discussion forum.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/try-the-new-ios-vm/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/try-the-new-ios-vm/try-the-new-ios-vm-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/try-the-new-ios-vm/try-the-new-ios-vm-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe just updated the build servers with the latest version of the Codename One iOS VM. This is still a work in progress and there is no guarantee your application will work. However, you can start playing with this right now and you might enjoy some of the benefits including proper stack traces, faster builds, smaller code size \u0026amp; faster performance.\u003c/p\u003e\n\u003cp\u003eTo try this just define the build argument ios.newVM=true\u003c/p\u003e","title":"Try The New iOS VM"},{"content":"\niOS allows us to send a push notification to trigger a numeric badge on the application icon, this is something you could do with Codename One for quite some time although it was mostly undocumented. You could send a push notification with the type 100 and the number for the badge and that number would appear on the icon, when you launch the app the next time the default behavior is to clear the badge value.\nThere is also an option to send push type 101 and provide a badge number semi-colon and a message e.g. use a message body such as this: \u0026ldquo;3;This message is shown to the user with number 3 badge\u0026rdquo;. Obviously, this feature will only work for iOS so don’t send these push types to other platforms…\nIn addition to that we have added an option to change the badge number, this is useful if you want the badge to represent the unread count within your application. To do this we added two methods to display: isBadgingSupported() \u0026amp; setBadgeNumber.\nNotice that even if isBadgingSupported will return true, it will not work unless you activate push support!\nTo truly utilize this you might need to disable the clearing of the badges on startup which you can do with the build argument ios.enableBadgeClear=false\nOn a separate note we also added the ability to scale images based on aspect ratio\nto the ImageIO class with a new method saveAndKeepAspect which should provide more memory efficient scaling. This is important for Android which manages image memory quite poorly.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — September 4, 2014 at 7:13 am (permalink) Anonymous says:\nI’ve made a mistake in this post. Number badges should be separated by a space not a semicolon so this \u0026ldquo;3;This message is shown to the user with number 3 badge\u0026rdquo; should be really:\n\u0026ldquo;3 This message is shown to the user with number 3 badge\u0026rdquo;\nOmar Suleiman — January 14, 2018 at 12:42 pm (permalink) Omar Suleiman says:\nWe tried more time to find badges with android but as some comments in stackoverflow is only working on IOS, so when will it become available on android? .\nThanks\nShai Almog — January 15, 2018 at 6:45 am (permalink) Shai Almog says:\nHi,\nI’ve answered this here: https://stackoverflow.com/q…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/badges/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/badges/badges-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/badges/badges-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eiOS allows us to send a push notification to trigger a numeric badge on the application icon, this is something you could do with Codename One for quite some time although it was mostly undocumented. You could send a push notification with the type 100 and the number for the badge and that number would appear on the icon, when you launch the app the next time the default behavior is to clear the badge value.\u003c/p\u003e","title":"Badges"},{"content":"\nOne of the great features we’ve added to the new iOS VM is the ability to get proper stack traces without a performance penalty. This is actually pretty easy to implement in a performant way, every entry to a method just registers an integer number representing the method name and class name and every time we reach a line number in the source file we update the current line number. When throwing the exception we just assemble all of that data to produce the exception and the cost in terms of RAM/CPU is very low.\nWe were hoping to expose the build argument for the new VM by now but right now builds are slow for some unclear reason… We have significantly less code in the new VM and its simpler code since it doesn’t include a lot of functionality that was necessary for the full Harmony API. But it builds slower and we are a bit stumped by that…\nWe are busy catching up to the many issues and RFE’s opened by pro/enterprise users during the past few weeks as we were working on the new VM. Some features/fixes of interest include the JSONParser which now has a special mode called setUseLongs(). This mode uses long objects for round values rather than doubles. So a numeric value might be a long or it might be a double.\nBy default the JSON parser always produces Doubles, the reason behind that is that we are missing support for the java.lang.Number class which would have been really useful for this case. Without that class its difficult to write a generic parser so we chose to go only with doubles. However, for larger numbers this is a problem which is why we now also offer the option to generate longs.\nIn addition we made maps within the JSON (key/value pairs) use LinkedHashMap rather than HashMap, this preserves their order from within the JSON after parsing which is important for some use cases.\nWe added an isDesktop method to indicate if we are currently within a Desktop application (similar to isTablet()) and a canDial() method, both of whihc are part of Display. This is important since dialing from Tablets or Desktop machines will naturally fail so you might not want to show a button in the UI that will lead to a dial() invocation.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/changes-stacks/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/changes-stacks/changes-stacks-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/changes-stacks/changes-stacks-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the great features we’ve added to the new iOS VM is the ability to get proper stack traces without a performance penalty. This is actually pretty easy to implement in a performant way, every entry to a method just registers an integer number representing the method name and class name and every time we reach a line number in the source file we update the current line number. When throwing the exception we just assemble all of that data to produce the exception and the cost in terms of RAM/CPU is very low.\u003c/p\u003e","title":"Changes \u0026 Stacks"},{"content":"\nFor the uninitiated, ARC is Apple’s term for Automatic Reference Counting. Objective-C uses a reference counting scenario to collect objects which is pretty painful to work with. Personally I preferred C/C++’s manual delete/free to the Objective-C semantics. But a couple of years ago Apple introduced ARC in which the compiler implicitly inserts the retain/release reference counting logic.\nWhile its a big improvement its still a reference counter with many of the implied limitations. It solves 95% of your memory handling logic leaving the hardest 5% for you to deal with manually but it does have one advantage over a GC: determinism. Since memory is deallocated immediately it provides consistent performance with no GC stalls.\nWe briefly covered the garbage collection approach we took with the new iOS VM, however this time we’ll go more in-depth into the implementation details. Our goal with the garbage collection was not to create the fastest GC possible but the one that stalls the least. Up to now pretty much all open source/iOS VM’s used Boehm GC which is a conservative GC designed for C, it is state of the art and pretty cool but stalls.\nBoehm can’t really avoid stalling since it needs to stop all executing threads so it can traverse their stacks and this takes time…\nUnlike C, we can make a lot of assumptions in a Java application thanks to the type safety and clearly defined VM. This makes the process of collecting comparatively easy and makes it possible to collect without stopping the world. We do however need that threads yield the CPU shortly otherwise the GC will be blocked, this is generally a good practice and the EDT makes sure to follow that practice however if you do something like this:\nwhile(true) { System.out.println(“WHeee”); } It would block our new GC from running unless you add a Thread.yield/sleep or wait() call (besides draining the CPU/battery). This might be considered a flaw but we mitigated that to some degree by incorporating a reference counting collector as well (similar to ARC) which deals with the \u0026ldquo;low hanging garbage\u0026rdquo; thus making the actual GC process far less important so our GC sweeps don’t need to be very fast.\nBut this post is titled \u0026ldquo;beating the ARC\u0026rdquo;… How can we be faster than ARC?\nSimple, we don’t de-allocate. All objects that our reference counter deems to be garbage are sent to the garbage heap and finalized/deleted on the GC thread (as is custom in Java) hence we get the benefit of multi-core parallel cleanup logic on top of the fast performance.\nOur GC never actually pauses the world, it uses a simple mark sweep cycle where we iterate the thread stacks and mark all objects in use, we then iterate all the objects in the world and delete the living, unmarked objects. Since deletion of GC’d and reference counted objects is always done in the GC thread this is pretty easy and thread safe on the VM part. The architecture is actually rather simple and conservative.\nThe benefit of the reference counting approach becomes very clear with the non-pausing GC, since the reference counting system still kicks out objects from RAM the GC serves only for the heavy lifting. So it can be executed less frequently and its OK for it to miss quite a few objects as the reference counting implementation will pick up the slack.\nWe are still working on getting this into users hands ideally within the next couple of weeks (albeit in alpha state) and eventually open sourcing all of that code.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/beating-the-arc/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/beating-the-arc/beating-the-arc-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/beating-the-arc/beating-the-arc-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eFor the uninitiated, ARC is Apple’s term for Automatic Reference Counting. Objective-C uses a reference counting scenario to collect objects which is pretty painful to work with. Personally I preferred C/C++’s manual delete/free to the Objective-C semantics. But a couple of years ago Apple introduced ARC in which the compiler implicitly inserts the retain/release reference counting logic.\u003c/p\u003e\n\u003cp\u003eWhile its a big improvement its still a reference counter with many of the implied limitations. It solves 95% of your memory handling logic leaving the hardest 5% for you to deal with manually but it does have one advantage over a GC: determinism. Since memory is deallocated immediately it provides consistent performance with no GC stalls.\u003c/p\u003e","title":"Beating The ARC"},{"content":"\nI’ve had some talks with rather savvy Codename One developers recently which made me realize that quite a few developers don’t truly grasp the reason why we have a separation between peer (native) components and Codename One components. This is a crucial thing you need to understand especially if you plan on working with native widgets e.g. Web Browser,\nnative maps\n, text input, media and\nnative interfaces\n(which can return a peer).\nCodename One draws all of its widgets on its own, this is a concept which we modeled in part after Swing. This allows you to do various things in Codename One that you just can’t do in any native platform:\n1. GUI builder/simulator that’s pretty close to how the app will look on the device – notice that this also enables the build cloud, otherwise you would be drowned by device specific bugs making the build cloud redundant.\n2. Ability to override everything – paint, pointer, key events are all overridable and replaceable. You can also paint over everything e.g. glasspane and layered pane.\n3. Consistency – you can get identical functionality on all platforms for the most part.\nThis all contributes to our ease of working with Codename One and maintaining Codename One. More than 95% of Codename One’s code is in Java hence its really portable and pretty easy to maintain!\n**\nSo why add native widgets at all?\n**\nWe need the native device to do input, html rendering etc. these are just too big and too complex tasks for us to do from scratch.\nSo whats the problems with native widgets?\nCodename One does pretty much everything on the EDT (Event Dispatch Thread), this provides a lot of cool features e.g. modal dialogs, invokeAndBlock etc. however native widgets have to be drawn on their own thread… So the process for drawing a native widgets has to occur in the naive rendering thread. This means that drawing looks something like this:\n1. Loop over all Codename One components and paint them.\n2. Loop over all native peer components and paint them.\nThis effectively means that all peer components will always be on top of the Codename One components.\n**\nSo how do we show dialogs on top of Peer Components?\n**\nThis is tricky; we grab a screenshot of the peer, hide it and then we can just show the screenshot. Since the screenshot is static it can be rendered via the standard UI. Naturally we can’t do that always since grabbing a screenshot is an expensive process on all platforms and must be performed on the native device thread.\n**\nWhy can’t we combine peer component scrolling and Codename One scrolling?\n**\nSince the form title/footer etc. are drawn by Codename One the peer component might paint itself on top of them. Clipping a peer component is often pretty difficult.\nFurthermore, if the user drags his finger within the peer component he might trigger the native scroll within the might collide with our scrolling?\nThe old text edit defaulted to stopping the editing during scrolling for exactly that reason, however the new iOS always on VKB mode doesn’t do that. It just hides the peer component the moment scrolling is detected to prevent these issues from happening.\nThere are also some additional problems that might be counter intuitive. E.g. iOS has\n7 screenshot images\nrepresenting the first form. If your first page is an HTML or a native map (or other peer widget) the screenshot process on our build server will show fallback code instead of the real thing thus providing sub-par behavior. Some developers asked us about the HTML aspect, but its hard for us to grab a desktop screenshot of the web component (JavaFX thread pain) and it would also look completely different from the web component running on the device.\nI hope this clarifies the problem with native peers and why we try to add as few of them as reasonably possible.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/understanding-peer-native-components-why-codename-one-is-so-portable/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/understanding-peer-native-components-why-codename-one-is-so-portable/understanding-peer-native-components-why-codename-one-is-so-portable-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/understanding-peer-native-components-why-codename-one-is-so-portable/understanding-peer-native-components-why-codename-one-is-so-portable-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve had some talks with rather savvy Codename One developers recently which made me realize that quite a few developers don’t truly grasp the reason why we have a separation between peer (native) components and Codename One components. This is a crucial thing you need to understand especially if you plan on working with native widgets e.g. Web Browser,\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/3/post/2014/03/mapping-natively.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nnative maps\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, text input, media and\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/how-do-i---access-native-device-functionality-invoke-native-interfaces.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nnative interfaces\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n(which can return a peer).\u003c/p\u003e","title":"Understanding Peer (native) Components \u0026 Why Codename One is so portable"},{"content":"\nIf you haven’t yet filled out the\ndeveloper economics survey\nplease do so now! We are still short of 30 entries in order to get better logo placement in the released survey. This is important since the people who read these surveys are of a demographic that’s much harder for us to reach normally.\nIt would help us greatly if you would convince your friends to fill this out as well. Thanks.\nFinishing the work on the new VM is taking longer than we originally estimated (as all engineering tasks do) but its getting along well. To give you a sense of scale, converting the Kitchen Sink to C with the old VM took 1,851,249 lines of code where is with the new VM its a \u0026ldquo;svelte\u0026rdquo; 1,001,317 with the current implementation. The old XMVM implementation produced 4,220 source files to do that whereis the new implementation produces \u0026ldquo;only\u0026rdquo; 1,474 files.\nIdeally we’d like this to shrink significantly since one of the main motivations here is smaller size and faster builds.\nHowever, the new VM will be naturally very verbose since bytecode by definition is more verbose than Dalvik which the existing XMLVM implementation relies on. We also embed the GC logic directly into the C code using an ARC like GC architecture (emphasis on the word \u0026ldquo;like\u0026rdquo; ARC isn’t a GC) which would also enlarge the VM a bit.\nOne of the hard goals with the new VM is to be mostly source level compatible with XMLVM but as we are moving forward this is something we are starting to reconsider. We already broke one major compatibility aspect with method signatures. E.g. with XMLVM a class such as this:\npackage com.mycompany;\nclass MyClass {\npublic int myMethod(int arg1, int arg2) ….\n}\nWith be translated to this in C:\nJAVA_INT com_mycompany_myMethod___int_int(JAVA_OBJECT thisObject, JAVA_INT arg1, JAVA_INT arg2);\nWe already changed this to support covariant return type in Java where the method return value must be a part of the signature, so if your return type is void this will work like XMLVM but for any other return type you will get:\nJAVA_INT com_mycompany_myMethod___int_int_\n**\nR_int(\n**\nJAVA_OBJECT thisObject, JAVA_INT arg1, JAVA_INT arg2);\nThis allows us to have two methods with different return values which the VM spec allows even though the Java language disallows it! The javac compiler makes use of that discrepancy to generate things such as covariant return type support.\nWe are considering a more radical change though, we would like to add to every method an additional argument:\nJAVA_INT com_mycompany_myMethod___int_int_R_int(\n**\nCODENAME_ONE_THREAD_STATE\n**\nJAVA_OBJECT thisObject, JAVA_INT arg1, JAVA_INT arg2);\nThis will allow us to define this as nothing on the current XMLVM code but when building the new VM we will be able to pass the thread context thru the method stack rather than look it up constantly which is an expensive operation. In the new VM this will translate to something like:\n#define CODENAME_ONE_THREAD_STATE struct ThreadData* threadStateData,\nWhich will effectively compile to this:\nJAVA_INT com_mycompany_myMethod___int_int_R_int(\n**\nstruct ThreadData* threadStateData,\n**\nJAVA_OBJECT thisObject, JAVA_INT arg1, JAVA_INT arg2);\nThis will allow us to avoid expensive locking and critical sections and easily keep track of the stack.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/vm-stats/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/vm-stats/vm-stats-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/vm-stats/vm-stats-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eIf you haven’t yet filled out the\u003cbr\u003e\n\u003ca href=\"http://www.vmob.me/DE3Q14CodenameOne\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\ndeveloper economics survey\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nplease do so now! We are still short of 30 entries in order to get better logo placement in the released survey. This is important since the people who read these surveys are of a demographic that’s much harder for us to reach normally.\u003c/p\u003e\n\u003cp\u003eIt would help us greatly if you would convince your friends to fill this out as well. Thanks.\u003c/p\u003e","title":"VM Stats"},{"content":"\nIf you read the article about the\n7 screenshots of iOS\nyou might have wondered whether you can just supply these screenshots yourself?\nWell, now you can. Our build server will now generate the screenshots only if they don’t already exist in the jar so you will need to create the right png images in the exact resolutions mentioned below:\nDefault.png – 320×480\nDefault@2x.png – 640×960\nDefault-568h@2x.png – 630×1136\nDefault-Portrait.png – 768×1024\nDefault-Landscape.png – 1024×768\nDefault-Portrait@2x.png – 1536×2048\nDefault-Landscape@2x.png – 2048×1536\nNotice that the names are case sensitive and the resolutions must match the numbers above.\nWe’ve been working for a while on a new Graphics pipeline and Shapes API which should include some pretty nifty features, the main code is mostly done for iOS. This includes a new Shape API that will allow you to define any arbitrary shape and stroke/fill it using common graphics idioms. This will be fully hardware accelerated which will allow us to offer rather elaborate effects such as good looking/fast charts.\nThe API will also expose a proper Affine Transform and potentially a perspective transform allowing for high performance rotation effects and 3D effects. This is all slated for 2.1 which we hope to release before Java One.\nWe will have a booth at this years Java One hopefully some of the sessions we submitted will also go thru.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — April 28, 2014 at 3:46 pm (permalink) Anonymous says:\nHello,\nWill the rotation and 3D effects be applied to Android and Windows ports?\nAnonymous — April 30, 2014 at 2:45 pm (permalink) Anonymous says:\nWe are targeting Android and ideally desktop. 3D might be tricky but we would like them on both of these.\nWindows Phone probably not in the near future.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/screenshots-and-graphics-update/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/screenshots-and-graphics-update/screenshots-and-graphics-update-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/screenshots-and-graphics-update/screenshots-and-graphics-update-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eIf you read the article about the\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/3/post/2014/03/the-7-screenshots-of-ios.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\n7 screenshots of iOS\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nyou might have wondered whether you can just supply these screenshots yourself?\u003c/p\u003e\n\u003cp\u003eWell, now you can. Our build server will now generate the screenshots only if they don’t already exist in the jar so you will need to create the right png images in the exact resolutions mentioned below:\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eDefault.png\u003c/code\u003e – 320×480\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eDefault@2x.png\u003c/code\u003e – 640×960\u003c/p\u003e","title":"Screenshots and Graphics Update"},{"content":"\nYou might have noticed things have been a bit quiet with new features recently. That is because we had a bit of a holiday around here and because we spent a great deal of time working on a new VM for iOS. This work is still ongoing and basic things such as the garbage collection scheme are still incomplete but we are now ready to talk about the motivations and direction with this new VM.\nInitially when we started working on Codename One we assumed we would have to build our own VM for iOS since there were no decent options at the time. However as luck would have it, the XMLVM guys just built a new backend to support iOS which was pretty good and we ended up going with XMLVM for the infrastructure instead of building our own VM. This was a great help since it allowed us to release our initial beta within 3 months of forming Codename One!\nHowever, this had some downsides specifically:\n1. XMLVM is huge and very generic so its remarkably hard to fix.\n2. Its size and generic architecture make the translation process slow which slows down the builds.\n3. It uses the boehm gc which stalls quite a bit.\n4. It uses Harmony for the class libraries which are much larger than what we actually need resulting in slower compilations and larger/slower executables.\n5. It translates dalvik code to iOS instead of bytecode directly which is slightly unintuitive and potentially suboptimial for some cases.\nNormally we would have other priorities but Apple has effectively forced our hand to do this when they released xcode 5.1 which broke compatibility with boehm code. Right now this isn’t a problem but Apple might suddenly decide to force all developers to migrate to a new version of xcode (which they did with 5.0) and we don’t want to get caught in such a situation scampering to patch an issue.\nWe thought long and hard about fixing XMLVM for our needs but eventually came to the conclusion that it would be simpler to start with a clean slate since XSLT is such a painful way to do something of this type. We were also having problems with our usage of XMLVM on Windows Phone so the replacement seemed to make more sense across the board (although we haven’t actually started the Windows Phone work).\nWe did look extensively at other projects that have sprung up in the past couple of years to address these issues but all seemed to be suffering from the problem of addressing a too large problem space, using harmony (or worse open JDK) and using boehm (which is a fine GC except for the stalls). The exception here is J2ObjC which isn’t really a VM and isn’t intended for this use case at all.\nYou might be wondering how this will effect you as a Codename One developer.\nIt won’t really, except for the fact that at some point in the future your builds will become faster and perform better. We chose a source architecture that is very similar to XMLVM since we liked the basic concepts of XMLVM and we think its the right direction going forward to be as compatible with Apple’s way of doing things as possible. All the things you rely on including native interfaces etc. should work just the same and the screenshot you see in this post is taken from the kitchen sink running in the new VM!\nSince there are always potential incompatibilities we will offer a build flag that will allow you to build with the old XMLVM backend for quite a while and we will maintain both approaches. We don’t currently have a fixed date for the release of this new VM since we have a lot of other priorities to deal with and this is a pretty big effort but we intend to have it ready before Java One. Ideally sooner.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — April 30, 2014 at 2:04 am (permalink) Anonymous says:\nhttp://oss.readytalk.com/av…\nAnonymous — April 30, 2014 at 2:20 am (permalink) Anonymous says:\nSteve Hannah already ported Codename One to Avian and it performed worse than XMLVM while taking up quite a bit of space. It suffers from pretty much all of the problems I illustrated above.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-vm/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-vm/new-vm-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/new-vm/new-vm-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eYou might have noticed things have been a bit quiet with new features recently. That is because we had a bit of a holiday around here and because we spent a great deal of time working on a new VM for iOS. This work is still ongoing and basic things such as the garbage collection scheme are still incomplete but we are now ready to talk about the motivations and direction with this new VM.\u003c/p\u003e","title":"New VM"},{"content":"\nUp until now debugging location oriented applications in the simulator was a bit painful, there was no real way other than coding to a specific location and if you relied on specific GIS data you couldn’t easily debug that case.\nChen was working with an enterprise customer and got fed up with that so he built a UI which you should be able to access via the Simulator menu in the next update. This UI allows you to drag a Map to determine your current location in the location API. It will fire the appropriate events and allow you to define the GPS states. This should make the lives of those of you building location aware applications much easier!\nI hope you took the time to fill up and promote the\ndeveloper economics survey\n, it is really helpful for us and we appreciate your effort here!\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — April 14, 2014 at 8:37 am (permalink) Anonymous says:\nGreat, This will be handy for quality assurance. The fixed GPS coordinates were not practical for most cases.\nAnonymous — April 16, 2014 at 4:42 am (permalink) Anonymous says:\nHi when is the plugin update going to be released?\nAnonymous — April 16, 2014 at 4:22 pm (permalink) Anonymous says:\nLater next week. We are on Passover holiday here so its a bit difficult to make a release right now.\nAnonymous — April 22, 2014 at 9:25 am (permalink) Anonymous says:\nPerfect, I needed this so much about 4 weeks ago lol, great new feature though!!!\nAnonymous — April 25, 2014 at 4:54 am (permalink) Anonymous says:\nHi I have downloaded latest plugin. Ran simulator. Can’t find \u0026ldquo;Map\u0026rdquo; menu item…\nAnonymous — April 25, 2014 at 10:38 am (permalink) Anonymous says:\nDid you use the update client libraries feature? The simulator is part of that unless you create a new project.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/placing/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/placing/placing-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/placing/placing-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eUp until now debugging location oriented applications in the simulator was a bit painful, there was no real way other than coding to a specific location and if you relied on specific GIS data you couldn’t easily debug that case.\u003c/p\u003e\n\u003cp\u003eChen was working with an enterprise customer and got fed up with that so he built a UI which you should be able to access via the Simulator menu in the next update. This UI allows you to drag a Map to determine your current location in the location API. It will fire the appropriate events and allow you to define the GPS states. This should make the lives of those of you building location aware applications much easier!\u003c/p\u003e","title":"Placing"},{"content":"\nThe last time we had a developer economics survey you guys really came thru and made us one of the top contributors for that survey!\nThis year the stakes are even higher and the incentive for referrals\nis greater, if you want to help us promote Codename One to a people outside of the core Java developer community then please fill out this survey using this link:\nhttp://www.vmob.me/DE3Q14CodenameOne\n. Please also help us by distributing this link as far as you can!\nThe guys at Developer Economics are also offering rewards for people who complete the forms so the incentive should be even greater!\nThanks for taking the time to fill this out.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/please-help-us-by-filling-the-developer-economics-survey/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/please-help-us-by-filling-the-developer-economics-survey/please-help-us-by-filling-the-developer-economics-survey-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/please-help-us-by-filling-the-developer-economics-survey/please-help-us-by-filling-the-developer-economics-survey-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe last time we had a developer economics survey you guys really came thru and made us one of the top contributors for that survey!\u003c/p\u003e\n\u003cp\u003eThis year the stakes are even higher and the incentive for referrals\u003c/p\u003e\n\u003cp\u003eis greater, if you want to help us promote Codename One to a people outside of the core Java developer community then please fill out this survey using this link:\u003cbr\u003e\n\u003ca href=\"http://www.vmob.me/DE3Q14CodenameOne\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nhttp://www.vmob.me/DE3Q14CodenameOne\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n. Please also help us by distributing this link as far as you can!\u003c/p\u003e","title":"Please Help Us By Filling The Developer Economics Survey"},{"content":"\nOne of our enterprise accounts was using lead component in a rather unique setting and needed a way to \u0026ldquo;unlead\u0026rdquo; essentially disable the lead component functionality which is one of those things we never imagined people doing. As a result we allowed setLeadComponent(null) to effectively \u0026ldquo;do the right thing\u0026rdquo; for most cases.\nThis reminded me that lead component is something that we definitely need to cover again, the developer guide barely touches the subject that is one of the most powerful concepts we have.\nCodename One has two basic ways to create new components:\n1. Subclass a component override paint, implement key handling etc.\n2. Composite multiple components into a new component, usually by subclassing a container.\nAs Codename One matures we find ourselves doing less of option 1 and a lot more of option 2. You can look at components like Tabs which make a lot of sense as a Container since they contain other components. However, components like MultiButton, SpanButton \u0026amp; SpanLabel don’t necessarily seem like the right candidate for that but they are…\nUsing a Container allows us a lot of flexibility in terms of layout \u0026amp; functionality for a specific component. MultiButton is a great example of that. Its internally a Container that contains 5 labels and a Button (that might be replaced with a check box or radio button).\nSo how do we make the MultiButton \u0026ldquo;feel\u0026rdquo; like a single button?\nSimple, we use setLeadComponent() which turns the button (or radio/checkbox) into the \u0026ldquo;leader\u0026rdquo; of the component.\nWhen a Container hierarchy is placed under a leader all events within the hierarchy are sent to the leader, so if a label within the lead component receives a pointer pressed event this event will really be sent to the leader. E.g. in the case of the multi button the button will receive that event and send the action performed event, change the state etc.\nThe leader also determines the style state, so all the elements being lead are in the same state. E.g. if the the button is pressed all elements will display their pressed states, notice that they will do so with their own styles but they will each pick the pressed version of that style so a Label UIID within a lead component in the pressed state would return the Pressed state for a Label not for the Button.\nThis is very convenient when you need to construct more elaborate UI’s and the cool thing about it is that you can do this entirely in the designer which allows assembling containers and defining the lead component inside the hierarchy.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — April 5, 2014 at 3:41 pm (permalink) Anonymous says:\nCould you elaborate a bit more on the last paragraph – creating a complex component from within the designer.\nYou can’t subclass a container in the designer, right? So one should simply use a basic container, layout whatever component is needed, and then set one of them as the leader? If so, can you then reuse this component in multiple places, multiple forms? If so, then it’s really cool! Well, even if it’s not quite like I described, it’s still pretty powerful!\nAnonymous — April 6, 2014 at 3:38 am (permalink) Anonymous says:\nSure, when you create a Container in the designer (not a form) it will appear as part of the User Components within other forms and you can drag it as a whole into new locations.\nNotice that this will create a copy so changes to the original will not be reflected.\nYou can also use crateContainer from code to create a container instance thus populate the UI from elements created in the designer. Thanks to lead component you don’t really need to subclass in order to create a completely new component. The main reason we subclassed to create multi-button etc. was so the API will be \u0026ldquo;pretty\u0026rdquo;.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/leading/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/leading/leading-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/leading/leading-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of our enterprise accounts was using lead component in a rather unique setting and needed a way to \u0026ldquo;unlead\u0026rdquo; essentially disable the lead component functionality which is one of those things we never imagined people doing. As a result we allowed setLeadComponent(null) to effectively \u0026ldquo;do the right thing\u0026rdquo; for most cases.\u003c/p\u003e\n\u003cp\u003eThis reminded me that lead component is something that we definitely need to cover again, the developer guide barely touches the subject that is one of the most powerful concepts we have.\u003c/p\u003e","title":"Leading"},{"content":"\nWe introduced a new rendering pipeline for Android a while back, it showed a lot of potential but unfortunately still had some major bugs. Chen just made some major fixes for this pipeline which should hopefully address those issues, please start testing your app with this pipeline and let us know if you experience regressions as a result of that.\nTo test the new pipeline just define the build argument android.asyncPaint=true\nYou define the build argument by going to your project properties, selecting Codename One and you should see a \u0026ldquo;Build Hints\u0026rdquo; tab option. Just enter the values there.\nOnce we feel this is stable enough we will \u0026ldquo;flip the switch\u0026rdquo; and make it the default rendering pipeline on Android so hopefully it should be stable and performant by then.\nThe regular Android pipeline should still work for the foreseeable future although due to changes Android 4.x made to various types of rendering strategies things that used to work in Android no longer work as expected for various edge cases (device fragmentation is indeed a problem here).\nSince the new pipeline is completely different performance of your application might actually degrade when you switch to it. You need to spend time investigating the paint chain in the Component Inspector tool (in the simulator menu) and make sure that there isn’t too much \u0026ldquo;overdraw\u0026rdquo;. Overdraw is the situation where a pixel on the screen is painted multiple times over and over. The old native pipeline eliminated this overdraw but the newer system doesn’t do a good job with that.\nOn an unrelated subject we also added a \u0026ldquo;Clean Storage\u0026rdquo; option to the simulator and a\n\u0026ldquo;Remove All\u0026rdquo; option to the network monitor tool.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — April 1, 2014 at 4:29 am (permalink) Anonymous says:\nAsync issue reported here https://code.google.com/p/c… is not yet fixed.\nOn March 5th I sent you an email with \u0026ldquo;Black issue with WebBrowser component\u0026rdquo;; that was also an async paint issue. Any progress on that?\nWim\nAnonymous — April 1, 2014 at 4:33 am (permalink) Anonymous says:\nThanks for the reminder, we will look into that.\nAnonymous — April 28, 2014 at 3:50 am (permalink) Anonymous says:\nhi,\nam a new user of your product codename one, i have some challenges i will want your team to help me with\n1. We are trying to wirte a mobile app for our client, this app will collect data from the field officers and submit to\ndatabase (SQL server 2008) does codebname one have the capabilties for SQL server database, if we subscribe do you host\ndatabase online or we have to get one ourselves ?\n2. In the form designer we have some controls on the form labale and textfield boxes, but the screen filled and we need to\nadd more under, we can’t scroll the designer screen up so as to add more why is codename one screen unscrollable.\nwe will appreciate if you can help with detail light on this two challenges.\nthanks ABRAHAM (ABDATA SOLUTIONS)\nAnonymous — April 28, 2014 at 12:26 pm (permalink) Anonymous says:\n1. No. You should use a webservice to hide the database.\n2. You can add them via the tree and you can expand the view further to add more space. Due to the architecture of the current designer its hard to allow scrolling in design mode. We have plans to replace that tool in the future.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-android-pipeline-fixes/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-android-pipeline-fixes/new-android-pipeline-fixes-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/new-android-pipeline-fixes-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/new-android-pipeline-fixes/new-android-pipeline-fixes-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eWe introduced a new rendering pipeline for Android a while back, it showed a lot of potential but unfortunately still had some major bugs. Chen just made some major fixes for this pipeline which should hopefully address those issues, please start testing your app with this pipeline and let us know if you experience regressions as a result of that.\u003c/p\u003e\n\u003cp\u003eTo test the new pipeline just define the build argument \u003ccode\u003eandroid.asyncPaint=true\u003c/code\u003e\u003c/p\u003e","title":"New Android Pipeline Fixes"},{"content":"\nA lot of developers have asked us for QR code support on Windows Phone 8, we finally took the plunge with the first attempt here. It seems QR support for ZXing on Windows Phone is WAY behind the level on Android or iOS.\nAs part of that work we made some additional Windows Phone improvements including integration with the native image gallery (via the show gallery API in Display), email, SMS API support and more.\nRecently we encountered a problem with a build for one of\nour enterprise customers\nwhere builds would just fail on iOS without even reaching the build stage… This happens when the\nscreenshot process on the server\nfails, however we looked thru their code and could see nothing there! It all seemed complex yet not something that should exceed the 20 second timeout per screenshot.\nThis particular application has a very rich resource file of more than 3.5mb, that is a lot… Our reference to the resource is a soft reference by default and it can be removed at any minute. The developer of the app was aware of this due to previous support incidents and invoked setKeepResourcesInRam(true); in the constructor of the state machine. However, this still caused the resource file to load/unload several times before that code was invoked… Moving it to init vars like this, solved the problem:\nprotected void initVars() { setKeepResourcesInRam(true); } Notice that this version of the initVars() doesn’t take any arguments and it happens before the constructor or anything…\nTo understand why that is you need to understand a few things on the Java language specification, say I have two classes:\nclass A { public A() { print(); } public void print() { } } class B extends A { int i = -1; public B() { } public void print() { System.out.println(i); } } This will printout 0.\nTo understand why look at this which is semantically identical to the above B class. The javac compiler effectively translates class level assignment into assignment within the constructor so class B looks like this:\nclass B extends A { int i; public B() { super(); i = 1; } public void print() { System.out.println(i); } } This is how javac compiles the class so while super (A’s constructor) is executing the variable is still in the default 0 state…\nIt is in fact an antipattern to invoke an overridable method from the constructor which unfortunately we did a few years ago when we created the original designer, when we noticed that mistake it was already too late to fix so instead we patched it with the initVars() method. That is why you should use one of those two methods when dealing with initialization and should generally not rely on the constructor or default values set to variables.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — March 13, 2015 at 7:17 am (permalink) Anonymous says:\nIt might work we haven’t tested that\nAnonymous — March 13, 2015 at 7:17 am (permalink) Anonymous says:\nIs it just QR code support or can you also scan conventional barcodes now, UPC, EAN etc.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/windows-phone-improvements-build-screenshots/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/windows-phone-improvements-build-screenshots/windows-phone-improvements-build-screenshots-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/windows-phone-improvements-build-screenshots/windows-phone-improvements-build-screenshots-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eA lot of developers have asked us for QR code support on Windows Phone 8, we finally took the plunge with the first attempt here. It seems QR support for ZXing on Windows Phone is WAY behind the level on Android or iOS.\u003c/p\u003e\n\u003cp\u003eAs part of that work we made some additional Windows Phone improvements including integration with the native image gallery (via the show gallery API in Display), email, SMS API support and more.\u003c/p\u003e","title":"Windows Phone Improvements \u0026 Build Screenshots"},{"content":"\nOne of the annoying tasks when programming native Android applications is tuning all the required permissions to match your codes requirements, when we started Codename One we aimed to simplify this. Our build server automatically introspects the classes you sent as part of the build and injects the right set of permissions required by your app.\nHowever, sometimes you might find the permissions that come up a bit confusing and might not understand why a specific permission came up. This maps Android permissions to the methods/classes in Codename One that would trigger them:\nandroid.permission.WRITE_EXTERNAL_STORAGE – this permission appears by default for Codename One applications, since the File API which is used extensively relies on it. You can explicitly disable it using the build argument android.blockExternalStoragePermission=true, notice that this is something we don’t test and it might fail for you on the device.\nandroid.permission.INTERNET – this is a hardcoded permission in Codename One, the ability to connect to the network is coded into all Codename One applications.\nandroid.hardware.camera \u0026amp; android.permission.RECORD_AUDIO – are triggered by com.codename1.Capture\nandroid.permission.RECORD_AUDIO – is triggered by MediaManager.createMediaRecorder() \u0026amp; Display.createMediaRecorder()\nandroid.permission.READ_PHONE_STATE – is triggered by com.codename1.ads package, com.codename1.components.Ads, com.codename1.components.ShareButton, com.codename1.media, com.codename1.push, Display.getUdid() \u0026amp; Display.getMsisdn(). This permission is required for media in order to suspend audio playback when you get a phone call.\nandroid.hardware.location, android.hardware.location.gps, android.permission.ACCESS_FINE_LOCATION, android.permission.ACCESS_MOCK_LOCATION \u0026amp; android.permission.ACCESS_COARSE_LOCATION – map to com.codename1.maps \u0026amp; com.codename1.location.\npackage.permission.C2D_MESSAGE, com.google.android.c2dm.permission.RECEIVE, android.permission.RECEIVE_BOOT_COMPLETED – are requested by the com.codename1.push package\nandroid.permission.READ_CONTACTS – triggers by the package com.codename1.contacts \u0026amp; Display.getAllContacts().\nandroid.permission.VIBRATE – is triggered by Display.vibrate() and Display.notifyStatusBar()\nandroid.permission.SEND_SMS – is triggered by Display.sendSMS()\nandroid.permission.WAKE_LOCK – is triggered by Display.lockScreen() \u0026amp; Display.setScreenSaverEnabled()\nandroid.permission.WRITE_CONTACTS – is triggered by Display.createContact(), Display.deleteContact(), ContactsManager.createContact() \u0026amp; ContactsManager.\ndeleteContact()\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/androids-permissions/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/androids-permissions/androids-permissions-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/androids-permissions/androids-permissions-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the annoying tasks when programming native Android applications is tuning all the required permissions to match your codes requirements, when we started Codename One we aimed to simplify this. Our build server automatically introspects the classes you sent as part of the build and injects the right set of permissions required by your app.\u003c/p\u003e\n\u003cp\u003eHowever, sometimes you might find the permissions that come up a bit confusing and might not understand why a specific permission came up. This maps Android permissions to the methods/classes in Codename One that would trigger them:\u003c/p\u003e","title":"Androids Permissions"},{"content":"\nSome of you have already noticed a build error when building for iOS if you used the processing package. This is due to a small change we made to the package where we replaced all usage of Hashtable/Vector with Map/List. That allows the processing package to work with the new parseJSON method that returns the new collection code and thus be MUCH faster on iOS.\nUnfortunately due to the way java codes method signatures you need to update the libraries in order to for this change to work, we automatically update the libraries when you send the build but that means you will need to send again if you get that failure.\nWe also improved button responsiveness on iOS, this was a very hard to track issue which we’ve been following for a while. Older iOS devices are somewhat overeager with pointer dragged events and tend to send them all over the place. Unfortunately this triggered a release of a button in some cases making it feel unresponsive. Normally dragging a pressed button should not release it but we had some very old pre-Codename One code that did just that for some cases. This code is now remove and hopefully your UI’s will just \u0026ldquo;magically\u0026rdquo; become more responsive.\nIf you do any native interfaces programming in Android you should be familiar with our AndroidUtil class which allows you to access native device functionality more easily from the native code. E.g. many Android API’s need access to the Activity which you can get by calling AndroidNativeUtil.getActivity() which is much simpler than the alternative approaches.\nWe now also have additional functions in the native util including the following –\nAndroidNativeUtil.addLifecycleListener/removeLifecycleListener\n– these will essentially provide you with a callback to lifecycle events: onCreate etc. which can be pretty useful for some cases.\nAndroidNativeUtil.registerViewRenderer – PeerComponent’s are usually shown on top of the UI since they are rendered within their own thread outside of the EDT cycle. So when we need to show a Dialog on top of the peer we grab a screenshot of the peer, hide it and then show the dialog with the image as the background (the same applies for transitions). Unfortunately some components (specifically the MapView) might not render properly and require custom code to implement the transferal to a native Bitmap, this API allows you to do just that. Esoteric but if you need it then its a lifesaver!\nLast but not least is AndroidImplementation.runOnUiThreadAndBlock(Runnable) – this is such a common pattern that we had to generalize it into a public static method. Its identical to Activity.runOnUiThread but blocks until the runnable finishes execution. Very important.\nSamples for usage for all of these is available in our\nmap library source code\n.\nOne of Androids annoying \u0026ldquo;features\u0026rdquo; is that everything needs to be coded at a very low level and a lot of components don’t do the \u0026ldquo;right thing\u0026rdquo; by default. E.g. mailto: URL’s don’t launch the mail app by default when clicked from a BrowserComponent on Android. We fixed this to be the sensible default but we still pass the shouldNavigate call in case you want to do something differently.\nIf you aren’t familiar with Dialog.showPopup(Component) it allows you to create the UI common on the iPad where a dialog points at the component that launched it. However, if you have a rather complex UI you might not have a component to point at, in which case we can use a new version of the method that accepts a rectangle to point towards as Dialog.showPopup(Rectangle).\nOn the right hand side you should see some new promotional graphics. It includes some featured Codename One apps including\nqmarkets\n,\nyhomework\n\u0026amp;\ntravel together\n.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/processing-responsiveness-native-more/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/processing-responsiveness-native-more/processing-responsiveness-native-more-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/processing-responsiveness-native-more-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/processing-responsiveness-native-more/processing-responsiveness-native-more-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eSome of you have already noticed a build error when building for iOS if you used the processing package. This is due to a small change we made to the package where we replaced all usage of Hashtable/Vector with Map/List. That allows the processing package to work with the new parseJSON method that returns the new collection code and thus be MUCH faster on iOS.\u003c/p\u003e\n\u003cp\u003eUnfortunately due to the way java codes method signatures you need to update the libraries in order to for this change to work, we automatically update the libraries when you send the build but that means you will need to send again if you get that failure.\u003c/p\u003e","title":"Processing, Responsiveness, Native \u0026 more"},{"content":"\nThis has been a frequent RFE in the groups but it never made its way up because of the complexity involved. A corporate account recently requested support for native Maps so we had to promote the task upwards. We decided to build the\nnative maps as an external cn1lib\nrather than build them into Codename One itself, the reasoning is two fold:\n1. Show how to map a native component – next time someone wants to add a native widget into Codename One they can use the Maps as a reference and go around us.\n2. Since Maps are VERY complex we wanted to give developers the ability to customize the native code easily.\nGoing forward we might introduce more and more extensions as cn1libs rather than as builtin functionality. There is one drawback we didn’t predict though, Googles Map API for iOS is 50mb in size which makes sending the builds pretty slow. This is solveable by changing the compression option in the project properties to compress the jar, it is still pretty large though.\nTo browse/checkout the code/demo-test for maps just go to the project page\nhere\n. For simplicities sake you can just\ndownload the binary here\nand place it in your lib directory for the project then right click the project and select refresh client libs.\nHowever, configuration does require a bit of work and there are a few limitations.\n**\nLimitations\n**\n1. The native maps are only supported on Android devices that have the Google Play store (e.g. not on Amazon Kindle) and on iOS devices. All other devices will show the MapComponent by default.\nMap component will be used on the simulator as well.\n2. Since a native component is used placing overlays is problematic. You will need to use Dialogs and the API’s of the MapContainer class to implement this.\n**\nConfiguration\n**\nThe configuration portion is the hardest part, Google made it especially painful in the Google typical way. You can follow the instructions from Google to get started for\nAndroid\nand for\niOS\n.\nYou will need to follow their instructions to generate your map keys. Then define the following build arguments within your project:\nMake sure to replace the values YOUR_ANDROID_API_KEY \u0026amp; YOUR_IOS_API_KEY with the values you obtained from the Google Cloud console by following the instructions for\nAndroid\nand for\niOS\n.\nNow that all of that is done you should be able to create a Map, add markers and paths:\nAt the time of this writing there are still issues with Maps some of which are pretty hard to resolve. Currently when poping a dialog over the Map it turns white on Android and we aren’t really sure why. There are some artifacts on iOS as well but those might not be fixable.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — March 17, 2014 at 3:22 pm (permalink) Anonymous says:\nI really like this approach of introducing new features as modules. This enables us to drill down to the core of what CN1 is. In the future it might even be possible to incorporate a sort of package manager into the designer to automatically load the modules that you need for your project. Sort of like developing Netbeans platform plugins. I know we’re a ways away from that, but this small step of introducing maps as a separate module is perhaps a precedent-setting step in the right direction.\nAnonymous — March 17, 2014 at 6:51 pm (permalink) Anonymous says:\nI’ve only used the MapComponent very simply, so am not really across any issues with it, so I’m wondering what the extra complexity of native maps buys me ?\nAnonymous — March 17, 2014 at 8:50 pm (permalink) Anonymous says:\nExcellent, thanks for this. I’ve just tried it with my own API keys (that is a debacle – thanks Google) but once set up it works great. Hopefully the graphical glitches can be addressed sometime but its looking and performing great.\nAnonymous — March 18, 2014 at 2:59 am (permalink) Anonymous says:\nActually most of the infrastructure for adding dynamic classes to the designer is already there (classloader etc.) we had something like that in the LWUIT days so its doable.\nThe main reason we didn’t add this back is that we want to migrate to a new designer architecture eventually. This is still in drawing board stages but we have a pretty good idea of where we want to go here.\nAnonymous — March 18, 2014 at 3:00 am (permalink) Anonymous says:\nIts mostly a matter of feel/performance. The native map is very fluid and fast, Google wrote it on OpenGL using vector graphics and its really smooth.\nAnonymous — March 20, 2014 at 7:19 am (permalink) Anonymous says:\nHi, I see the Android dialog blank screen. Is it possible to capture the screen before dialog is displayed and then use it as a background image behind the dialog?\nReason being I think users will complain about the blank screen, because they are used to seeing the map in the background.\nAnonymous — March 20, 2014 at 4:36 pm (permalink) Anonymous says:\nWe do that automatically for all peer components. Map is special (check the code to understand why) we had an issue in the AndroidPeer which should be fixed in current builds.\nAnonymous — March 21, 2014 at 1:36 pm (permalink) Anonymous says:\nHi I have just updated my SVN CN1 source project and refreshed libs. The Google map still becomes blank when a dialog is displayed.\nAnonymous — March 21, 2014 at 1:37 pm (permalink) Anonymous says:\nHi I have just updated my CN1 sources project and refreshed libs. The Google map still becomes blank when a dialog is displayed.\nAnonymous — March 21, 2014 at 2:24 pm (permalink) Anonymous says:\nI’ll try this.\nAnonymous — March 23, 2014 at 7:10 am (permalink) Anonymous says:\nFor some reason the fix didn’t propagate to the build servers. We are updating them again now. Should be there in a half hour or so.\nAnonymous — March 23, 2014 at 8:15 am (permalink) Anonymous says:\nThanks map now appears in the background of dialog.\nAnonymous — September 5, 2014 at 3:22 am (permalink) Anonymous says:\nhi,\nIf I am developing only for iOS do I still need the android key?\nThanks\nGreg\nAnonymous — September 5, 2014 at 12:42 pm (permalink) Anonymous says:\nHi,\nno. Should work fine without.\nAnonymous — November 10, 2014 at 3:41 am (permalink) Anonymous says:\nI tried to put GoogleMaps.cn1lib into the lib folder in my Intellij IDEA project workspace and got java.lang.OutOfMemoryError:Java heap space at build.xml, line 449.\nAre there other steps required, beside just dropping library into libs folder especially for IDEA environment?\nAnonymous — November 26, 2014 at 8:13 am (permalink) Anonymous says:\nSorry for the delay answering (got buried in my inbox).\nIts an issue with IDEA that’s easily fixable, check out this: http://devnet.jetbrains.com…\nBobo Collen — April 8, 2015 at 2:49 pm (permalink) Bobo Collen says:\nHow do i define iOS \u0026amp; Android build arguments within the project? i want to include GoogleMaps in this GoogleMapTest Demo using my GoogleMaps API, so that i can be more familiar with the process before i develop my Maps project.\nShai Almog — April 9, 2015 at 5:29 am (permalink) Shai Almog says:\nRight click the project, select preferences. In the Codename One section you should see a \u0026ldquo;Build Hints\u0026rdquo; tab and there you can add keys/values.\nBobo Collen — April 13, 2015 at 3:27 pm (permalink) Bobo Collen says:\nThank you for your prompt response, I included the build arguments and the project is showing an Openstreet Maps instead of Google Maps. Are these Google maps APIs for Android and iOS going to cater for those of Windows Phone and Black Berry? If not, which maps APIs must we use since Black Berry and Windows Phone are not covered by Google maps?\nShai Almog — April 14, 2015 at 5:20 am (permalink) Shai Almog says:\nThat is the map component fallback, you can define it by replacing the map implementation. Keep in mind that on the device this will look completely different anyway since it will run native code. I suggest you start with device testing and make sure that works for you since there are quite a few hurdles there.\nMarco Grabmüller — September 13, 2016 at 1:50 pm (permalink) Marco Grabmüller says:\nHello Shai,\ni think, we have the issue with the white screen instead of the map. we use the native map and we have defined the build arguments corectly.\npreviously we used map component. Unfortunately this was not performing well enough but worked.\nin the simulator, we see the openstreetmap and a second java window with a loaded google map.\ndirectly on the phone, we see only a white space.\nmaybe you have an idea what we can do?\nThx\nThis is our Code:\nBefore Part:\nMapContainer cnt = new MapContainer();\nimageViewerContainer.addComponent(BorderLayout.CENTER, cnt);\nPost Part:\nCoord coord = new Coord(geoMapDataModel.getLatitude(), geoMapDataModel.getLongitude());\ncnt.setCameraPosition(coord);\ncnt.addMarker(null, coord, \u0026ldquo;test\u0026rdquo;, \u0026ldquo;\u0026rdquo;, null);\nShai Almog — September 14, 2016 at 4:33 am (permalink) Shai Almog says:\nHi,\nmake sure you are up to date on the latest map from the extensions menu (under Codename One Settings). This usually means the SHA1 or something is incorrect so make sure you are using a proper release build etc.\nIf this still fails you need to connect the device with a cable and look thru the DDMS Android tool at the console. Google prints errors to the console with more details and you should be able to see the misconfiguration there.\nMarco Grabmüller — September 14, 2016 at 8:06 am (permalink) Marco Grabmüller says:\nhello,\nthx for your hints.\nfirst we had a wrong api-key. the same key we have used @ the mapcomponent.\nwe think, maybe was this the fault. 1 key = 1 Project…\nsecond we had a bug in our layout.\nparent container was borderlayout -\u0026gt; children Map container also borderlayout in center -\u0026gt; therefore we saw only a white screen.\nnow the map works great! thx for support!\nessay writer — September 19, 2016 at 7:26 pm (permalink) essay writer says:\nThe mapping natively makes it easier for the performance. It might be difficult in the start but the complete working with research and limitation leads this as perfect one. It shoddily not has complexity in its findings.\nYngve Moe — September 23, 2016 at 11:09 pm (permalink) Yngve Moe says:\nWarning: be careful not to add any leading or trailing spaces in the iOS build hints (I got them added automatically when copying from this page in Chrome). The build server chokes on the extra spaces.\nyoussef abdeen — December 1, 2016 at 5:25 pm (permalink) youssef abdeen says:\ni am new at this, i dont know where to put this code in my app, any help please !!\nShai Almog — December 2, 2016 at 5:31 am (permalink) Shai Almog says:\nIt’s the main application code, you can just include the cn1lib from the extensions menu and use MapContainer in code like other components. Notice you need to define some build hints based on the instructions in the extensions menu under Codename One Settings.\nyoussef abdeen — December 2, 2016 at 11:54 pm (permalink) youssef abdeen says:\ni did what you said and the application worked, but i did not use the google map API key, i got the API key but i don’t know where to put it. and sorry i didn’t understand the part you said about the \u0026ldquo;build hints\u0026rdquo;.\nthank you\nyoussef abdeen — December 3, 2016 at 12:30 am (permalink) youssef abdeen says:\nhttps://uploads.disquscdn.c…\nwhere exactly to put the argument thing and the keys here??\nShai Almog — December 3, 2016 at 9:15 am (permalink) Shai Almog says:\nIn the right click menu go to the Codename One Settings app where a build hints option is available. Native maps work on the simulator but are very different on the device…\nMarco Grabmüller — December 5, 2016 at 7:31 am (permalink) Marco Grabmüller says:\nHello Shai,\nI need your help again 🙂\nWe get the following build errors after sending a debug ios build -\u0026gt; fatal error: \u0026ldquo;GoogleMaps.h\u0026rdquo; file not found\n#import \u0026ldquo;GoogleMaps.h\u0026rdquo;\nOur native Android apps works flawlessly.\nWe have done all the points as described above.\nWe downloaded the native map extension using the codenameone Settings Tool.\nAny ideas, what is wrong?\nThank you very much\nShai Almog — December 6, 2016 at 5:27 am (permalink) Shai Almog says:\nHi,\nthe post above is outdated and you should refer to the github project page for instructions. Ideally we’ll post an updated blog on doing this.\nThe new extension which is installable via the extensions menu in the Codename One Settings auto-setups most of these hints so if you added ios.* hints as instructed above you shouldn’t have and should remove them.\nMarco Grabmüller — December 6, 2016 at 8:19 am (permalink) Marco Grabmüller says:\nHello and thank you for your answer.\nWe have looked at the Git guide -\u0026gt; https://github.com/codename…\nFor our understanding:\nThis build hint -\u0026gt; ios.glAppDelegateHeader = #import \u0026ldquo;GoogleMaps / GoogleMaps.h\u0026rdquo; is automatically set by the extension.\nWe can not delete it, because it is always re-created.\nThe build hint is also not in your example?\nOur build hints are included as screenshot.\nStrange is:\nWe are now no longer the error reported by us above.\nThere is still a build error, but there is no error in the log.\nIs there a way to send the log file to you? Or. Can you see it?\nThanks again! https://uploads.disquscdn.c…\nShai Almog — December 7, 2016 at 6:39 am (permalink) Shai Almog says:\nIn the past GoogleMaps.h was included but the new syntax is GoogleMaps/GoogleMaps.h due to the cocoa pods change which is why I said this is a setup problem.\nFor build errors we have a support engineer in the chat application on the bottom right side who can help with those. Just let them know you have an error and paste the link our server returned. They will review the error and try to guide you.\nFYI 9 out of 10 iOS build errors happen when you generate your own certificates incorrectly instead of using the certificate wizard.\nyoussef abdeen — December 8, 2016 at 8:39 pm (permalink) youssef abdeen says:\ni am developing an app using codename one to notify a driver if he drives in a the wrong direction of a street using google maps i already downloaded the google map extension and it opened in my app i just want any ideas how to know the direction of a certain street on google map and use it in my code, so if a driver went on the wrong direction of this street i would notify him by a dialog message.\nthank you\nShai Almog — December 9, 2016 at 7:37 am (permalink) Shai Almog says:\nThat’s probably a part of the google GEO API. I’m afraid I’m unfamiliar with that and can’t give you any pointers. I think you will need to modify the implementation of the google maps cn1lib to include this functionality so it’s non-trivial and requires some native code.\nStephen Michael — January 18, 2017 at 6:13 pm (permalink) Stephen Michael says:\nIs there any work in progress to update the native mapping library to utilize V3 of the Google Maps API? I am looking to integrate the \u0026ldquo;unlimited/free\u0026rdquo; access via Android and IOS native maps API’s, and am wondering about the accessibility of V3 Google Maps API’s via CodenameOne. Thoughts?\nShai Almog — January 19, 2017 at 6:18 am (permalink) Shai Almog says:\nV2 is the latest. V3 is for JavaScript only and we use the native API’s.\nWe are actually updating the Maps right now to have an optional JavaScript fallback instead of the MapComponent fallback. I think the UX is better overall. There are already some committed changes on that but this isn’t released yet since it’s work in progress.\nTerry Wilkinson — February 2, 2017 at 8:21 pm (permalink) Terry Wilkinson says:\nHi Shai,\nI’m just getting started with this, and am having trouble getting this Native Maps demo running using eclipse. I’ve copied the GoogleMaps.cn1lib file to the lib directory in my project, but the statement\nimport com.codename1.googlemaps.MapContainer;\nis giving the error\n\u0026ldquo;The import com.codename1.googlemaps cannot be resolved GoogleMapsTestApp.java/Goog… line 3″\nIs this because GoogleMaps.cn1lib is not a jar file? What am I doing wrong?\nThank,\nTerry\nShai Almog — February 3, 2017 at 7:42 am (permalink) Shai Almog says:\nHi,\nI suggest using the extension manager tool in Codename One Settings to install cn1libs. I hope to post a refreshed version of this guide within a couple of weeks once we get out the new version of the library.\nTerry Wilkinson — February 3, 2017 at 5:01 pm (permalink) Terry Wilkinson says:\nThanks, Shai, I look forward to your updated guide.\nIn the mean time, your suggestion helped me, and I have succeeded in building and installing the demo app. However, when I run it, it comes up using OpenStreetMaps. I must have missed something else 🙂\nShai Almog — February 4, 2017 at 8:18 am (permalink) Shai Almog says:\nYou need to make sure all the keys from google are setup correctly in the build hints.\nTerry Wilkinson — February 4, 2017 at 1:42 pm (permalink) Terry Wilkinson says:\nThat’s what it took – thanks very much. I thought I’d done that, but is must have gotten deleted somehow – grrrr.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/mapping-natively/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/mapping-natively/mapping-natively-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/mapping-natively/mapping-natively-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis has been a frequent RFE in the groups but it never made its way up because of the complexity involved. A corporate account recently requested support for native Maps so we had to promote the task upwards. We decided to build the\u003cbr\u003e\n\u003ca href=\"https://github.com/codenameone/codenameone-google-maps\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nnative maps as an external cn1lib\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nrather than build them into Codename One itself, the reasoning is two fold:\u003c/p\u003e\n\u003cp\u003e1. Show how to map a native component – next time someone wants to add a native widget into Codename One they can use the Maps as a reference and go around us.\u003c/p\u003e","title":"Mapping Natively"},{"content":"\nHave you ever noticed how iOS apps start almost instantly in comparison to Android apps?\nThere is a trick to that. iOS applications have a file traditionally called Default.png that includes a 320×480 pixel image of the first screen of the application. So you are treated to an \u0026ldquo;illusion\u0026rdquo; of the application instantly coming to life and filling up with data, this is pretty cool on the surface but is a source to no end of trouble in iOS and becomes a huge hassle.\nInitially this was a pretty clever workaround then Apple introduced the retina display 640×960 so you needed to add a Default@2x.png file then it added the iPad, iPad Retina and iPhone 5 (which is slightly higher resolution), to make matters worse iPad apps can be launched in landscape mode so that’s two more resolutions for the horizontal orientation iPad. Overall as of this writing (or until Apple adds more resolutions) we need 7 screenshots for a typical iOS app!\niOS developers literally run their applications 7 times with blank data to grab these screenshots every time they change something in the first form of their application!\nWhen we started working on Codename One we understood that this will not be feasible, initially we thought we would show a hardcoded screenshot but that wouldn’t be \u0026ldquo;right\u0026rdquo; then we came up with a simple idea. We run the application 7 times in the build server, grab the right sized screenshot in our simulator and then build the app!\nThis means the process of the iPhone splash screen is almost seamless to you… But its not completely seamless.\nEvery abstraction leaks and this one has quite a few leaks/pitfalls you should be aware of as a developer.\n**\nSize\n**\nOne of the first things we ran into when building one of our demos was a case where an app that wasn’t very big in terms of functionality took up 30mb!\nAfter inspecting the app we discovered that the iPad retina PNG files were close to 5mb in size… Since we had 2 of them (landscape and portrait) this was the main problem.\nThe iPad retina is a 2048×1536 device and with the leather theme the PNG images are almost impossible to compress because of the richness of details within that theme. This produced the huge screenshots that ballooned the application.\n**\nMutable first screen\n**\nA very common use case is to have an application that pops up a login dialog on first run. This doesn’t work well since the server takes a picture of the login screen so the login screen will appear briefly for future loads and will never appear again.\n**\nUnsupported component\n**\nOne of the biggest obstacles is with heavyweight components, e.g. if you use a browser or maps on the first screen of the app you will see a partially loaded/distorted MapComponent and the native webkit browser obviously can’t be rendered properly by our servers.\nThe workaround for such issues is to have a splash screen that doesn’t include any of the above. Its OK to show it for a very brief amount of time since the screenshot process is pretty fast.\nOn the right hand side of this article you can see the upcoming native Google maps implementation running on Android. There are still bugs there but we are getting there…\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/the-7-screenshots-of-ios/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/the-7-screenshots-of-ios/the-7-screenshots-of-ios-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/the-7-screenshots-of-ios/the-7-screenshots-of-ios-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eHave you ever noticed how iOS apps start almost instantly in comparison to Android apps?\u003c/p\u003e\n\u003cp\u003eThere is a trick to that. iOS applications have a file traditionally called Default.png that includes a 320×480 pixel image of the first screen of the application. So you are treated to an \u0026ldquo;illusion\u0026rdquo; of the application instantly coming to life and filling up with data, this is pretty cool on the surface but is a source to no end of trouble in iOS and becomes a huge hassle.\u003c/p\u003e","title":"The 7 Screenshots Of iOS"},{"content":"\nCloud files are a great pro feature that we didn’t emphasize enough, its remarkably useful. It allows you to upload a file into the cloud which you can then transfer to anyone thru a simple \u0026ldquo;obfuscated\u0026rdquo; URL. The URL is long so the probability of someone guessing it is low, hence its pretty secure for private file transfer (if its really private you should use\nbouncy castle\n). The API couldn’t be simpler:\nString fileId = CloudStorage.getInstance().uploadCloudFile(mimeType, fileName); This will block to upload the file so you might want to display an infinite progress indicator or something, once its done and the file was uploaded you can just call:\nString url = CloudStorage.getInstance().getUrlForCloudFileId(fileId); That URL will provide you with the file download and you can delete the file via deleteCloudFile(fileId). In the upcoming version we are also adding deleteAllCloudFilesForUser() and deleteAllCloudFilesBefore(timestamp, developerAccount, developerPassword)\nwhich will allow you to purge some of your quota.\nYou can use this for image exchange and other such tricks but one of my favorite concepts is sharing data between devices e.g. you can upload your application state as a file to the cloud and expose it via a QR code like this:\nint size = Math.min(Display.getInstance().getDisplayWidth(), Display.getInstance().getDisplayHeight());\nLabel qrCode = new Label(new URLImage(\u0026ldquo;http://chart.apis.google.com/chart?cht=qr\u0026chs=\" + size + \u0026ldquo;x\u0026rdquo; + size \u0026ldquo;\u0026amp;chl=\u0026rdquo; + fileId + \u0026ldquo;\u0026amp;chld=H|0\u0026rdquo;));\nNow on the other device just scan the QR code and download the file to import the data, trivial synchronization between devices without typing a single word into the device!\nThe image you see on the right is a bit unrelated but you might find it interesting…\nA corporate account requested\nnative Google Maps support for iOS/Android, we already have a prototype on iOS although Android is a bit more of a challenge. We hope to have something to show soon though.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — March 10, 2014 at 7:01 pm (permalink) Anonymous says:\nHey Shai,\nwhat about Windows Phone? will it have native maps support too?\nAnonymous — March 11, 2014 at 5:02 am (permalink) Anonymous says:\nThat isn’t planned at the moment. On Windows Phone we will currently fallback to MapComponent. Google Maps doesn’t have a version for Windows Phone so supporting something like here maps etc. might be a pain.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/cloud-files/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/cloud-files/cloud-files-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/cloud-files-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Map\" loading=\"lazy\" src=\"/blog/cloud-files/cloud-files-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eCloud files are a great pro feature that we didn’t emphasize enough, its remarkably useful. It allows you to upload a file into the cloud which you can then transfer to anyone thru a simple \u0026ldquo;obfuscated\u0026rdquo; URL. The URL is long so the probability of someone guessing it is low, hence its pretty secure for private file transfer (if its really private you should use\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/3/post/2013/06/bouncy-castle-crypto-api.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nbouncy castle\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n). The API couldn’t be simpler:\u003c/p\u003e","title":"Cloud Files"},{"content":"\nWe recently introduced the corporate server option which is seeing initial deployments right now. As part of that we are now publishing the install guide to the general public, if you are considering the option of purchasing a corporate server but aren’t sure about the process of install you can follow the instructions\nhere\n.\nIn other news you might recall in a recent blog post I mentioned\nwe added isDragRegion\n, well its now deprecated in favor of a more ambitious getDragRegionStatus which can return multiple constants to help us fine tune the drag behavior to all the various edge cases and make the UI feel more responsive.\nUp until now desktop applications in Codename One shared the same .cn1 storage as the simulator, this was a problem with multiple apps installed. Starting with current builds desktop apps should store their data under .AppMainClassName within the home directory. We also fixed the icon on the windows builds to appear correctly within the frame and the running apps menu (alt-tab etc.).\nThe Google Play ads were causing some issues in Gingerbread devices where clicks would have no effect, unfortunately we aren’t clear on why exactly this happens but its related to obfuscation probably removing some compatibility code needed by Google. The only workaround we found for this to work on older devices is to disable obfuscation on Android by using the build argument: android.enableProguard=false\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/corporate-guide/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/corporate-guide/corporate-guide-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/corporate-guide/corporate-guide-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe recently introduced the corporate server option which is seeing initial deployments right now. As part of that we are now publishing the install guide to the general public, if you are considering the option of purchasing a corporate server but aren’t sure about the process of install you can follow the instructions\u003cbr\u003e\n\u003ca href=\"/corporate-server.html\"\u003e\u003cbr\u003e\nhere\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n.\u003c/p\u003e\n\u003cp\u003eIn other news you might recall in a recent blog post I mentioned\u003c/p\u003e","title":"Corporate Guide"},{"content":"\nImageDownloadService is one of the first classes we wrote when creating the original IO package, as such we were still thinking over the API and the code… stinks.\nI’ve had the task of writing a tutorial for ImageDownloadService for such a long time and I just kept procrastinating on it because it is so painful to deal with. Eventually I broke down and decided to solve the problem in the proper way of creating a completely new API that’s simpler and thus doesn’t really require an extensive tutorial: URLImage.\nURLImage is an image created with a URL… Simple. It is seamlessly downloaded, scaled (adapted) and automatically updates itself in place. All good.\nThe simple use case is pretty trivial:\nImage i = URLImage.createToStorage(placeholder, \u0026ldquo;fileNameInStorage\u0026rdquo;, \u0026ldquo;http://xxx/myurl.jpg\u0026rdquo;, URLImage.RESIZE_SCALE);\nAlternatively you can use the similar\nURLImage.createToFileSystem method instead of the Storage version.\nThis image can now be used anywhere a regular image will appear, it will initially show the placeholder image and then seamlessly replace it with the file after it was downloaded and stored.\nNotice: Since\nImageIO is used to perform the operations of the adapter interface its required that ImageIO will work. It is currently working in JavaSE, Android, iOS \u0026amp; Windows Phone. It doesn’t work on J2ME/Blackberry devices so if you pass an adapter instance on those platforms it will probably fail to perform its task.\nIf the file in the URL contains an image that is too bit it will scale it to match the size of the placeholder precisely!\nWe currently also have an option to fail if the sizes don’t match. Notice that the image that will be saved is the scaled image, which means you will have very little overhead in downloading images that are the wrong size although you will get some artifacts.\nThe last argument is really quite powerful, its an interface called URLImage.ImageAdapter and you can implement it to adapt the downloaded image in any way you like. E.g. you can use an image mask to automatically create a rounded version of the downloaded image or to scale based on aspect ratio. We will probably add some tools to implement such functionality based on user demand.\nTo do this you just override public EncodedImage adaptImage(EncodedImage downloadedImage, Image placeholderImage) in the adapter interface and just return the processed encoded image. If you do heavy processing (e.g. rounded edge images) you would need to convert the processed image back to an encoded image so it can be saved. You would then also want to indicate that this operation should run asynchronously via the appropriate method in the class.\nIf you need to download the file instantly and not wait for the image to appear before download initiates you can explicitly invoke the fetch() method which will asynchronously fetch the image from the network.\n**\nLists\n**\nThe biggest problem with image download service is with lists. We decided to attack this issue at the core by integrating URLImage support directly into GenericListCellRenderer which means it will work with MultiList, List \u0026amp; ContainerList. To use this support just define the name of the component (name not UIID) to end with _URLImage and give it an icon to use as the placeholder. This is easy to do in the multilist by changing the name of icon to icon_URLImage then using:\nmap.put(\u0026ldquo;icon_URLImage\u0026rdquo;, urlToActualImage); in the data.\nMake sure you also set a \u0026ldquo;real\u0026rdquo; icon to the entry in the GUI builder or in handcoded applications. This is important since the icon will be implicitly extracted and used as the placeholder value. Everything else should be handled automatically. You can use setDefaultAdapter \u0026amp; setAdapter on the generic list cell renderer to install adapters for the images. The default is a scale adapter although we might change that to scale fill in the future.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — March 14, 2014 at 7:15 am (permalink) Anonymous says:\nThanks, this is just what I needed for my new project! That old ImageDownloadService worked as well, but it surely felt a bit clumsy.\nAnonymous — April 4, 2014 at 12:27 am (permalink) Anonymous says:\nHi, i want to use the URLImage class in my current project but can’t seem to find it in my current version of codenameone running on netbeans 7.4. How do I incorperate it into my IDE? I tried downloading the latest plugin but it did not do the job. Any tips? As I find the ImageDownloadService confusing.\nAnonymous — April 4, 2014 at 2:57 am (permalink) Anonymous says:\nLibraries are updated by going to the project properties Codename One section and clicking the update client libs button.\nAnonymous — April 4, 2014 at 9:12 am (permalink) Anonymous says:\nThanks for the prompt response!\nAnonymous — April 4, 2014 at 10:34 am (permalink) Anonymous says:\nHi Shai, I tested between two seperate image urls (via simulator) and noticed that unless the \u0026ldquo;fileNameInStorage\u0026rdquo; is changed, the image displayed will not change despite the url used. This likely means that the image is stored locally and is no longer being called via the URL.\nI would like to know if the images that are downloaded via the URL are stored in a directory and if so where?\nAnonymous — April 4, 2014 at 3:46 pm (permalink) Anonymous says:\nAll images are placed in Storage or FileSystemStorage based on the type of URL you created under the file name you gave. Storage and file system are mapped to the .cn1 directory in your home directory for the simulator.\nAnonymous — June 19, 2014 at 5:47 am (permalink) Anonymous says:\nHi Shai,\nThis seems very convenient in most case.\nI have 2 questions:\n– what about background pictures ?\n– is there anylimitations we should be aware of (like only PNG files, max size file, resolution) ?\nThank you.\nAnonymous — June 20, 2014 at 12:46 am (permalink) Anonymous says:\nHi,\nbackground images should work too.\nAny file type should work although if the image is rescaled using the default scaling in some cases the image will become a PNG and in others it will become a JPEG. The logic isn’t as clear as it should be.\nAnonymous — June 20, 2014 at 10:00 am (permalink) Anonymous says:\nHi.\nI am not able to work with URLImage for background pictures.\nAlso, I have done a dumb test. I try to insert 4000 pictures downloaded inside my form.\nWhen pictures are downloaded, scroll is smooth and efficient.\nBut, when app is downloading pictures, and during this time, we have a bad scroll effect on Android device (Nexus 4). But not on iOS.\nAny idea ?\nThank you.\nAnonymous — June 20, 2014 at 1:53 pm (permalink) Anonymous says:\n4000 seems like a bit much.\nAnonymous — June 21, 2014 at 4:20 pm (permalink) Anonymous says:\nThank you for your answer Shai.\nI agree, 4000 is quite too much. But I have the same result with 400.\nAnd I do not get the difference between Android and iOS.\nIs there something I can / should do ?\nI read on the forum other option like pre-download the pictures in the background and I will use it anyway. But if I can do something on this case, it would be great.\nThank you.\nAnonymous — March 3, 2015 at 6:31 am (permalink) Anonymous says:\nHow can I fetch changing placeholder image by downloaded image for revalidate ImageViewer?\nAnonymous — March 3, 2015 at 12:19 pm (permalink) Anonymous says:\nI don’t quite understand the question but did you see the property cross demo and tutorial where we use this API in two different settings:\nhttp://www.codenameone.com/…\nhttps://www.udemy.com/learn…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/image-from-url-made-easy/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/image-from-url-made-easy/image-from-url-made-easy-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/image-from-url-made-easy/image-from-url-made-easy-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eImageDownloadService is one of the first classes we wrote when creating the original IO package, as such we were still thinking over the API and the code… stinks.\u003c/p\u003e\n\u003cp\u003eI’ve had the task of writing a tutorial for ImageDownloadService for such a long time and I just kept procrastinating on it because it is so painful to deal with. Eventually I broke down and decided to solve the problem in the proper way of creating a completely new API that’s simpler and thus doesn’t really require an extensive tutorial: URLImage.\u003c/p\u003e","title":"Image From URL Made Easy"},{"content":"\nIts been pretty busy around here the last couple of weeks. However, we still introduced a couple of new API’s and abilities besides the many bug fixes that constantly go in.\nWe deprecated JSONParser.parse(Reader) in favor of Map\u0026lt;String, Object\u0026gt; parseJSON(Reader i). This is effectively the exact same class with one minor difference, it returns HashMaps/ArrayLists rather than Hashtables/Vectors to represent the hierarchy.\nBesides the modern aspect of the new collections they are also slightly faster due to the lack of synchronization calls.\nWe finally implemented RFE\n738\nwhich asks for improved overscroll behavior, we can’t get it to be 100% accurate but we got it as close as possible with the current rendering architecture.\nWith MultiList/GenenricListCellRenderer one of the common issues is making a UI where a specific component within the list renderer has a different UIID style. E.g. this can be helpful to mark a label within the list as red, for instance in cases of a list of monetary transactions. Up until now the only answer we had was: you need to create your own renderer. With the latest version of GenericListCellRenderer (MultiList uses GenericListCellRenderer internally) we have another option.\nNormally to build the model for a renderer of this type we use something like:\nmap.put(\u0026quot;componentName\u0026quot;, \u0026quot;Component Value\u0026quot;);\nWhat if we want\ncomponentName to be red? Just use:\nmap.put(\u0026quot;componentName_uiid\u0026quot;, \u0026quot;red\u0026quot;);\nThis will apply the uiid \u0026ldquo;red\u0026rdquo; to the component which you can then style in the them. Notice that once you start doing this you need to define this entry for all entries e.g.:\nmap.put(\u0026quot;componentName_uiid\u0026quot;, \u0026quot;blue\u0026quot;);\nOtherwise the component will stay red for the next entry (since renderer acts like a\nrubber stamp\n).\nLast but not least we felt the need to simplify the very common task of download. Up until now downloading a file required a bit of code, where you needed to open a connection request and do quite a few other things. There is really no justification for that.\nSo we added to Util the following methods: downloadUrlToFileSystemInBackground, downloadUrlToStorageInBackground, downloadUrlToFile \u0026amp; downloadUrlToStorage.\nThese all delegate to a new feature we added to ConnectionRequest called: ConnectionRequest.setDestinationStorage(fileName)/\nConnectionRequest.setDestinationFile(fileName);\nWhich simplifies the whole process of downloading a file.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — February 26, 2014 at 4:31 pm (permalink) Anonymous says:\nThese changes are in the netbeans plugin?\nAnonymous — February 27, 2014 at 3:51 am (permalink) Anonymous says:\nNot yet, soon.\nAnonymous — March 24, 2014 at 12:27 pm (permalink) Anonymous says:\nHi Shai, luis already asked and you said soon. Have you got a date on that ? Thanks\nAnonymous — March 24, 2014 at 4:32 pm (permalink) Anonymous says:\nNo.\nWe released the plugin almost a month ago I forgot the exact date.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/json-overscroll-more/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/json-overscroll-more/json-overscroll-more-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Overscroll\" loading=\"lazy\" src=\"/blog/json-overscroll-more/json-overscroll-more-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eIts been pretty busy around here the last couple of weeks. However, we still introduced a couple of new API’s and abilities besides the many bug fixes that constantly go in.\u003c/p\u003e\n\u003cp\u003eWe deprecated JSONParser.parse(Reader) in favor of Map\u0026lt;String, Object\u0026gt; parseJSON(Reader i). This is effectively the exact same class with one minor difference, it returns HashMaps/ArrayLists rather than Hashtables/Vectors to represent the hierarchy.\u003c/p\u003e\n\u003cp\u003eBesides the modern aspect of the new collections they are also slightly faster due to the lack of synchronization calls.\u003c/p\u003e","title":"JSON, Overscroll \u0026 More"},{"content":"\nWe’ve been even more busy than usual with our first\ncorporate deployment\nkicking off, this is currently a pretty rough process that requires a lot of hands on help from us but we hope to make it less painful for our customers. Either way, this being a completely new offering with a great deal of complexity involved its an uphill effort which is part of why we are experiencing a slowdown in new features.\nAnother aspect that hit us this week is the camera bug on iOS which apparently still wasn’t resolved, it got solved thanks to the combined stubbornness of Chen and some clues from Steve. We also had some rendering artifacts on Android KitKat due to regressions Android has with its TextureView, we ended up disabling the TextureView which we introduced to workaround a relatively rare Android bug (there are a lot of those around). You can still explicitly enable the TextureView approach by using the build flag android.textureView=true.\nThese issues are highlighting the importance of migrating to the Android async mode, unfortunately it isn’t complete at this time and it too suffers from some significant issues.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/device-bugs-and-updates/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/device-bugs-and-updates/device-bugs-and-updates-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/device-bugs-and-updates/device-bugs-and-updates-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve been even more busy than usual with our first\u003cbr\u003e\n\u003ca href=\"/corporate-server.html\"\u003e\u003cbr\u003e\ncorporate deployment\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nkicking off, this is currently a pretty rough process that requires a lot of hands on help from us but we hope to make it less painful for our customers. Either way, this being a completely new offering with a great deal of complexity involved its an uphill effort which is part of why we are experiencing a slowdown in new features.\u003c/p\u003e","title":"Device Bugs And Updates"},{"content":"\nI’ve been working a bit with Kapila and Andreas on a\nCalendar project for Codename One\nto be used as a\ncn1lib\n(working is a strong word I’ve mostly just bossed them around and didn’t really do much, they did all the work). Its a pretty ambitious project since Calendar API’s are so fragmented and problematic, in fact no cross platform tool I’m familiar with has anything remotely close to a working Calendar API.\nIf this is something important/dear to your heart feel free to pitch in and try to improve the implementation, file issues etc.\nIn other news we’ve Improved facebook support on iOS to use the device native login where possible, this was actually implemented incorrectly and was brought to our attention.\nLast week we had one of the most annoying bugs I think we ever had to deal with. It seems that in some iPhones (only iPhones never iPads) camera capture crashes when saving the photo. We were never able to reproduce this on any of our devices but a customer was getting this consistently on his, eventually he lent us his personal iPhone and we spent half a day debugging this, turns out this is a known issue and the solution is: reboot the device… Ugh.\nWe no longer have a device that reproduces this issue but we’ve incorporated one of the suggested workarounds for this issue into the code so we hope it works around that iOS bug. If it doesn’t and you are seeing crashes on devices when taking a picture with the current builds let us know!\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — February 26, 2014 at 2:49 pm (permalink) Anonymous says:\nIs this library finished or there is still some works going on?\nThanks\nAnonymous — February 26, 2014 at 3:54 pm (permalink) Anonymous says:\nIt seems development has slowed down a little. As far as I understand the basic functionality Andreas and Kapilla need is working for them. I suggest you ask this on the forum where they can see it and respond with more information.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/calendar-small-changes/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/calendar-small-changes/calendar-small-changes-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/calendar-small-changes/calendar-small-changes-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve been working a bit with Kapila and Andreas on a\u003cbr\u003e\n\u003ca href=\"http://code.google.com/p/codenameone-calendar/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nCalendar project for Codename One\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nto be used as a\u003cbr\u003e\n\u003ca href=\"http://codenameone.com/cn1libs.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\ncn1lib\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n(working is a strong word I’ve mostly just bossed them around and didn’t really do much, they did all the work). Its a pretty ambitious project since Calendar API’s are so fragmented and problematic, in fact no cross platform tool I’m familiar with has anything remotely close to a working Calendar API.\u003c/p\u003e","title":"Calendar \u0026 Small Changes"},{"content":"\nIn the latest update to desktop builds we made the mouse wheel scroll the UI which is something that we’ve meant to do for ages but just didn’t get around to doing. This will also work in the simulator when the next update arrives.\nThis was a big challenging to implement properly since the mouse doesn’t actually touch a specific component, eventually we decided to just send press/release/drag events in sequence when a mouse wheel is active.\nWe also made some improvements to drag behavior. One of the surprisingly difficult aspects of touch development is recognizing whether a user wants to drag or tap. This is especially difficult with touch UI since a user might drag over a button in order to scroll down so the button shouldn’t fire an action event in that case!\nIts the main reason we should avoid binding logic to the pointer pressed method and instead use the pointer released method (there is another reason but I digress…). The problem is further compounded by the fact that some devices send drag events even when there was no perceivable drag. This makes it even harder to differentiate such a case.\nTo workaround this behavior the Codename One implementation layer filters out drag events until we decide that a drag is \u0026ldquo;really\u0026rdquo; occurring and isn’t just \u0026ldquo;noise\u0026rdquo;. We filter using two different methods:\n1. The number of drag events sent – this is problematic on some platforms e.g. Android where a ridiculous number of drag events can be sent without the user moving his finger.\n2. Drag percentage – if the user moved his finger more than a given percentage of the screen drag should be activated.\nThe problem is that if we set drag percentage too low buttons become harder to press since they notice small drag events that happen unintentionally and we assume you are trying to scroll the screen.\nCodename One has a setter within Display called setDragStartPercentage and some use cases feel smoother when setting it to a lower value however this is very device specific and error prone.\nSo we added a new method to Component to indicate if a drag in a particular area is positively a drag operation: protected boolean isDragRegion(int x, int y)\nFor Lists this will return true if the list is large making it easier to scroll larger lists, for side menu this will return true if the drag operation is in the left side of the screen trying to open the sidemenu.\nIn those cases drag percentage is implicitly treated as very low (it still has an effect) to create a smoother dragging experience.\nNotice that we might change that method in the future to become more expressive.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/wheel-drag/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/wheel-drag/wheel-drag-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/wheel-drag/wheel-drag-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eIn the latest update to desktop builds we made the mouse wheel scroll the UI which is something that we’ve meant to do for ages but just didn’t get around to doing. This will also work in the simulator when the next update arrives.\u003c/p\u003e\n\u003cp\u003eThis was a big challenging to implement properly since the mouse doesn’t actually touch a specific component, eventually we decided to just send press/release/drag events in sequence when a mouse wheel is active.\u003c/p\u003e","title":"Wheel \u0026 Drag"},{"content":"\nVision mobile just released their new developer economics study, you can check it out\nhere\n.\nWe toggled the\nnew pipeline mode\nfor windows\nphone to be the default, its clearly the way to go forward in the long run since we just don’t have any other choice. All feedback on the new pipeline found it to improve performance significantly and generally reduces some of the paint issues that we run into with Windows Phone. However, there are a couple of reports pointing out that font quality has degraded with the new pipeline. We are looking into this but came to the decision that even if this isn’t solvable we will stick with the new pipeline since the old one is just not viable for moving forward.\nAs part of our ongoing work with the new Android pipeline we added an experimental rendering mode that tries to automatically detect invisible layers and not draw them. You can enable this mode by invoking\nDisplay.getInstance().setProperty(\u0026quot;blockOverdraw\u0026quot;, \u0026quot;true\u0026quot;);\nThis might improve performance for some cases and might improve performance on platforms other than Android. We’d be interested to hear if this mode break stuff in your application.\n**\nDesktop Build Arguments\n**\nOur recent desktop build support allows pro users to send builds for desktop applications. These builds are actually highly customizable using the following build arguments:\ndesktop.width – width of the window in pixels (defaults to 800)\ndesktop.height – height of the window in pixels\n(defaults to 800)\ndesktop.fullScreen – whether the application will run in full screen\n(true/false defaults to false)\ndesktop.adaptToRetina – doubles the pixels for a high resolution display (true/false defaults to true)\ndesktop.resizable – whether the window would be resizable (true/false defaults to true)\ndesktop.theme – the theme to use as the native theme defaults to \u0026ldquo;native\u0026rdquo;. Can be \u0026ldquo;none\u0026rdquo; to indicate no theme or the name of any resource file within the bundle that you would like to use as a base without the .res extension. E.g. iPhoneTheme assuming you placed the iPhoneTheme.res file in your src directory.\ndesktop.windowsOutput – the installer type you want for Windows can be exe or msi defaults to msi\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — February 6, 2014 at 6:04 am (permalink) Anonymous says:\nDisplay.getInstance().setProperty(\u0026ldquo;blockOverdraw\u0026rdquo;, \u0026ldquo;true\u0026rdquo;); doesn’t seem to break anything on first sight.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/desktop-vision-mobile-misc-changes/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/desktop-vision-mobile-misc-changes/desktop-vision-mobile-misc-changes-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/desktop-vision-mobile-misc-changes/desktop-vision-mobile-misc-changes-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eVision mobile just released their new developer economics study, you can check it out\u003cbr\u003e\n\u003ca href=\"http://www.visionmobile.com/DE1Q14CodenameOne\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nhere\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n.\u003c/p\u003e\n\u003cp\u003eWe toggled the\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/3/post/2014/02/a-new-pipeline-for-windows-phone.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nnew pipeline mode\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nfor windows\u003c/p\u003e\n\u003cp\u003ephone to be the default, its clearly the way to go forward in the long run since we just don’t have any other choice. All feedback on the new pipeline found it to improve performance significantly and generally reduces some of the paint issues that we run into with Windows Phone. However, there are a couple of reports pointing out that font quality has degraded with the new pipeline. We are looking into this but came to the decision that even if this isn’t solvable we will stick with the new pipeline since the old one is just not viable for moving forward.\u003c/p\u003e","title":"Desktop, Vision Mobile \u0026 Misc Changes"},{"content":"\nThe Windows Phone port is one of our most painful ports, the platforms is so fragmented, volatile and rigid its remarkably hard to extract a common porting layer that will satisfy our requirements. We’ve just updated our servers with the 3rd port we did for Windows Phone, its experimental so its off by default, to activate it just use win.newPipeline=true in your build arguments.\nAs you may recall our first port targeted Windows Phone 7.5 and used XNA which Microsoft killed with Windows Phone 8.\nOur second port was\nsilverlight based and tried to dynamically create a scene-graph structure to match the graphics we are drawing in code, this is a very \u0026ldquo;imaginative\u0026rdquo; approach and it worked for most cases but had a lot of issues worst of which was very bad graphics performance and paint artifacts that were very hard to fix.\nThe third approach takes a very different direction, we effectively create a writeable bitmap object and draw onto a huge int array representing the screen. This means we draw everything. Our initial attempt at this tried to use silverlight for this but this performed very badly, so we ported Pisces to C# and use that to some degree to get basic graphics primitives and image blitting working on the platform. This isn’t the best approach in terms of performance but its better than what we have now and might be good enough for now. If this pans out we can always port some of the low level code to direct x using the basic API’s we already implemented.\nPlease try this new port and let us know both here and in the discussion forum how it affects your application.\nThis was quite a bit of work that took a lot of effort we have a pretty large pipeline of tasks ahead of us both in terms of bug fixes and pending features, so if a particular issue you filed wasn’t addressed please bare with us as we work thru the backlog. Its OK to remind us occasionally since things sometimes do fall thru the cracks.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — February 4, 2014 at 8:25 am (permalink) Anonymous says:\nStill some minor bugs but way better than the previous support. Keep up the good work !\nAnonymous — April 28, 2014 at 10:27 am (permalink) Anonymous says:\nSo far my development under WP has been going well, and I’m making a game. Performance wise, it’s \u0026ldquo;playable\u0026rdquo;, maybe not the best but I am using a low-end device for debugging.\nOverall it’s a good port, but better performance through through directX would be nice! 🙂\nAnonymous — April 28, 2014 at 12:28 pm (permalink) Anonymous says:\nUnfortunately I don’t think we will be able to use DirectX. The problem is that when you use DirectX we can’t use text and we can’t use widgets (e.g. TextInput), it might be possible to achieve something like that but it seems rather difficult in comparison to other platforms.\nAnonymous — April 30, 2014 at 5:59 am (permalink) Anonymous says:\nNo worries, the latest build of the game runs smooth on low-end devices! Had to improve some GC logic etc for the game.\nIt really does show how powerfull CodenameOne is, great job guys!\nAnonymous — July 24, 2014 at 4:28 am (permalink) Anonymous says:\nHi!\nIs the win.newPipeline=true now on by default? I tried to build with and without it and the build seamed to generate the same .xap file.\nAnonymous — July 24, 2014 at 2:13 pm (permalink) Anonymous says:\nHi,\nyes its the default. You can set it to false to disable it.\nAnonymous — October 30, 2014 at 5:57 am (permalink) Anonymous says:\nHello, has further improvement/updates been made since? Also what are the current limitations to this port compared to Android/IOs?\nAnonymous — October 30, 2014 at 9:42 am (permalink) Anonymous says:\nThe port is far inferior and there was no progress to speak of. From talking to our enterprise/corporate subscribers it seems they only want Windows Phone as a checklist feature and prefer we invest our efforts on the iOS/Android fronts.\nAnonymous — October 30, 2014 at 11:18 am (permalink) Anonymous says:\nThanks for the feedback. I am seeing WP gaining momentum and with Windows Phone 10, it might gain more in the near future. Its a pity CN1’s direction is currently dictated by current paying customers since your initial ethos was to create a toolchain that enables developers to write code once that would run on most major platforms. I don’t blame you Shai, but it would be so nice to see good support for at least these three major platforms, which might attract more paying customers. Some colleagues of mine are advising me to invest development in web apps which are more portable for major platforms in the long run.\nAnonymous — October 30, 2014 at 9:56 pm (permalink) Anonymous says:\nOur direction was always dictated by paying users as we repeatedly stated in the discussion forum.\nWindows phone isn’t growing anywhere and got 3 total rewrites so far because of Microsoft’s flakiness.\nTry getting a non-trivial webapp to work on the mobile version of internet explorer not to mention the browser changes made in the Android 4.x branch which have no workarounds available then talk about the \u0026ldquo;portability of the web\u0026rdquo; nonsense. Anyone who says web is portable didn’t actually use it professionally on a wide scale.\nAnonymous — October 31, 2014 at 6:03 am (permalink) Anonymous says:\nShai, when people look at a product offered, they usually look at the company’s first web page (at least that the case with me), which states very clearly your support for major platforms such as Android, IOs, BlackBerry and Windows Phone so forgive me for not looking at your discussion forums about how they are ‘really’ supported and at what level. It initially sounds to me you support everything quite well to some extent until I read this blog article of yours.\nAgreed, Windows Phone may not have gained much traction until now, but in the country where I live, I see more people using it than iPhones surprisingly, as it is the case in some parts of Europe. I don’t understand your comment about blaming Microsoft for your support hindrance, but it would be disingenuous to blame Microsoft if you are unable to make it work properly with your platform’s architecture.\nMy friend has a company that writes web apps quite successfully for various clients, both big and small. So yes, it all depends on the nature of the app, but your comment is a little strong about people that still write web apps.\nLooking at your pricing package I would have loved to pay as a corporate or enterprise customer if you support Windows Phone quite well. Do you support BB10? I reckon your customers are using the Android port for running on that platform. Going back to the main discussion, even if I am a paying customer, I won’t have the guarantee you will support Windows Phone platform because the majority of your paying customers don’t want it as a main feature (until they decide to) and I cannot compete with the majority which is my main concern and its difficult for me to invest money into your services with this uncertainty. Thanks and all the best to you, Jan.\nAnonymous — October 31, 2014 at 8:47 am (permalink) Anonymous says:\nIf you were a corporate customer it would be financially viable for us to take the 3-6 man months of engineering effort required to rewrite the Windows Phone port.\nWe do give corporate/enterprise customers the guarantee that their priority use cases will be properly supported. Obviously the effort required for Windows Phone is much bigger than most of the other tasks we face mostly due to inherent design choices made by MS.\nJust so I’m clear about the word majority, we have a few pro customers who want Windows Phone, but no Enterprise/Corporate users who are interested in it.\nWe have a couple of pro users to whom BB10 is important but they are satisfied with the option of using the APK and we try to keep the chief functionality level there working with BB10.\nAnonymous — December 27, 2014 at 6:32 pm (permalink) Anonymous says:\nHi,\nis there any progress in developing Apps for Win 8.x Phones?\nWhat is about ‘packing’ a wep app core within codenameone?\nis there any help article available for signing the app?\nThanks, Jan\nAnonymous — December 28, 2014 at 4:44 am (permalink) Anonymous says:\nHi,\nthere is no need/option to sign for Windows Phone. MS signs on its own and since Windows Phone doesn’t have an OTA install option (without the store) there is no real need. Currently none of our enterprise customers have made a formal request to justify the effort on Windows Phone. We support desktop development which should work well for the more popular Windows platforms such as the Surface Pro.\nAnonymous — February 14, 2015 at 8:32 pm (permalink) Anonymous says:\nHi Shai,\ni tried to build a very simple app and deploy it to my\nLumia 630 phone by clicking on the *.XAP File uploaded\non OneDrive.\nIt says something like (in german):\nThis enterprise app cannot be installed…\nDo i have to sign it with windows phone sdk?\nI understand your last answer in the way that\nthis is not necessary / possible ?\nThanks for an answer,\nJan\nAnonymous — February 15, 2015 at 5:21 am (permalink) Anonymous says:\nWindows Phone is the only \u0026ldquo;modern\u0026rdquo; mobile OS that doesn’t support installing apps over the air (or by click) only via cable sync or thru the store beta test process.\nAnonymous — February 23, 2015 at 8:52 pm (permalink) Anonymous says:\nHi Shai,\nsorry, but no success:\n– I tried to install the app via SD card,\n– it does not appears in the App \u0026ldquo;Store\u0026rdquo;\n– clicking on it in WP 8 file manager doesn’t work\n– i try to build it actuallay again (24-02-2015)\nthe message stays the same (… cannot be installed)\nOliver\nP.S.\nThe same code (simple list of buttons) runs even\non my very old sony ericsson k800i as j2me app…\nany idea?\nAnonymous — February 24, 2015 at 3:45 am (permalink) Anonymous says:\nSee http://www.codenameone.com/…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/a-new-pipeline-for-windows-phone/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/a-new-pipeline-for-windows-phone/a-new-pipeline-for-windows-phone-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/a-new-pipeline-for-windows-phone/a-new-pipeline-for-windows-phone-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe Windows Phone port is one of our most painful ports, the platforms is so fragmented, volatile and rigid its remarkably hard to extract a common porting layer that will satisfy our requirements. We’ve just updated our servers with the 3rd port we did for Windows Phone, its experimental so its off by default, to activate it just use win.newPipeline=true in your build arguments.\u003c/p\u003e\n\u003cp\u003eAs you may recall our first port targeted Windows Phone 7.5 and used XNA which Microsoft killed with Windows Phone 8.\u003c/p\u003e","title":"A New Pipeline For Windows Phone"},{"content":"\nWe’ve just uploaded a new how do I\ntutorial for push notification\n. This tutorial covers the basics and is complementary to the post we\npublished a while back covering push\n.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMahmoud — June 25, 2016 at 11:52 pm (permalink) Mahmoud says:\nHello,\nsome time when i call registered for push in some android devices\nthe device hang or the app destroyed and i have to shut down app and reopen then call registered for push everything is ok\nany idea please\nthanks\nShai Almog — June 26, 2016 at 4:47 am (permalink) Shai Almog says:\nHi,\ndo you have anything in the register callback? Can you place some logging there so you will see if that method is reached and if so where does it get stuck?\nIf you can reproduce this on one of your devices try connecting this with a cable and DDMS to see the printouts.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/push-notification-tutorial/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/push-notification-tutorial/push-notification-tutorial-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/push-notification-tutorial/push-notification-tutorial-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve just uploaded a new how do I\u003cbr\u003e\n\u003ca href=\"/how-do-i---use-push-notification-send-server-push-messages.html\"\u003e\u003cbr\u003e\ntutorial for push notification\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n. This tutorial covers the basics and is complementary to the post we\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/3/post/2013/07/pushing-it.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\npublished a while back covering push\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"notice-this-post-was-automatically-converted-using-a-script-from-an-older-blogging-system-some-elements-might-not-have-come-out-as-intended-if-that-is-the-case-please-let-us-know-via-the-comments-section-below\"\u003eNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\u003c/h2\u003e\n\u003ch2 id=\"archived-comments\"\u003eArchived Comments\u003c/h2\u003e\n\u003cp\u003e\u003cem\u003eThis post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\u003c/em\u003e\u003c/p\u003e","title":"Push Notification Tutorial"},{"content":"\nOne of our enterprise developers started complaining about the performance of our Android port, which forced us to take a closer look at our rendering pipeline on Android. It seems that Google’s hardware acceleration broke pretty much all the best practices of the Android 2.x era and what we had wasn’t taking full advantage of \u0026ldquo;project butter\u0026rdquo; the codename for Google’s new Android rendering layer.\nThis took a lot of effort to adapt and the effort is still ongoing but we wrote a brand new rendering layer for Android, at the moment you would need to switch it on explicitly and it will only work for Android 3.x or newer. When we will feel that its stable we will flip the default switch and make this the default for all future Android builds.\nIf you want to play with it just use the build argument android.asyncPaint=true\nIn this mode all paint graphics operations are added to a \u0026ldquo;task\u0026rdquo; pipeline and rendered asynchronously which allows better utilization of the device GPU for some use cases. Because of that this mode returns false from Display.areMutableImagesFast() this allows us to optimize rendering to avoid double buffering paradigms where possible (e.g. within the MapComponent).\nOne of the nice unintended side effects of this rendering mode is that color reproduction on the device is more accurate in subtle ways. The rasterization process on Android devices is slightly different especially on\nPenTile\ndevices (very common on Android) and when we use this approach such devices produce a more accurate result.\nAnother unexpected bonus we got as a result of this change was that Android related GPU debugging tools started working for Codename One applications. Unfortunately, they indicated extreme overdraw issues for some cases. Overdraw indicates that we paint the same pixel multiple times to draw a single form which means the UI will effectively be slower. Androids tools are really good at pointing out a problem but they are awful at pointing us to the location of the problem. So we had to extend our performance monitor tool and add a special mode to it that shows the exact graphics operations performed by every component painting itself. This can be illuminating when trying to see why a specific UI is so slow, it also provides stack traces for every graphics operation.\nTo try it just open the performance monitor from the simulator and select the second tab then refresh within the form you want to inspect. You can then traverse the tree of components and see the exact rendering calls that were used to draw every single component within the hierarchy.\nUsing this tool we noticed that the parent form drew itself twice for every rendering cycle, it turns out that a special case needed only for transitions was active with every repaint. This was easy to fix in the core and should provide a small performance boost to Codename One applications on all platforms.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — January 28, 2014 at 5:22 am (permalink) Anonymous says:\nYes! Great Job!\nThis is something I’ve really been waiting for.\nAnonymous — February 5, 2014 at 5:46 am (permalink) Anonymous says:\nIt’s funny because just yesterday I thought I noticed my app was running smoother, sometimes its easy to forget you eager beavers are improving our lives secretly and remotely, I appreciate this so much. As for ever draw, Im assuming you can detect if something wont be scene and not render it, a little like a 2d game tile engine. I THINK though that this new build hint is making the native browsers I have embedded in my app flash.\nAnonymous — March 12, 2014 at 1:13 pm (permalink) Anonymous says:\nExcellent! I think the android port has been in need of a serious performance review for quite some time now. Android being the mobile platform with the most market share, it would be quite expedient if performance on this platform is focused on more intently. Looking forward to hearing more about this. Thanks!\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/a-new-pipeline/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/a-new-pipeline/a-new-pipeline-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/a-new-pipeline/a-new-pipeline-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of our enterprise developers started complaining about the performance of our Android port, which forced us to take a closer look at our rendering pipeline on Android. It seems that Google’s hardware acceleration broke pretty much all the best practices of the Android 2.x era and what we had wasn’t taking full advantage of \u0026ldquo;project butter\u0026rdquo; the codename for Google’s new Android rendering layer.\u003c/p\u003e\n\u003cp\u003eThis took a lot of effort to adapt and the effort is still ongoing but we wrote a brand new rendering layer for Android, at the moment you would need to switch it on explicitly and it will only work for Android 3.x or newer. When we will feel that its stable we will flip the default switch and make this the default for all future Android builds.\u003c/p\u003e","title":"A New Pipeline"},{"content":"\nAs you may know Apple will require that all applications submitted next month would be compiled with XCode 5 and target iOS 7 primarily. We\nsupported this for quite some time\nhowever the default was still set to the legacy support first. Today we are deploying an update which will make xcode 5.0 the default and make the theme use iOS 7 theme styling when running on an iOS 7 device.\nWe are also updating the plugin to default to iOS 7 skins and adding the old iOS 6 related skins under the \u0026ldquo;more\u0026rdquo; menu in the device section, this will allow you to target existing devices more effectively.\nNotice that components such as Spinner do not work as they should in iOS 7, you should switch to using the Picker component. It provides native functionality when running on the device. This is due to a radical design of the picker UI in iOS 7.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/switching-defaults/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/switching-defaults/switching-defaults-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/switching-defaults/switching-defaults-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eAs you may know Apple will require that all applications submitted next month would be compiled with XCode 5 and target iOS 7 primarily. We\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/3/post/2013/10/seven.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nsupported this for quite some time\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nhowever the default was still set to the legacy support first. Today we are deploying an update which will make xcode 5.0 the default and make the theme use iOS 7 theme styling when running on an iOS 7 device.\u003c/p\u003e","title":"Switching Defaults"},{"content":"\nAn article of mine with the above title just\ngot published in dzone\ncheck it out and let us know what you think in the comments over there.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/5-cool-new-features-in-codename-one-for-netbeans-ide/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/5-cool-new-features-in-codename-one-for-netbeans-ide/5-cool-new-features-in-codename-one-for-netbeans-ide-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/5-cool-new-features-in-codename-one-for-netbeans-ide/5-cool-new-features-in-codename-one-for-netbeans-ide-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eAn article of mine with the above title just\u003cbr\u003e\n\u003ca href=\"http://netbeans.dzone.com/articles/5-cool-new-features-codename\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\ngot published in dzone\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\ncheck it out and let us know what you think in the comments over there.\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\u003c/p\u003e","title":"5 Cool New Features in Codename One for NetBeans IDE"},{"content":"\nNative interfaces allow developers to invoke platform native methods/functions/libraries and even widgets directly from within Codename One without having to adapt your code to every platform. They are a very powerful tool when bridging between Codename One and OS specific features to access functionality that might not yet be exposed in the Codename One platform.\nNormally in Java we would use JNI to access \u0026ldquo;native\u0026rdquo; however, JNI is designed to access C and we need much more. Codename One allows developers to access Dalvik (Java) when running under Android and defines that as \u0026ldquo;native\u0026rdquo;, C# when running in Windows Phone and Objective-C when running under iOS. Because of that it is remarkably hard to map arbitrary objects, callbacks and functionality to a native call. So to simplify that work we placed many restrictions on the construction of a native interface, however you can still accomplish pretty spectacular things such as a\ncomplete working socket implementation\nand more.\nCheck out the new\nHow Do I? video we just published covering native interfaces\n.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nGert — July 13, 2017 at 2:14 am (permalink) Gert says:\nIs EVERYTHING of native code possible in codenameone by native interface?\nIn other word, when we assume we built some project by native code, is it possible to build ABSOLUTELY SAME PRODUCT (design, effect and functions etc,,of course, besides execution file size and response speed..) in cd1?\ne.g.\nLike Camera overlaying (for face detection, like MSQRD app, …)\nShai Almog — July 13, 2017 at 4:26 am (permalink) Shai Almog says:\nThese things can be done in Codename One but \u0026ldquo;everything\u0026rdquo; is a bit of a big word.\nFurthermore, lets separate \u0026ldquo;can\u0026rdquo; from \u0026ldquo;should\u0026rdquo;. If a lot of your code is native and you need a big native interface abstraction this might become painful to the point where Codename One isn’t worth it. I can’t put my finger on an exact point since it varies and this depends on your needs.\nGert — July 13, 2017 at 4:39 am (permalink) Gert says:\nThanks for your kind answer.\nWell, do you have any idea how to build face recognition app in cd1?\nThere, the issue for me is just how to get image info in real-time. (during camera showing)\nBest.\nShai Almog — July 14, 2017 at 6:34 am (permalink) Shai Almog says:\nLook at how it’s done in native and follow those instructions. I haven’t done this so I can’t really point you at anything.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/native-interface/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/native-interface/native-interface-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/native-interface/native-interface-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eNative interfaces allow developers to invoke platform native methods/functions/libraries and even widgets directly from within Codename One without having to adapt your code to every platform. They are a very powerful tool when bridging between Codename One and OS specific features to access functionality that might not yet be exposed in the Codename One platform.\u003c/p\u003e\n\u003cp\u003eNormally in Java we would use JNI to access \u0026ldquo;native\u0026rdquo; however, JNI is designed to access C and we need much more. Codename One allows developers to access Dalvik (Java) when running under Android and defines that as \u0026ldquo;native\u0026rdquo;, C# when running in Windows Phone and Objective-C when running under iOS. Because of that it is remarkably hard to map arbitrary objects, callbacks and functionality to a native call. So to simplify that work we placed many restrictions on the construction of a native interface, however you can still accomplish pretty spectacular things such as a\u003cbr\u003e\n\u003ca href=\"https://github.com/shannah/CN1Sockets\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\ncomplete working socket implementation\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nand more.\u003c/p\u003e","title":"Native Interface"},{"content":"\nThe next plugin update will finally include the support for building desktop applications with Codename One and to celebrate this we added a\nHow Do I video on this subject\n. Notice that this is a pro only feature so if you don’t have a pro account this will fail on the build server.\nThe end result should be pretty similar to what you get in the simulator, I assume we will make some improvements as we move along to refine the user experience a bit further and adapt it for desktop development.\nWe also added support for XML user interface elements in the designer, if you activate team mode in the designer and save the resource file you will now notice that we generate a UI file for every form (as well as a file with no extension which is a binary file). Currently the UI file is write only to prevent issues with this approach from breaking existing usage. However, if you want to move to a more XML based file format right now you would be able to edit your top level XML file and set\nuseXmlUI=\u0026ldquo;false\u0026rdquo;.\nOnce you change that all changes to the .ui files will be incorporated when\nyou reload the resource file and you will be able to work with XML files which might be convenient if you are doing elaborate team work. This is also convenient for the case of a recovery if a file gets corrupted you should be able to recover more easily and see what happened.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — January 28, 2014 at 4:50 am (permalink) Anonymous says:\nGood article but it should have been a bit more descriptive. Any suggestions for me, I do don’t have a pro account.\nAnonymous — January 28, 2014 at 5:00 pm (permalink) Anonymous says:\nYou can handcode a desktop app by searching for instructions in the discussion forum. Pro subscription has many other benefits.\nAnonymous — January 30, 2014 at 1:08 pm (permalink) Anonymous says:\nWhy?\nWhat am I missing? Why on earth would I want a desktop version of my tablet app?\nAnonymous — January 30, 2014 at 2:33 pm (permalink) Anonymous says:\nInitially that’s what we thought but users asked for that quite a lot. There are several reasons:\n1. Demo – this way users can download a demo version to run on their PC/Mac.\n2. x86 tablets – E.g surface pro etc. have a niche following in some sectors.\n3. Checklist feature – some developers need a desktop app as a feature but don’t care if it feels like a mobile app.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/build-desktop-apps-xml-improvements/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/build-desktop-apps-xml-improvements/build-desktop-apps-xml-improvements-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/build-desktop-apps-xml-improvements/build-desktop-apps-xml-improvements-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe next plugin update will finally include the support for building desktop applications with Codename One and to celebrate this we added a\u003cbr\u003e\n\u003ca href=\"/how-do-i-use-desktop-javascript-ports.html\"\u003e\u003cbr\u003e\nHow Do I video on this subject\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n. Notice that this is a pro only feature so if you don’t have a pro account this will fail on the build server.\u003c/p\u003e\n\u003cp\u003eThe end result should be pretty similar to what you get in the simulator, I assume we will make some improvements as we move along to refine the user experience a bit further and adapt it for desktop development.\u003c/p\u003e","title":"Build Desktop Apps \u0026 XML Improvements"},{"content":"\nSteve\nrecently added an implementation of a\nsockets library\nwhich is pretty cool and very timely since we are just about to release our own socket library and unlike his work which supports all Codename One targets we currently only support iOS \u0026amp; Android.\nAt the moment we only support TCP sockets, we support server socket (listen/accept) on Android but not on iOS. You can check if Sockets are supported using the Socket.isSupported() and whether server sockets are supported using Socket.\nisServerSocketSupported().\nTo use sockets you can use the Socket.connect(String host, int port, SocketConnection eventCallback) method. To listen on sockets you can use the Socket.listen(int port, Class scClass) method which will instantiate a SocketConnection instance (scClass is expected to be a subclass of SocketConnection) for every incoming connection.\nThis simple example allows you to create a server and a client assuming the device supports both:\nAlso in the coming update to Codename One we will include support for multiline entries in trees and more arbitrary tree node types. To support that we added a new flag to indicate if the tree is multiline in which case each node would be a SpanButton instead of a button. This is pretty simple for the basic use case just invoke setMultilineMode(true).\nUnfortunately for the complex use cases up until now when we customized a tree entry one had to override the method: protected Button createNodeComponent(Object node, int depth), which relies on the Tree’s usage of buttons. So that method is now deprecated (although it will still work for now).\nYou should now override:\nprotected Component createNode(Object node, int depth), which allows you to return any component type. However, the tree needs methods to receive a click event from the node and to set an icon both of which aren’t available in Component. So for that purpose you might need to override: protected void bindNodeListener(ActionListener l, Component node), and: protected void setNodeIcon(Image icon, Component node). Just override them to support your custom component type unless its a Button/SpanButton (or subclass) both of which are supported.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — January 8, 2014 at 1:15 pm (permalink) Anonymous says:\nI like the more event-driven approach to sockets. Reminds me a little of the Node.js model. It removes a lot of the complexities around socket programming.\nAnonymous — January 8, 2014 at 1:47 pm (permalink) Anonymous says:\nThanks.\nWe were mostly trying to imitate the concepts of NetworkManager/ConnectionRequest for consistency and simplicity. The main pain point was server sockets, we just couldn’t find the right abstraction that will work with GCD on iOS. Unfortunately there is very little samples on iOS socket programming and a lot of developers incorrectly use POSIX sockets on iOS. This is a huge mistake, they work on wifi but they don’t guarantee to activate the radio and so they might fail to connect simply because the phone is trying to save some battery life.\nUnfortunately GCD doesn’t play well with the select() based behavior of Java sockets.\nAnonymous — January 12, 2014 at 10:16 am (permalink) Anonymous says:\nGreat to see that you are releasing a socket library. I have also checked out Steve’s CN1Socket library. I am working on home automation from mobile devices and need to use UDP sockets. I was unable to find UDP socket support in CN1Socket and from the text above, I see you that your library might also not have UDP support. Could you suggest any alternatives? I need to support iOS primarily right now, and android in a later release.\nAnonymous — January 12, 2014 at 3:58 pm (permalink) Anonymous says:\nAt this point in time we have no such plans since none of our enterprise customers asked for this functionality. I’m assuming that you are not an enterprise account holder, right?\nYou can probably extends Steve’s approach to support UDP or just use it as a reference to create your own cn1lib for UDP.\nAnonymous — March 21, 2014 at 5:32 pm (permalink) Anonymous says:\nShai,\nI am using NetBeans with the current 1.0.70 and I do not see any Socket or SocketConnection class as is shown in the javadoc online:\nhttps://codenameone.googlec…\nhttps://codenameone.googlec…\nI will use Steve’s library, but I would rather stay within Codename One as much as possible. Am I missing something in the plugin update process?\nAnonymous — March 22, 2014 at 4:58 am (permalink) Anonymous says:\nGo to project properties, Codename One settings and click update client libraries.\nAnonymous — March 24, 2014 at 3:11 pm (permalink) Anonymous says:\nUnfortunately this path is not there. I do not see Codename One settings. I am currently using Netbeans 7.3. I am looking into this and i will update when I find the answer.\nAnonymous — March 24, 2014 at 3:35 pm (permalink) Anonymous says:\nIn case this helps someone else: It appears that my property window was not expanding all the way to reveal the \u0026ldquo;Update Project libs\u0026rdquo; button. The end to a frusterating hunt.\nAnonymous — April 27, 2014 at 6:42 pm (permalink) Anonymous says:\nHello Shai!\nI’m developing an application for sending OSC messages and now I have the following questions. The Codename One supports the development of Sockets for the UDP protocol?\nAnonymous — April 28, 2014 at 2:21 am (permalink) Anonymous says:\nHi,\nno we don’t. However, you can write this using native code just like Steve implemented TCP sockets in the library linked above.\nAnonymous — December 7, 2014 at 8:23 am (permalink) Anonymous says:\nHi Shai,\nI’m looking for something like Android’s Expandable List in Codename One. Would a tree with an overridden createNode() now be the best choice? Or would you recommend using List and a Renderer containing another List?\nAnonymous — December 7, 2014 at 8:55 am (permalink) Anonymous says:\nOh, I forgot to mention: Unfortunately, I can’t just use the Tree as it is, since I need Buttons on the right hand side of each entry.\nAnonymous — December 7, 2014 at 2:54 pm (permalink) Anonymous says:\nYou can have buttons on the right hand side without a problem with a Tree as explained in the above post. You can just create a container with anything you want in it (multiline being the common example).\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/sockets-multiline-trees/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/sockets-multiline-trees/sockets-multiline-trees-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/sockets-multiline-trees/sockets-multiline-trees-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://sjhannah.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nSteve\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nrecently added an implementation of a\u003cbr\u003e\n\u003ca href=\"https://github.com/shannah/CN1Sockets\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nsockets library\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nwhich is pretty cool and very timely since we are just about to release our own socket library and unlike his work which supports all Codename One targets we currently only support iOS \u0026amp; Android.\u003c/p\u003e\n\u003cp\u003eAt the moment we only support TCP sockets, we support server socket (listen/accept) on Android but not on iOS. You can check if Sockets are supported using the \u003ccode\u003eSocket.isSupported()\u003c/code\u003e and whether server sockets are supported using Socket.\u003c/p\u003e","title":"Sockets \u0026 MultiLine Trees"},{"content":"\nWe just added a new offering to our\npricing page\n, offline server. This option isn’t for everyone since it requires quite a lot of effort to setup and in fact includes less functionality than even the pro subscription.\nThe main reason for this offering is the old-school regulated industries where a cloud build solution just isn’t an option. In those cases you can still enjoy the benefits of our cloud architecture within the organization. However, you would need to setup at least 4 separate servers in order to get these benefits so the total cost in hours/hardware and licensing is pretty steep.\nIf you think this is the right solution for you please\ncontact us\n, unlike other offerings corporate servers are sold by us in person with a more corporate friendly invoicing process.\nNotice that the corporate server is priced very differently when compared to regular pricing, support is separately bundled and priced on a case by case basis since its much harder for us to properly evaluate support overhead. The pricing doesn’t limit developer count and includes updates for one year.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/offline-builds/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/offline-builds/offline-builds-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/offline-builds/offline-builds-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe just added a new offering to our\u003cbr\u003e\n\u003ca href=\"/pricing.html\"\u003e\u003cbr\u003e\npricing page\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, offline server. This option isn’t for everyone since it requires quite a lot of effort to setup and in fact includes less functionality than even the pro subscription.\u003c/p\u003e\n\u003cp\u003eThe main reason for this offering is the old-school regulated industries where a cloud build solution just isn’t an option. In those cases you can still enjoy the benefits of our cloud architecture within the organization. However, you would need to setup at least 4 separate servers in order to get these benefits so the total cost in hours/hardware and licensing is pretty steep.\u003c/p\u003e","title":"Offline Builds"},{"content":"\nSteve\njust released a very important\ncn1lib\nthat effectively provides developers with elaborate low level graphics primitives to draw pretty much everything on all platforms. The main use case for this library is for charts and graphs which up until now we had to do with the relatively limited graphics capabilities of Codename One (which are currently optimized for speed/portability).\nPisces is a rendering engine developed at Sun that was designed to be very portable, it performs all the rendering in Java and can thus do relatively advanced graphics even on J2ME devices that don’t necessarily have such graphics capabilities. The downside is that it can’t be fast since it effectively can’t use the GPU.\nWe are working on adding \u0026ldquo;native\u0026rdquo; support for advanced graphics capabilities that will use hardware acceleration to bring this level of graphics to all use cases. This is obviously a tall order and would only work on smartphones so the utility of the Pisces port will remain even when we provide such an API.\nSince the Pisces API outputs an image, the drawing of the image itself should be pretty fast so for the use case of static chart creation this tool should be more than enough.\nOther than that we will be introducing support for a String picker in the upcoming update of Codename One. Essentially the Picker class will also allow you to set a string array to pick from just like it allows you to pick a date/time etc.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — January 3, 2014 at 8:36 am (permalink) Anonymous says:\nHello, when are you releasing the upcoming update?\nAnonymous — January 4, 2014 at 6:07 am (permalink) Anonymous says:\nYesterday.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/pisces-string-picker/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/pisces-string-picker/pisces-string-picker-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/pisces-string-picker/pisces-string-picker-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://sjhannah.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nSteve\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\njust released a very important\u003cbr\u003e\n\u003ca href=\"/cn1libs.html\"\u003e\u003cbr\u003e\ncn1lib\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nthat effectively provides developers with elaborate low level graphics primitives to draw pretty much everything on all platforms. The main use case for this library is for charts and graphs which up until now we had to do with the relatively limited graphics capabilities of Codename One (which are currently optimized for speed/portability).\u003c/p\u003e\n\u003cp\u003ePisces is a rendering engine developed at Sun that was designed to be very portable, it performs all the rendering in Java and can thus do relatively advanced graphics even on J2ME devices that don’t necessarily have such graphics capabilities. The downside is that it can’t be fast since it effectively can’t use the GPU.\u003c/p\u003e","title":"Pisces \u0026 String Picker"},{"content":"\nDecember has been pretty busy with the release of 2.0 but January will probably be MUCH busier since we have a major backlog of features requested by enterprise and pro users. We are already well under way with quite a few interesting features but most of them won’t be landing for the next couple of weeks since we need the trunk to remain stable for now.\nBefore I get started, if you are interested in Socket support for Codename One and native interface’s you should check out the work\nSteve Hannah\ndid on a\nsocket library\nfor Codname One. Its also a great reference implementation on how one would write a native library implementation!\nWe have a separate socket implementation of our own which has a somewhat different approach, we should be releasing it at some point before 2.1 and it is on our roadmap for the next couple of months. Currently we plan to only support TCP streams and we might support server sockets on select platforms (currently iOS server socket isn’t planned).\nWe are doing quite a bit of work for our enterprise customers, we already completed the effort for two major requests. The first asked for improved text input in iOS where today we always fold the virtual keyboard when a user finished editing the text field. In fact we have an\nissue\nwhich we tried to resolve in the past and deemed it to be impossible to fix. Well… Few things are impossible when an enterprise customer makes a formal request so we spent quite a few days trying to resolve this, after the next server update you should be able to see the fruits of this labor by defining the build argument ios.keyboardOpen=true which will keep the keyboard always open when you start editing unless you press the \u0026ldquo;Done\u0026rdquo; button.\nAs part of this work we also added a feature to text area that allows it to grow up to a limit so using textArea.setGrowLimit(int) will limit the amount of rows to which the text area grows based on user input.\nAnother enterprise developer needed to detect a disconnect of headphones which is pretty niche but we added that as well. Starting with the next server update you should be able to define the build arguments ios.headphoneCallback=true and android.headphoneCallback=true\nOnce those are defined you should also define the callback methods with these signatures in your main class:\npublic void headphonesDisconnected() {\n}\npublic void headphonesConnected() {\n}\nThey should be invoked based on headphone state.\nWe will also be releasing support for desktop builds, this support will be limited to pro users since a typical desktop app includes the full JVM within it making it a hefty download that puts a toll on our servers. You would effectively get a Mac OS DMG or a Windows MSI/EXE to install a Codename One app that would include pretty much everything you would expect. We’ll write a more detailed tutorial when that functionality launches.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — December 31, 2013 at 11:45 am (permalink) Anonymous says:\nRegarding PC/MAC builds, am disappointed it is Pro-only, and I suspect there is a sweet spot somewhere between Basic and Pro. $70 per month more for this single and very attractive feature is too much to take. Would love an option for the do-it-yourself crowd.\nAnonymous — December 31, 2013 at 4:37 pm (permalink) Anonymous says:\nWe were asked that a couple of times. Unfortunately the features that are important to you are not those that are important to other people and so forth.\nPro \u0026amp; enterprise users are what keeps us in business and they effectively subsidize basic \u0026amp; free accounts. We ran the numbers on providing a cheaper account in the middle between pro/basic and it just won’t add up.\nAnonymous — January 24, 2014 at 6:20 am (permalink) Anonymous says:\nToo bad. I could use the the pro account myself but it is too expensive for amateur developer. I would love if you consider it again in the future.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/upcoming-features/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/upcoming-features/upcoming-features-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/upcoming-features/upcoming-features-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eDecember has been pretty busy with the release of 2.0 but January will probably be MUCH busier since we have a major backlog of features requested by enterprise and pro users. We are already well under way with quite a few interesting features but most of them won’t be landing for the next couple of weeks since we need the trunk to remain stable for now.\u003c/p\u003e\n\u003cp\u003eBefore I get started, if you are interested in Socket support for Codename One and native interface’s you should check out the work\u003cbr\u003e\n\u003ca href=\"http://sjhannah.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nSteve Hannah\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\ndid on a\u003cbr\u003e\n\u003ca href=\"https://github.com/shannah/CN1Sockets\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nsocket library\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nfor Codname One. Its also a great reference implementation on how one would write a native library implementation!\u003c/p\u003e","title":"Upcoming Features"},{"content":"\nTel Aviv, Israel – Mobile development platform Codename One is announcing the release of its 2.0 version on Wednesday, December 25th. In the 7 months since the May release of 1.1 Codename One has reached profitability, quadrupled its paying subscriber base and was downloaded by 500,000 developers.\nCodename One is a one of a kind solution that allows Java developers to build native applications that work on all mobile devices seamlessly. It combines an open source client architecture that integrates seamlessly with all major Java development environments: Eclipse, NetBeans and IntelliJ IDEA. To leverageits one of kind cloud build system. This unique architecture enables Java developers to build iPhone applications without owning a Mac or Windows Phone applications without a Windows 8 machine.\nVersion 2.0 is a major leap forward with containing 300 new features and improvements to the 1.1 version such as: Support for IntelliJ IDEA, Google Play Ads, binary 3rd party libraries and much more.\nThe platform to date has been used to build over 5,000 native mobile applications and has received widespread, viral acclaim in technology and business media including InfoWorld, Slashdot, Hacker News, VentureBeat, Business Insider, The Next Web, Dr. Dobbs and Forbes.\n\u0026ldquo;The level of traction we are seeing is astounding, it is amazing that in less than 2 years we have amassed so many applications.\u0026rdquo; said co-founder and CEO Shai Almog.\nAlmog, along with co-founder Chen Fishbein, decided to launch the venture after noticing a growing inefficiency within mobile application development. By enabling developers to significantly cut time and costs in developing native applications for iOS, Android, Blackberry, Windows Phone and other devices, Almog and Fishbein hope to make mobile application development increasingly feasible.\nThe Java-based platform is open-source and utilizes lightweight technology, allowing it to produce unique native interfaces highly differentiated from competitive cross-platform mobile development toolkits, which typically use HTML5 or heavyweight technology.\nThe startup’s founders are recognized for engineering Sun Microsystems’s famous Lightweight User Interface Toolkit, a mobile platform used by leading mobile carriers and industry leaders to this date.\nCodename One is available for download free of charge.\n**\nAbout Codename One\n**\nCodename One is an Israel-based technology company that has created a powerful cross-platform software development kit for mobile applications. The technology enables developers to create native applications across multiple operating systems using a single code base. Codename One was founded by renowned software engineers Shai Almog and Chen Fishbein in 2012.\n__Download\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — March 13, 2015 at 7:09 am (permalink) Anonymous says:\nThanks for excellent job.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/with-25m-device-installs-mobile-development-platform-codename-one-announces-version-20/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/with-25m-device-installs-mobile-development-platform-codename-one-announces-version-20/codename-one-charts-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eTel Aviv, Israel – Mobile development platform Codename One is announcing the release of its 2.0 version on Wednesday, December 25th. In the 7 months since the May release of 1.1 Codename One has reached profitability, quadrupled its paying subscriber base and was downloaded by 500,000 developers.\u003c/p\u003e\n\u003cp\u003eCodename One is a one of a kind solution that allows Java developers to build native applications that work on all mobile devices seamlessly. It combines an open source client architecture that integrates seamlessly with all major Java development environments: Eclipse, NetBeans and IntelliJ IDEA. To leverageits one of kind cloud build system. This unique architecture enables Java developers to build iPhone applications without owning a Mac or Windows Phone applications without a Windows 8 machine.\u003c/p\u003e","title":"With 25m Device Installs, Mobile Development Platform Codename One Announces Version 2.0"},{"content":"\nWe will release the full Codename One 2.0 in a couple of days in the meantime here are the release notes covering the changes for this version.\n**\nHighlights Of This Release\n**\nSupport for IntelliJ IDEA\nSupport for Google Play Ads on iOS/Android\nSupport for 3rd party libraries using the cn1lib format\nMajor improvements to the Windows Phone 8 port making it far more reliable\nFine tuned performance on iOS optimized garbage collector behavior\nExtensive code migration to use Java 5 features and collections, generified some core interfaces\nXML mode for Codename One Designer allows for better usage in source control scenarios\nImproved text input and browser support in the simulator\nNative Facebook login support on iOS/Android\nNative share functionality on iOS\nSupport for iOS 7 appearance/functionality, including new device skins\nNew native picker API allows opening time/date picker of the native platform when applicable\nSupport for push notification on blackberry\nAdded export/import of CSV/Android XML string bundles (localization) to the designer tool\nAdded standardized API for pinch to zoom (simulated by a right click drag in the simulator)\nImage background styles can now be scaled to fit and fill as well as the many other options\nUpdated developer guide increasing its content by more than 30% to 200 pages\n**\nNew Components \u0026amp; Functionality of note\n**\nImage viewer class allowing pinch to zoom and swiping between images\nAuto complete text field component\nLayered pane allows a more refined way of placing components on top of the entire UI\nInfinite scroll adapter allowing a user to scroll a container and add\nelements as he reaches the bottom\nMany improvements to the SideMenuBar – swipe to open, title commands, side menu or top and to the right\nSpan button – button component that can span multiple lines\nSpan label – label component that can span multiple lines\nMade location manager simpler to work with by adding a synchronous method to\nfetch location\nAdded JSObject API contributed by Steve Hannah\nAdded an XMLWriter API\nAdded new demos: Poker game, Push\nAdded image rotation API’s designed for camera images that can rotate or flip an image by square angles, this is important for rotating an image that isn’t a perfect square (e.g. taken by camera)\nAdded support for the GridBagLayout from AWT\nAdded access point support to the Android port (contributed by Fabricio from Pumpop)\nAdded gzip stream support and a GZipConnectionRequest\n**\nDetails\n**\nChanged friction values in scrolling algorithm\nImproved text area input handling in iOS by making it use the Codename One styling and have next/done buttons\nMade media event callbacks on Android happen on the EDT\nTabs are now more sensitive to swipe gestures\nImproved the simulator to behave more like a device in terms of event delivery, filesystem mappings and more\nFixed issue 794 which prevented Codename One from running on some older J2ME devices due to usage of UnsupportedOperationException in the retroweaver code\nSimulator can now simulate capturing audio/video\nFix for contact images in J2ME to work correctly\nRewrote event processing to be much faster and reduce GC thrushing\nRemoved some usage of Hashtable to speed up rendering\nFixed locationManager to call providerStateChanged once the gps status has changed\nFixed getCurrentLocation to return fast – get the current location if exists then fallback to network location.\nFix for issue 825 : iOS BrowserComponent doesn’t provide error codes on error\nImplemented RFE 826: Network activity indicator while loading pages on iOS WebBrowser\nFix for issue 893 in the Codename One designer : Unselected style lost properties when delete Selected style\nFix for issue 944 : DateSpinners can’t be disabled\nFix for issue 949 : Dragging Component inside scrollable container doesn’t properly scroll the container in both directions\nFixed the WebBrowser component to no longer flicker in the simulator!\nFix for Issue 960 : Result.getAsInteger(path) throws number format exception\nImproved simulator text input with fixes for Issue 957 : Simulator TextField misc bugs\nFixed audio on Android to pause the playing media when a call comes in\nFixed android native editing to fire the event only once the data has changed\nFix for a checkbox/mutli-button issue. When the multi button is in checked mode within a MultiList the emblem icon sometimes disappears\nFixed issue 955 : hamburger menu command not respecting enabled\nAdded ability to \u0026ldquo;inject\u0026rdquo; additional cookies into a connection request\nFix for storage file names to be normalized\nMade the framerate lock faster to smooth up animation a bit\nFixed back command behavior in the side menu with the GUI builder which is triggered because the command is both added and set to the form\nFixed the XML parser for reading some files with BOM\nFix for an issue where opening the mail app caused the app to restart\nFixed Audio playback not to crash on exceptions thrown by the Android device\nFixed an SMS sending issue on blackberry devices and J2ME devices\nMade minor refinements for iOS peer cleanup and push notification behavior in case of an error\nSome improvements to memory utilization in iOS as part of fixes for issue 926 : iOS crash with sounds playing\nFix for issue 946 : Dropdown on Windows Phone is transparent\nFixed native commands on Android to refresh correctly when modified for cases where withText or other hints were used\nFixed issue 939 : Two Memory Leaks in iOS Obj C Code\nFixed the designer to hide properties that are overriden by custom component attributes\nFix for RFE 936: text shadow bottom right (i.e. drop shadow)\nFixed push registration to not fail completely in China\nFixed full screen ads which had a race condition that prevented ad skipping after clicking\nAdded support for array arguments to connection requests\nFixed fail silently to not broadcast fail events anymore\nAdded support for timeout in the location manager sync request\nFixed a potential Android exception that can happen during background playback of audio due to display not checking whether it is initialized\nAdded auto complete text field to the GUI builder\nFixed User-Agent behavior on iOS to return the correct user agent value\nFixed Android audio playback to return playing false when buffering and also not fail with exception on some cases.\nFixed iOS audio capture\nFixed an issue with Image capture on iOS\nFixed media playback hints for iOS\nFix for issue 937 : GenericSpinner does not allow you to provide new renderer via the setRenderer() method\nFixed Android web progress dialogs to dismiss after 10 sec max\nFixed Android’s back button on video to not minimize the app\nFix for Issue 917 : Keyboard hide sometimes crashes on Android 4.3 – changed the SurfaceView to TextureView for SDK version \u0026gt; 18\nImplementation of RFE 928: Add \u0026ldquo;Contains\u0026rdquo; operator for Expression Language Contributed by Eric Coolman\nFix for killAndWait which seems to have violated the EDT since its inception\nFix for an issue with sidemenu bar with the keyboard open\nFixed a couple of sidemenu issues with screen resize and dragging the side menu from the open menu button.\nFixed the dragStop to check all parents if it’s in a middle of a scroll gesture\nFixed an issue with multibutton drag and drop\nFixed an issue with pointer released being invoked on a component when stopping a swipe scroll operation\nAdded an option to customize the cookie HTTP header to workaround a bug in PHP which isn’t treating the cookie header as case insensitive\nFixed issue with side swiping the side menu bar where pressing again while swiping back a menu that was previously swiped in triggered the seamless creation of a new menu that didn’t have the limits of the old menu thus allowed dragging the menu to cover the entire screen\nAdded action listener to slider to allow more coarse event dispatch\nFixed exception handling behavior in addToQueueAndWait\nFixed a bug in android where pressing back while dialog was showing minimized the app\nFixed TextField right alignment issue (mostly relevant for rtl langs)\nAdded rtl support to the android native editing\nFixed an issue with video capture on nexus 7 devices\nImplemented RFE 919: TextArea – Localization by adding a span button\nImproved Analytics API that integrates with the application analytics\nChanged the detect network URL to google.com and made it configurable\nFix for dialog regression where the onShow event wasn’t fired for Dialog\nChanged isTablet implementation to better detect tablets\nFixed bug in ImageIO.save() where the image was recycled too soon\nFixed Capture to save the scaled versions with a .jpg extension to allow the gallery to identify the file and show a preview in the gallery\nFixed issue 918 Sidemenu closes automatically when keyboard is open\nFixed LayeredLayout to consider the margins in the calc size\nImplemented RFE 898: Textfield hint is not displayed while keyboard is open\nFixed issue 901 : Polling push support not calling registeredForPush\nFixed camera implementation based on issue 913\nUpdated capture to use the version of the ImageIO.save() method that accepts a file path to prevent out of memory errors\nAdded support for non-cyclic flicking of the ImageViewer curtesy of Fabrício Carvalho Cabeça of Pumpop\nFixed barcode reading crash on iOS 7\nFixes push with meta data that had a race condition with the initialization of Display.\nFixed remote control playback, so events from the screensaver on iOS will be delivered\nAdded Media information API’s and an OS version API\nFixed several crashes related to images and image scaling\nAdded new Media API’s allowing the developer to pass various hints to the playing media. Currently the first batch of hints allow developers to manipulate the \u0026ldquo;now playing\u0026rdquo; screen in iOS\nImproved notify status bar to include hints including the ability for a non-dismissible notice, added the option to dismiss a notice manually\nProvided an API to indicate whether notifications are supported\nAdded an option to hide the zoom map keys as a theme constant\nFix for commands, two identical commands with different client properties would resolve as equal and only one of them will get added\nAdded an OSVer constant to Display.getProperties() to return the OS version\nFixed issue 911 NPE occurs in TextArea constructor when input text is null\nFixed an issue with hints on List disappearing in the designer\nFixed an exception in the designer in EditableResources\nFixed push with type 3 to work as expected\nMade logging on Android smarter, instead of using System.out we will now use Log.d with the application name.\nFixed an issue with purchase where the success callback wasn’t sent to the activity\nFixed Issue 890 : TitledMap shows over open SideMenuBar on ios\nAdded an ability to drag vertically when a horizontal scroll component is in the hierarchy\nFixed a potential edge case in RMS storage on J2ME devices\nFixed issue 900 (repeatedly) OutOfMemoryError in XMLParsing\nFixed issue 896 : XMLParser endTag callback is not called for self-closing tags\nFixed issue 892 : text field with URL/email constraint still starts with upper case\nFixed issue 895 : OnOffSwitch alternate text does not apply on first display\nFixed Android image loading to use Bitmap.Config.ARGB_8888 which should give better UI fidelity and possibly better performance\nFixed issue 889 : OnOffSwitch state restoring\nAdded support for RFE 880: scroll event callback mechanism\nFixed an issue where drag events when entering the side menu set the dragged variable and then when we got back from it the button wouldn’t function on first touch.\nAdded feature for a single softbutton on J2ME devices.\nMade UIBuilder throw a nicer exception when failing to show a non-existing form\nFixed issue 884 in the designer : Derive All does not work\nFixed issue 883 in the designer : when you change the Pressed Icon and save, it doesn’t save the change\nImplemented RFE 722: Create side menu on both sides of title\nFixed the native Blackberry popup field to be white on black\nImplemented RFE 870: Ability to remove bounce in sidemenu\nImplemented RFE 874: Add pressed state icon for sidemenu\nAdded drop shadow effect to the sidemenu\nFixed issue 868: Hardware volume button needs repeated presses\nFixed issue 867: Sidemenu closing transition problems\nFixed issue 871: Title of Form is not centered\nFixed issue 865 : XMLParser CDATA hiccup\nImproved Twitter API to work with new OAuth API 1.1\nFixed vserv ads in a case of suspended apps\nEnhanced google map provider to allow configurable sizes\nFix for side menu bar in a case of a back command + a Title Command where effectively the side menu isn’t showing\nEnhanced the table UIID behaviors\nFixed array index out of bounds in the Base64 class for some edge cases\nFixed an IO stream leak in ImageIO\nAdded another option to the ImageIO that accepts file path\nFixed email sending on iOS to support multiple recipients\nFix for issue in in-app-purchase on iOS.\nAdded ability to clear the preferences API\nAdded ability to attach multiple message attachments\nFixed the processing package which had multiple localization encoding issues all over the place and added ability to pass readers rather than input streams\nFixed a potential race condition in the crash reporter\nAdded better current day handling to the calendar class\nImplemented RFE 855: Simulate internet connection cases. Simulator can now simulate slow connection and disconnected internet\nFixed issue 827 : disposing a web browser doesn’t \u0026ldquo;clear\u0026rdquo; it\nImproved the auto complete documentation and functionality to allow more dynamic data sets and asynchronous fetch\nFixed the processing package and read to String to work better with different encoding types\nMade the scaled method for EncodedImage more intelligent, it now tries to generate an EncodedImage image when possible\nAdded ability to create an encoded image from ARGB data, this is possible by using the ImageIO API\nFixed a minor bug in the calendar class where it didn’t default to the selected day view\nMade an improvement to combo box so it can be used with popup dialogs otherwise they were too close to the combo\nAdded support for media key events\nExposed the current selected functionality of list which is useful for some renderer use cases\nFixed border layout padding in absolute center mode required for iOS 7 title padding\nAdded performance optimization for fixed images in renderers\nFixed popup dialog borders which had some bugs with various size options\nFix for running in JavaSE port without a skin\nPotential fix for multiple threads on the Network class in iOS\nFix for exception in in-app-purchase code on iOS\nFixed WebBrowser to remove the progress in HTMLComponent when there is an exception in the network request\nFixed ActionBar to stay visible if the Form has commands\nFixed issue 814 : SimpleDateFormat returns incorrect time on iPhone/MIDP/RIM\nFixed Issue 787 : iOS networking error with cookies containing expires header\nFix for issue 841 : local use class points to absolute path making team development harder\nAdded some helper methods in Rectangle to ease working with it\nFixed a null pointer exception in Log sending\nAdded ability not to act on long press in list\nFixed Dialog’s onShowCompleted() which wasn’t invoked\nFixed arrows in popup dialogs for some cases\nFixed exceptions in RSS reader\nAdded ability to block redirect after OAuth\nFixed issue 835 : SideMenu opens when command list is empty\nImplemented RFE’s 837 \u0026amp; 838 to scroll down the performance log and add a way to clear it\nFixed several missing stream close() calls on Android \u0026amp; Resources.\nFixed race condition while editing text on Android\nFixed issue on Windows Phone with GUI builder applications which generally is the same issue we dealt with in iOS (xmlvm instanceof issue)\nFixed a race condition exception in Tree\nGenerified List, renderers etc.\nFixed a rarely occurring null pointer exception in Container\nFixed a spelling mistake in ConnectionRequest\nFixed and NPE and StackOverflow in the AndroidImplementation code\nUpdated zxing to be bundled on the server to resolve some J2ME/Blackberry issues\nAdded a new form of lock() that works asynchronously thus allowing us to load an image in the background while showing a dummy and still enjoy the convenience of lock()\nMade lock() more robust and added the ability to check if an image lock is applied.\nAdded lock() detection functionality to the performance monitor\nDisabled a block on EDT exception handling in the Android port which fixed error reporting for Android devices thru the cloud\nFix for issue 755 : Streaming MP3 not working in ios\nAdded ability to get the size of an element within storage\nAdded static getter instance to the L10NManager for convenience\nFixed font anti alias in derived ttf on the Android platform\nFixed the barcode scanner download app dialog to work properly\nFixed issue 819 : tel: links in webbrowser on android redirect to a protocol error page\nFixed J2ME email to respect more properties if the native platform supports them\nFixed the j2me VirtualKeyboard appearance\nAdded feature that allows J2ME developers to show the status bar\nImplemented RFE 807: add title UIID to the designer\nImprovement for resource handling allowing for better control over DPI/multi image loading. This is important for some gaming use cases\nFix for issue 802 : Geolocation API doesn’t work in Android Implementation of WebBrowser\nAdded getContactById with params which allows much faster retrieval of contact details\nSimulator now sends the destroy app event\nMade multiple improvements for iOS contact handling\nAdded ability for google maps provider to determine language\nFixed RTL transition direction regression\nMade push registration synchronous and more predictable\nFixed the implementation of CachedDataService\nFixed issue 795 : Windows Phone MapComponent does not work\nAdded the option of invoking createTrueTypeFont(name, null);\nFixed issue 785 : MultiButton background problem\nFix for issue 776 : iOS Multibutton problem. The multi button didn’t behave like regular buttons when dragging a pressed button\nFix for issue 777 : TextArea setGrowByContent problem\nFixed uncover transition drawing\nAdded ability to get multiple headers with the same name in the connection request\nWe now throw an exception for an improper use of rename\nImplemented RFE 769: Slow performance of opening the side menu on IOS due to usage of mutable image\nFix for issue 773 : merged error input stream into stream for errors on Java SE and Android\nAdded support to check whether on iOS a user has granted contact access permissions\nFix some push related issues on Android\nAdded an ability to differentiate the source of the back command on Android\nAdded an ability to hide the loading progress status for the web browser component\nFixed an issue where android sometimes sends double sizeChanged events\nFixed r and t handling in the JSONParser\nAdded support for the lastmodified property in the file system API\nDisabled shared cookies by default for iOS because it might break analytics\nFix for drawString on iOS for cases where the string is longer than the maximum texture size (can happen for a case of a ticker)\nImproved support for video RSS’s and fixed an exception when parsing a content type that has an additional type attribute (happens for RSS streams)\nImplemented back button support for RTL allowing it to switch directions\nAdded support for mirroring images to the reverse direction\nAdded \u0026ldquo;uncover\u0026rdquo; transition that is the opposite of the cover transition allowing a form to \u0026ldquo;slide out\u0026rdquo; after it covered the screen.\nFixed newline parsing in JSON\nAdded support for maintaining aspect ratio in the image download service\nFixed a race condition in the contacts model that kept showing loading for some entries\nFixed an issue with http redirect header when an infinite progress is showing\nFixed an encoding bug with Facebook login\nFixed issue 760: Media.getDuration() returning 0 instead of -1 when instance reads mp3 metadata\nFixed issue 761: Audio implementation for Media interface doesn’t keep the time when paused\nFixed issue 759 : Media.isPlaying() crashed on Android if media buffered the first bytes\nBorder layout now disables scrolling when applied to a component to prevent a common mistake of placing a border layout on a scrollable container\nReduced EDT thread priority on Android to prevent issues on the Blackberry Z10\nFixed issue with facebook URL’s which include the pipe (|) character in them which breaks on iOS (Apple is right here, this is against the RFC)\nAdded major performance improvement to char width on iOS which really improves the performance of TextArea on iOS (critical for complex UI’s).\nImproved the performance of DrawStringTextureCache on iOS by removing redundant tests and reordering the tests so the faster code happens first (hence if it fails the cost is really low).\nMade XML/JSON parsers use StringBuilder to improve their performance noticeably, this removes synchronization code which is especially slow on iOS\nMade multiple improvements to working with RSS’s in foreign languages and encodings\nRemoved synchronization from text area and made non-EDT code fail \u0026ldquo;gracefully\u0026rdquo;, this synchronization code is REALLY slow on iOS and since text area is used for multiline labels this was impacting performance\nChanged text area to optimize it for scrolling speed, it would constantly revalidate for no reason\nImplemented RFE 745: added more arguments to the postOnWall method of FaceBookAccess\nMade improvements to facebook allowing the listing of wall posts, fetching images synchronously as well as their URL’s\nFixed a null pointer exception in facebook pages.\nFixed a potential race condition for the in place text editing on Android\nFixed a layout bug that caused elements to not appear in edge cases where scrollable Y returns false (tensile disabled) due to padding being too big.\nAdded ability to get a picture synchronously from facebook\nFixed potential null pointer exception in action listeners\nFixed major bug in StringUtil’s tokenization feature\nFixed issue 733: NetworkManager.getInstance().killAndWait(request) freezes Device and simulator\nFixed issue 740 : NullPointerException in openImageGallery on simulator\nAdded ability to fetch facebook images for ContainerList\nAdded ability to login for some facebook functionality without OAuth\nFixed issue 737: Cannot display browser in container\nEnabled updating the UIManager externally for two look and feels in one UI\nAdded support for Android 4 and iOS 7 dialog buttons which use a thin line to separate plush components\nAdded a done listener to the TextField as a fix for issue 596 : TextField.addActionListener() should not be called on Back button\nFixed the contacts to return a sorted list\nFixed a couple of issues with the webview loading feature on Android\nFixed spinners and fixed Lists to move selection upon pointer press\nFixed simulator media time to milliseconds\nFixed issue 714 : iOS crash at startup\nImplemented RFE 726: IOS – contacts createContact and deleteContact\nFixed exception in designer when saving with override resources in place\nAdded ability to define smaller fonts in designer tool when choosing millimeters\nFixed video capture on J2ME devices\nFixed a performance issue that is visible in spinners with large data such as the DateTime spinner\nFixed for issue 730 : Text fields with password constraint are capitalized by default\nAdded ability for table layout to grow its last column without requiring constraints\nFixed a bug in multi button when placing the icon where the emblem is supposed to be\nAdded ability to define the prototype for generic spinner\nAdded some more refined events for drag over events\nAdded ability to get the component closest to a given point which is really useful for drag and drop\nAdded ability to get drag notification events while dragging over an area\nFixes for table layout to span better\nFixed default side menu transparency\nFixed a NullPointerException in grid layout and UIBuilder\nMade editing stop if a command was dispatched from the native menu on Android\nFixed issue 727 : Problem with LeadComponent when the lead component is a TextField\nAdded a Nokia Asha theme\nFixed action \u0026ldquo;withText\u0026rdquo; to show on the ActionBar if there is room on Android devices\nAdded ability to string util to tokenize by more than one character\nAdded ability to define multiple columns to a generic spinner\nFixed small exception in transitions\nBox layout now supports a version of X axis layout that makes more sense for most purposes which doesn’t grow beyond its preferred size vertically\nFix for sliders that couldn’t be dragged all the way to the edge\nFix for text area preferred size when hints are defined\nMinor improvement for dialog behavior\nAdded ability to read the content of an HTTP response that has an error code e.g. 500 or 400 etc. which could be useful for some cases\nFixed transition NPE in iOS for some cases.\nFixed iOS builds on Eclipse which caused some issues due to ADT being somewhat incompatible with javac\nAdded support for writing Codename One Maker plugins\nFix for a NullPointerException in a case of an empty Tree\nFixed the SideMenuBar to open on menu key and close on back key\nFixed getDatabasePath() to work correctly on all platforms and return the proper path for a databased that wasn’t created\nFixed multipart request which used the wrong content length\nFixed the cursor color on Android during native editing\nFixed potentially dropped push notifications on iOS\nMade generic spinner more robust before it is actually shown if its value was set via the model\nFixed lead component functionality on 3 button mode which is a fix for Issue 721 : MultiButton problem with setThirdSoftButton(true)\nFixed a bug in drag and drop that prevented the second drag of the same component from working\nFixed scanning to call scanCancel when the action is canceled by user\nAdded a Page object to the facebook api and simpler getter methods to the FaceBookAccess\nFixed issue 715 text field max size doesn’t work\nFix for app version to return a value in iOS\nMultiple fixes for test execution minor null pointer issue in a race condition\nNative utility class for Android allowing easier native code integration\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — December 23, 2013 at 11:14 am (permalink) Anonymous says:\nAmazing!\nCan’t wait, right on time!\nAnonymous — December 24, 2013 at 3:19 am (permalink) Anonymous says:\nthis is literally the best xmas gift im getting this year 😀 awesome work guys love that list of fixes!\nAnonymous — December 26, 2013 at 1:32 pm (permalink) Anonymous says:\nThanks so much guys… You rock\nAnonymous — December 31, 2013 at 9:45 am (permalink) Anonymous says:\nThis is awesome! I’m proud of you guys…\nAnonymous — February 11, 2014 at 10:18 am (permalink) Anonymous says:\nwhere is it?\nAnonymous — February 11, 2014 at 1:44 pm (permalink) Anonymous says:\nEverywhere. If you use the plugin and keep it up to date you are always on the latest version.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/release-notes-for-codename-one-201/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/release-notes-for-codename-one-201/codename-one-charts-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe will release the full Codename One 2.0 in a couple of days in the meantime here are the release notes covering the changes for this version.\u003c/p\u003e\n\u003cp\u003e**\u003cbr\u003e\nHighlights Of This Release\u003cbr\u003e\n**\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eSupport for IntelliJ IDEA\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eSupport for Google Play Ads on iOS/Android\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eSupport for 3rd party libraries using the cn1lib format\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eMajor improvements to the Windows Phone 8 port making it far more reliable\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFine tuned performance on iOS optimized garbage collector behavior\u003c/p\u003e","title":"Release Notes For Codename One 2.0"},{"content":"\nWhen Chen initially drew up the proof of concept for LWUIT he copied the concept of list renderers from Swing, this was one of the most hotly debated issues between us. Whether we should aim for familiarity for Swing users or simplify what has always been an API that novices wrestle with. We eventually went with the familiarity approach, a decision we both agree today was short sighted.\nUnfortunately changing the renderer API isn’t practical at this stage but we simplified a lot thanks to the GenericListCellRenderer which powers GUI builder list renderers. We simplified this further with the MultiList component which has a default renderer that’s pretty powerful to begin with.\nHowever, this simplicity has resulted in developers using lists without\nquite understanding why they behave in this way. In a normal container all components are kept in a Tree like hierarchy that we can render (essentially similar to DOM). A list however doesn’t contain any components within it so it can hold a million entries with the same overhead it would have when holding 100 entries.\nIt works like this:\nThe EDT (event dispatch thread) asks the List to paint itself.\nThe List asks the ListModel for the values of the currently visible entries.\nThe List asks the renderer for a component representing every value (the same instance is recycled and discarded).\nThis List paints the renderer as a rubber stamp for every single value.\nSo if the model has 1m entries we don’t need to create 1m components since we will reuse the renderer for every entry. We also don’t render elements that are invisible.\nThere are problems with this model though:\nSince the renderer is \u0026ldquo;stamped\u0026rdquo; (drawn then used for a different value) adding a listener to a component within the list won’t do what you expect.\nObviously individual elements within the list entry can’t get focus and can’t be edited\nWithin a List all entries have to be the exact same width/height. Otherwise its very expensive for us to calculate the list offset. ContainerList allows for variable height list but its performance/functionality is equivalent to Container so the benefits aren’t great.\nThe performance of the model \u0026amp; the renderer must be very high otherwise the whole list will be impacted.\nIts hard to create animations (since there is no state).\nYou might be asking yourself:\nWhy should I use a List? Why not just use a List or a Container with BoxLayout Y?\nThat’s actually our recommendation for most cases, List is often too much of a hassle for some use cases and we try to avoid it in many applications. It is now also possible to create\nlong scrolling containers\nrelatively easily although you might see performance degrading after a while.\nHowever List does have some serious advantages:\nScale – it scales well to huge lists and maintains speed. Flexibility – list can be flicked to horizontal mode, center selection behavior and other such capabilities. MVC – the list makes working with a data model really easy, if you are well versed with MVC this could be a very powerful So assuming you pick list lets see how you can make better use of it.\nH\now do you deal with events on a button click within a list renderer?\nSo assuming I have a list renderer that has a button named X on the the side, dealing with this differs between a GUI builder app and a handcoded app.\nFor a GUI builder app use the standard action listener for the list and within the action listener just write:\nNotice that the method above will not work for MultiList or a list containing MultiButton’s since those are composite components and can’t be separated to an individual component within.\nIf you are building a handcoded renderer this is a bit harder:\nThere are a few other features in the generic list cell renderer that aren’t well documented:\nThe UIID of the renderer is based on the UIID of the renderer component we also add a focus component to the list whose UIID is based on: selected.getUIID() + \u0026ldquo;Focus\u0026rdquo;. So if your selected renderer container has the UIID MyRenderer, then you focus component will have the UIID MyRendererFocus.\nItems are always overriden by their hashtable/map value even when they are missing. So if you place an icon in the renderer but don’t put the icon value in the hashtable model it will be removed.\nA solution is to just name the component with the word fixed in the end (case insensitive) as in iconFixed. This means that the value you give the icon in the renderer won’t change.\nYou can disable/enable entries within the list by using map.put(\nGenericListCellRenderer.ENABLED, Boolean.FALSE). Notice that once you do this you must do this for all the entries otherwise the renderers \u0026ldquo;rubber stamp\u0026rdquo; behavior will repeat the status of the last entry.\nYou can implement a \u0026ldquo;Select All\u0026rdquo; entry for a checkbox list by using map.put(GenericListCellRenderer.SELECT_ALL_FLAG, Boolean.TRUE). This is pretty useful if you have a checkbox list. You can place the entry number within the list by creating a component named $number. It will start with 1 as the offset and not with 0. If you want to provide a different value when an entry is selected (e.g. different image when clicked) you can use # in front of the name e.g. to allow Icon to have a different image when selected put a value into #Icon. Notice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — December 18, 2013 at 6:59 pm (permalink) Anonymous says:\nAny chance of some sample code snippets for the \u0026ldquo;few other features in the generic list cell renderer that aren’t well documented\u0026rdquo;\nAnonymous — December 19, 2013 at 3:19 am (permalink) Anonymous says:\nThey are all listed below with the relevant code where applicable. Which one of the bullets isn’t clear?\nAnonymous — December 19, 2013 at 3:22 am (permalink) Anonymous says:\nthe last two.\nAnonymous — December 19, 2013 at 3:27 am (permalink) Anonymous says:\nThere is no code involved for the first. In the GUI builder just place a component and name it $number. In the UI this will be rendered as 1, 2, 3 etc. based on the offset.\nThe second case allows you to provide different values for selected/unselected states. So if you have a model with values on the keys of the hashtable that you want to appear differently when pressed you can use that. A common use case is a different icon when the entry is selected (to match the colors) so normally I would place the icon as hash.put(\u0026ldquo;icon\u0026rdquo;, myUnselectedIcon); which will work both for selected/unselected states of the renderer. If I want a different icon design for the selected state I can use: hash.put(\u0026quot;#icon\u0026quot;, mySelectedIcon) as well. This will appear when the entry is selected.\nAnonymous — May 10, 2014 at 5:43 am (permalink) Anonymous says:\nHi,\nI have noticed that the \u0026ldquo;setFocus(Boolean focus)\u0026rdquo; is deprecated. I am currently using this to show the selected cell in a list (custom cell renderer based upon the default renderer).\nUnfortunately I can not find the alternative method when the setFocus should disappear.\nCan u provide some insight into this??\nAnonymous — May 10, 2014 at 12:00 pm (permalink) Anonymous says:\nGood question!\nWe deprecated this method since people kept using it instead of requestFocus() for standard components. However, the renderer is indeed a special case where it is needed.\nUnfortunately there is no way in Java to indicate \u0026ldquo;don’t use this method here but only use it there\u0026rdquo; so we use the relatively coarse tool of deprecation. In hindsight we should have done renderers completely differently if at all but that is already water under the bridge.\nAnonymous — August 14, 2014 at 2:21 am (permalink) Anonymous says:\nhow to add different online images on each items of list ?\nAnonymous — August 14, 2014 at 3:46 am (permalink) Anonymous says:\nSet a different URL for the URLImage attribute in the model.\nAnonymous — August 14, 2014 at 5:41 am (permalink) Anonymous says:\nI have used container which contains labels with name address and image. And want to use this container in list row and set image to image label and set address to address label.\nI am able to pass address to its label with hash_table in model as shown below.\nhash_table.put(\u0026ldquo;address\u0026rdquo;,\u0026ldquo;Nepal\u0026rdquo;);\nhash_table.put(\u0026ldquo;image\u0026rdquo;,\u0026ldquo;res_Image\u0026rdquo;);\nBut problem is unable to pass online image\ncan you give me simple codes for using online image in list ?\nAnd how to use URL Image in model (by code) ?\nKaneda — December 11, 2015 at 1:18 pm (permalink) Kaneda says:\nI want to create a list of event like attach picture, i read this page i know i must not use List to build that, but do you have an example, a tutorial to do ?\nThanks you\nShai Almog — December 12, 2015 at 5:30 am (permalink) Shai Almog says:\nI would just create a box layout container similar to the PropertyCross demo with containers within it.\nEvery container would have the image label on top in the center with some padding defined to take up the right size and background image behavior defined as \u0026ldquo;SCALE_TO_FIT\u0026rdquo; which will allow the image on top to look like that.\nI noticed that the Oct 23rd container has a carousel, if you need that to animate/move manually that is also easily doable thru replace animation.\nThe bottom container can be a standard BoxLayout.X_AXIS with two BoxLayout.Y_AXIS within it. The first box Y would container the date as month string and number and the second would contain the title/subtitle (possibly as span label).\nKaneda — December 14, 2015 at 11:10 am (permalink) Kaneda says:\nI try it 🙂\nKaneda — December 14, 2015 at 4:07 pm (permalink) Kaneda says:\nIt works well 🙂 , and i use :\nLabel myLabel = new Label(\u0026ldquo;My Title\u0026rdquo;);\nImageDownloadService.createImageToStorage(thumb_url, myLabel, guid, new Dimension(Display.getInstance().getDisplayWidth(), Display.getInstance().getDisplayHeight()));\nBut, the text of the label doesn’t display, how can I display the text hover the image. I think the image is not a background image.\nShai Almog — December 15, 2015 at 5:15 am (permalink) Shai Almog says:\nI think the text is implicitly set to blank on download.\nTry placing a label with a text in a Container next to a label with the downloadable image.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/deeper-in-the-renderer/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/deeper-in-the-renderer/deeper-in-the-renderer-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"List\" loading=\"lazy\" src=\"/blog/deeper-in-the-renderer/deeper-in-the-renderer-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhen Chen initially drew up the proof of concept for LWUIT he copied the concept of list renderers from Swing, this was one of the most hotly debated issues between us. Whether we should aim for familiarity for Swing users or simplify what has always been an API that novices wrestle with. We eventually went with the familiarity approach, a decision we both agree today was short sighted.\u003c/p\u003e","title":"Deeper In The Renderer"},{"content":"\nWe finally got around to updating Codename One LIVE! and in the process also added a How Do I? video\nguiding you thru the process of using it\n.\nIf you didn’t use Codename One LIVE! in the past its a really cool tool that allows you to instantly preview the design you build within the GUI builder right on the device. This works seamlessly for all devices although for iOS its difficult to get an app like that thru itunes and it requires a jailbroken device (unlike regular Codename One apps).\nThis update also disables the feature for non-pro users, it was always listed as a pro user feature in our\npricing page\nbut in the past this wasn’t enforced.\nOn a different subject, we made some major compatibility breaking changes to the Android port. Please test your application and see that it behaves correctly on start up, this is very important since we are about to release Codename one 2.0 and we want it to be very stable.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — December 16, 2013 at 7:37 pm (permalink) Anonymous says:\nWhen are you going to release ver 2.0?\nAny chance in the next 3 days 🙂\nThere is a Hackathon coming up here Thu/Fri and I would like to delve again into your framework but would prefer 2.0 if is already out.\nAnonymous — December 17, 2013 at 2:54 am (permalink) Anonymous says:\nIt is scheduled for a bit later but what you have right now is functionally equivalent to 2.0.\nWith a cloud service version releases have a very different meaning.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-live-updated-android-changes/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-live-updated-android-changes/codename-one-live-updated-android-changes-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/codename-one-live-updated-android-changes/codename-one-live-updated-android-changes-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe finally got around to updating Codename One LIVE! and in the process also added a How Do I? video\u003cbr\u003e\n\u003ca href=\"/how-do-i---preview-my-designs-on-the-device-using-codename-one-live.html\"\u003e\u003cbr\u003e\nguiding you thru the process of using it\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n.\u003c/p\u003e\n\u003cp\u003eIf you didn’t use Codename One LIVE! in the past its a really cool tool that allows you to instantly preview the design you build within the GUI builder right on the device. This works seamlessly for all devices although for iOS its difficult to get an app like that thru itunes and it requires a jailbroken device (unlike regular Codename One apps).\u003c/p\u003e","title":"Codename One LIVE Updated \u0026 Android Changes"},{"content":"\nWe have a couple of new\n\u0026ldquo;How Do I\u0026rdquo; videos\ncovering\nversioning\nand\ncrash protection\n. The code freeze has been in full effect this week and no new features are coming in (although some bugs were squashed), we plan to make a second release candidate which will include some critical bug fixes for 2.0.\nWe now have a new HTML based developer guide and as usual a downloadable PDF, the HTML guide was generated using\npdftohtml.net\nwhich did a pretty decent job except for our logo. We now removed the scribd document and are only maintaining the\nguide here\n.\nWe are also stopping the use of Google Docs for the developer guide. When we started that approach community members promised they\nwould support our effort and none have seriously come forward. Normally we wouldn’t mind maintaining the document in the cloud but the Google tool chain is problematic, they killed some basic features that are essential for something of this type (proper table of contents for one) and the final product (PDF) is of relatively low quality.\nSo with a bit of a heavy heart we moved to editing offline which has its advantages (e.g. grammar checker).\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-html-developer-guide-how-do-i/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-html-developer-guide-how-do-i/new-html-developer-guide-how-do-i-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/new-html-developer-guide-how-do-i/new-html-developer-guide-how-do-i-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe have a couple of new\u003cbr\u003e\n\u003ca href=\"/how-do-i.html\"\u003e\u003cbr\u003e\n\u0026ldquo;How Do I\u0026rdquo; videos\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\ncovering\u003cbr\u003e\n\u003ca href=\"/how-do-i---get-repeatable-builds-build-against-a-consistent-version-of-codename-one-use-the-versioning-feature.html\"\u003e\u003cbr\u003e\nversioning\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nand\u003cbr\u003e\n\u003ca href=\"/how-do-i---use-crash-protection-get-device-logs.html\"\u003e\u003cbr\u003e\ncrash protection\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n. The code freeze has been in full effect this week and no new features are coming in (although some bugs were squashed), we plan to make a second release candidate which will include some critical bug fixes for 2.0.\u003c/p\u003e\n\u003cp\u003eWe now have a new HTML based developer guide and as usual a downloadable PDF, the HTML guide was generated using\u003c/p\u003e","title":"New HTML Developer Guide \u0026 How Do I"},{"content":"\nIf you haven’t checked the\nHow Do I?\nsection recently check it out now. Its completely redone with a filter tool and every video now has the ability to accept comments right below it which you can use to give out tips to other community members about the usage of a specific feature. There is also a\nnew video covering the include sources feature\nand how to debug a Codename One iOS application on xcode with the native device/simulator.\nApparently the old i18n How Do I video\nthat I recorded ages ago slipped between the cracks and never made it to the how do I page either so\nits now there as well\n.\nWe updated the Codename One developer guide with more than 50 additional pages passing the 200 page mark\n, we will update that guide as part of the 2.0 release.\nThe IDEA plugin is also generally available now and includes its own\ngetting started video\nguide.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — December 9, 2013 at 11:42 am (permalink) Anonymous says:\nHi Shai\nCan you do some tutorials on animations?\nAnonymous — December 10, 2013 at 5:15 am (permalink) Anonymous says:\nIts in my todo list but its pretty low in the queue since we have quite a lot of other priorities. Animations should be very well documented in the developer guide though, what don’t you understand?\nAnonymous — December 12, 2013 at 4:37 am (permalink) Anonymous says:\nLooks like it has been broken for a couple of days. Cannot see the images for Themes and Templates in the \u0026ldquo;Codenameone\u0026rdquo; project. They displayed as radio buttons instead. But it did work for me the very fist day when you announced this plugin.\nTested on Windows 7, Mac OS X Mavericks with IntelliJ-13 versions Ultimate and CE.\nAnonymous — December 12, 2013 at 4:55 am (permalink) Anonymous says:\nThis was broken by IDEA 13 which seems to have a Windows specific bug there, we filed an issue on that. The images don’t show but the dialog should work as usual.\nI’m using IDEA on Mac (Lion) and I see the images with the latest plugin, which JDK are you using?\nAnonymous — December 12, 2013 at 6:22 am (permalink) Anonymous says:\njdk1.7.45\nAnonymous — December 12, 2013 at 5:38 pm (permalink) Anonymous says:\nThanks, there is an issue here http://youtrack.jetbrains.c… to address this.\nWe are also looking into the possibility of it being related to that specific JDK.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-how-do-i-idea-launch-expanded-developer-guide/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-how-do-i-idea-launch-expanded-developer-guide/new-how-do-i-idea-launch-expanded-developer-guide-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/new-how-do-i-idea-launch-expanded-developer-guide/new-how-do-i-idea-launch-expanded-developer-guide-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eIf you haven’t checked the\u003cbr\u003e\n\u003ca href=\"/how-do-i.html\"\u003e\u003cbr\u003e\nHow Do I?\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nsection recently check it out now. Its completely redone with a filter tool and every video now has the ability to accept comments right below it which you can use to give out tips to other community members about the usage of a specific feature. There is also a\u003cbr\u003e\n\u003ca href=\"/how-do-i---use-the-include-sources-feature-to-debug-the-native-code-on-iosandroid-etc.html\"\u003e\u003cbr\u003e\nnew video covering the include sources feature\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nand how to debug a Codename One iOS application on xcode with the native device/simulator.\u003c/p\u003e","title":"New How DO I, IDEA Launch \u0026 Expanded Developer Guide"},{"content":"\nWe are officially code frozen so only critical bug fixes should be resolved until the actual release. The very last feature to make it in is support for\nGoogle Play Ads\non iOS/Android. We currently only work with the Admob SDK as we move along we might add additional options.\nTo enable mobile ads just\ncreate an ad unit\nin Admob’s website, you should end up with the key similar to this:\nca-app-pub-8610616152754010/3413603324\nTo enable this for Android just define android.googleAdUnitId=ca-app-pub-8610616152754010/3413603324 in the build arguments and for iOS use the same as in ios.googleAdUnitId. The rest is seamless, the right ad will be created for you at the bottom of the screen and the form should automatically shrink to fit the ad. This shrinking is implemented differently between iOS and Android due to some constraints but the result should be similar and this should work reasonably well with device rotation as well.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\njuanpgarciac — May 22, 2015 at 9:17 pm (permalink) juanpgarciac says:\nThere is a way to check the functionablity in the debug process ? cause I’d follow the steps and it doesn’t show anything… thanks for sharing\nShai Almog — May 23, 2015 at 6:32 am (permalink) Shai Almog says:\nIts supposed to be seamless. On which device are you running into a problem?\nNotice this will only work on devices and not the simulator.\nApp Maker — January 10, 2016 at 9:30 pm (permalink) App Maker says:\nmonetize option is not available! can u please tell me why? n how can i get it?!\nShai Almog — January 11, 2016 at 3:22 am (permalink) Shai Almog says:\nWe removed it as it was hard to maintain across IDE’s. We provided several newer monetization options including several ad based cn1libs https://www.codenameone.com…\nAnd this option which doesn’t require the monetization section, just a build hint.\nPugazhendi E — March 26, 2016 at 7:36 am (permalink) Pugazhendi E says:\nadmob ads are not coming…I set the admob adunit ID in build arguments in netbeans ide…if i run a app, app ll work bt ads ll nt come…I followed the codename procedure… help me..\nShai Almog — March 27, 2016 at 4:25 am (permalink) Shai Almog says:\nIs this on the device? Which device type?\nJean Carlos Rojas Ramirez — June 8, 2016 at 11:35 pm (permalink) Jean Carlos Rojas Ramirez says:\nI am working on an app and I can add the hint for Android but I would like to know which I should use for windows phone. Thanks,\nShai Almog — June 9, 2016 at 5:05 am (permalink) Shai Almog says:\nWe don’t currently support Windows Phone with ads. AFAIK Googles AdMob isn’t available on Windows Phone.\nJean Carlos Rojas Ramirez — June 9, 2016 at 5:24 am (permalink) Jean Carlos Rojas Ramirez says:\nRight now there is a version for windows phone for AdMob. If we build a windows phone app we can add the AdMob AdUnit for those builds.\nShai Almog — June 10, 2016 at 3:46 am (permalink) Shai Almog says:\nOK. Either way Windows Phone is on the way out at Microsoft and I doubt Google would support that version. We are switching to the UWP port for universal Windows 10 support.\nPugazhendi E — July 25, 2016 at 1:27 pm (permalink) Pugazhendi E says:\nyes sir..I ve tested this app with lenevo smartphone….app works well but ads ll not come\nShai Almog — July 26, 2016 at 4:11 am (permalink) Shai Almog says:\nThat’s probably related to these changes https://github.com/codename…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/adding-google-play-ads/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/adding-google-play-ads/adding-google-play-ads-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Ad\" loading=\"lazy\" src=\"/blog/adding-google-play-ads/adding-google-play-ads-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are officially code frozen so only critical bug fixes should be resolved until the actual release. The very last feature to make it in is support for\u003cbr\u003e\n\u003ca href=\"https://developers.google.com/mobile-ads-sdk/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nGoogle Play Ads\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\non iOS/Android. We currently only work with the Admob SDK as we move along we might add additional options.\u003c/p\u003e\n\u003cp\u003eTo enable mobile ads just\u003cbr\u003e\n\u003ca href=\"https://apps.admob.com/?pli=1#monetize/adunit:create\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\ncreate an ad unit\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nin Admob’s website, you should end up with the key similar to this:\u003c/p\u003e","title":"Adding Google Play Ad's"},{"content":"\nWe recently introduced a new Facebook API to allow native integration since Facebook has stated their intention to no longer accept OAuth logins from applications. This is very much work in progress so some things will change as we move along especially related to elevated permissions for posting.\nIf you just want something in the form of a \u0026ldquo;share button\u0026rdquo; we suggest you refer to the builtin share button which uses native sharing on both iOS and Android.\nThe new Facebook API is very simple, in fact as of this writing it includes only 5 methods. Notice that the old Facebook API will still work as expected with the exception of the login aspect which will be handled by the new API.\nThere are really 3 significant method\ns in the API, login/logout and isLoggedIn(). You can also bind a listener to login event callbacks which is really pretty simple. The difficulty isn’t here though.\nBefore you get started you need to go to the page on Facebook for app creation:\nhttps://developers.facebook.com/apps\nHere you should create your app and make sure to enter the package name of the Codename One application both for the section marked as Bundle Id and Package Name\n(see the red highlighting in the attached image).\nOnce you do that you need to define the build argument facebook.appId to the app ID in the Facebook application (see the red marking at the top of the image).\nNow when you send a build and invoke FacebookConnect.login() this should work as expected on iOS but it will fail on Android. The reason is that Facebook\nrequires a hash from Android developers to identify your app. However, their instructions to generate said hash don’t work… The only way we could find for generating the hash properly is on an Android device.\nIf you have DDMS you can connect the device to your machine and see the printouts including the hashcode (notice the hashcode will change whenever you send a debug build so make sure to only use Android release builds). You can also get the value of the hashcode from Display.getInstance().getProperty(\u0026quot;facebook_hash\u0026quot;, null);\nThis will return the hash only\non Android ofcourse.\nYou can take this hash and paste it into the section marked Key Hashes in the native android app section. Notice you can have multiple hashes if you have more than one certificates or applications.\nOnce login is successful the existing facebook API’s from the Facebook package should work pretty much as you would expect.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — December 2, 2013 at 7:55 am (permalink) Anonymous says:\nWhat about platforms which donot have native facebook integration like J2ME ? When is facebook planning to stop OAUTH login from applications ? This is really a shocking piece of news!!\nAnonymous — December 2, 2013 at 2:40 pm (permalink) Anonymous says:\nAt the moment they still work but it was bound to happen with Facebook. If you are relying on Facebook as your only means of authentication I would look for alternative solutions.\nAnonymous — December 4, 2013 at 6:02 am (permalink) Anonymous says:\nGreat and very important addition to CodeNameOne!\nThis improves the user experience a great deal – a very important issue if you have a socially boosted app.\nA few things I broke my head about:\n– The new API is in a different package: com.codename1.social\n– Once you use the new API, you should use getToken() in order to get the token to use the old API for sharing and stuff.\n– The hash key is changed by Facebook. If you get an error that the hash key doesn’t match, try this:\nhttp://stackoverflow.com/qu…\nFor me it worked – I changed the hash key from s_XroFyP24CL… to s/XroFyP24CL… and log in was successful.\nGood luck!\nAnonymous — December 5, 2013 at 11:13 am (permalink) Anonymous says:\nThanks, the token should automatically be set to FaceBookAccess so after login it should seamlessly be there and you should be able to use the class.\nAnonymous — January 20, 2014 at 5:37 am (permalink) Anonymous says:\nHello,\nI’m getting an error on importing import com.codename1.social.FacebookConnect (the whole social package is missing) .\nAm I missing the latest version of CodeNameOneBuildClient.jar?\nHow do I get the required jars?\n(using IntelliJ IDEA)\nAnonymous — January 20, 2014 at 3:25 pm (permalink) Anonymous says:\nIt seems there is a bug in the IDEA plugin where Update Client Libs is incorrectly mapped to refresh libs. As a workaround just send a build (to any platform) without this import, it will update the libraries for you after which point you should be able to import this package.\nAnonymous — February 3, 2015 at 10:55 am (permalink) Anonymous says:\nHi,\nI have an application that uses Facebook as a login option but it always asks for the credentials, i.e. instead of clicking on the ‘login with facebook’ and entering my app, it requires the user to enter his Facebook login info even if he is already signed in to Facebook (Web or/and Facebook App)\nAnonymous — February 3, 2015 at 10:56 am (permalink) Anonymous says:\n🙂 forgot to ask the question..\nWhat can I do so it will go in straight without the additional required login?\nAnonymous — February 3, 2015 at 1:42 pm (permalink) Anonymous says:\nMake sure that on your device settings facebook login is enabled otherwise the native facebook login falls back to web login.\nMr Emma — September 26, 2015 at 5:08 pm (permalink) Mr Emma says:\ni cant generate the key hash.\nhow do i go about doing that. i keep getting the error\n‘openssl’ is not recognized as an internal or external command,\noperable program or batch file.\nwhen i use this below –\nkeytool -exportcert -alias (your_keystore_alias) -keystore (path_to_your_keystore) | openssl sha1 -binary | openssl base64\nShai Almog — September 27, 2015 at 3:51 am (permalink) Shai Almog says:\nIn which os?\nSee the newer guide: http://www.codenameone.com/…\nMr Emma — September 27, 2015 at 7:24 am (permalink) Mr Emma says:\nAm on the windows 10 OS and I want to generate the key hash for my Android app. I have gone through the new guide my only issue is generating the key hash\nShai Almog — September 28, 2015 at 4:08 am (permalink) Shai Almog says:\nSecond entry when googling: \u0026ldquo;facebook openssl windows\u0026rdquo;\nhttp://stackoverflow.com/qu…\nMr Emma — September 28, 2015 at 11:28 pm (permalink) Mr Emma says:\nthanx it helped alot\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/using-the-new-facebook-api/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/using-the-new-facebook-api/using-the-new-facebook-api-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/using-the-new-facebook-api-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/using-the-new-facebook-api/using-the-new-facebook-api-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eWe recently introduced a new Facebook API to allow native integration since Facebook has stated their intention to no longer accept OAuth logins from applications. This is very much work in progress so some things will change as we move along especially related to elevated permissions for posting.\u003c/p\u003e\n\u003cp\u003eIf you just want something in the form of a \u0026ldquo;share button\u0026rdquo; we suggest you refer to the builtin share button which uses native sharing on both iOS and Android.\u003c/p\u003e","title":"Using The New Facebook API"},{"content":"\nI’ve just written a\nblog post for O’Reilly media\nand we’d very much appreciate it if you check it out, share it (ideally via the social media buttons on it) and spread it to your friends/colleagues. Please take the 5 minutes to do this as this would be very helpful for us. Thank you.\nThe ShareButton component in Codename One\nis one the most important pieces in making your app a viral success. In Android it fires the native share intent where you can select to distribute the app’s message via a very wide selection of options. In other platforms you get a pretty narrow, fixed selection of options that is very cross platform since it uses Codename One’s builtin capabilities.\nWe added support for native iOS sharing in the latest version, this effectively means that when running on iOS you would get a native share dialog that would integrate with apps installed in the system in a very similar way to the Android intent. We hope this will improve viral distribution in iOS.\nWe’ve also made a lot of changes to the iOS rendering and performance related hotspots. Some of these changes caused a bit of regression but overall we feel the performance is improving further. We are still in the midst of these changes and we hope to increase performance noticeably.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/oreilly-blog-sharing-performance/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/oreilly-blog-sharing-performance/oreilly-blog-sharing-performance-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/oreilly-blog-sharing-performance/oreilly-blog-sharing-performance-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eI’ve just written a\u003cbr\u003e\n\u003ca href=\"http://programming.oreilly.com/2013/11/wora-can-be-better-than-native.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nblog post for O’Reilly media\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nand we’d very much appreciate it if you check it out, share it (ideally via the social media buttons on it) and spread it to your friends/colleagues. Please take the 5 minutes to do this as this would be very helpful for us. Thank you.\u003c/p\u003e\n\u003cp\u003eThe ShareButton component in Codename One\u003c/p\u003e\n\u003cp\u003eis one the most important pieces in making your app a viral success. In Android it fires the native share intent where you can select to distribute the app’s message via a very wide selection of options. In other platforms you get a pretty narrow, fixed selection of options that is very cross platform since it uses Codename One’s builtin capabilities.\u003c/p\u003e","title":"O'Reilly Blog, Sharing \u0026 Performance"},{"content":"\nThis came out 5 months ago but the guy from\nPubNub\ndidn’t update us on the status so we just didn’t notice this until now. That’s probably a good sign of us being too busy. There is now official PubNub integration for Codename One, which means you can get push like fast 2 way communications between devices without writing too much code.\nHow does it work?\nPubNub has CDN like operations around the world, this means they can keep a high performance channel to your devices and send peer to peer or server/peer messages REALLY fast.\nHow is this different from just using Push notification?\nThese aren’t separate ideas, push is generally good if the application isn’t running. Its also good for very small messages and provides no delivery guarantees. So using push for a chat application might not be the right thing but using PubNub for that makes perfect sense.\nThere is now a\nCodename One SDK from PubNub\nand\na tutorial\nrelated to the SDK that should help you get started right away and even a\nquick start tutorial\n. Normally we write a tutorial for things such as these but the guys at PubNub did such a good job at making this really simple, there is really no need to do so. Check out their work and let us know what you think.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — April 22, 2014 at 9:28 am (permalink) Anonymous says:\nJust spent a day looking at this finally, its kind of tough to get started for the first couple of hours but after that its plain sailing, made a whatsapp clone in 7 hrs that runs on all mobiles, thanks to codenameone 😀 Im amazed pubnub have put together such a decent and problem free API and extremely bloody thankful.\nAnonymous — September 6, 2014 at 8:07 pm (permalink) Anonymous says:\nPlease someone help me out,I don’t know where to start in pubnub\nAnonymous — September 7, 2014 at 3:00 am (permalink) Anonymous says:\nDid you go thru the tutorial on their website?\nAnonymous — September 7, 2014 at 8:31 am (permalink) Anonymous says:\nI did but not understanding anything there.\nAnonymous — September 7, 2014 at 1:31 pm (permalink) Anonymous says:\nThis http://www.pubnub.com/docs/… seems really simple. Do you have any Java programming experience?\nAnonymous — September 18, 2014 at 5:09 am (permalink) Anonymous says:\nHelo Gareth,am jude.Am trying to create a mobile chat application for my project.I want to create something similar to whatsap and skype for android,but am not sure how to go about this.Please can you give me tips on how to do this project.Thanks in advance\nLinsong Wang — December 19, 2016 at 8:08 pm (permalink) Linsong Wang says:\nPubnub is deprecating 3.x version, and 4.x is the recommended now. Any plan to upgrade corresponding cn1lib?\nShai Almog — December 20, 2016 at 5:28 am (permalink) Shai Almog says:\nWe didn’t build that cn1lib. It was built by pubnub. I think there are no technical issues in porting it to the new API as Codename One supports sockets/websockets and allows any form of communication including native interfaces.\nHowever, I don’t think they see enough paying user engagement from Codename One so if you rely on their service you need to write to them and ask for this.\nOn our side we’d like to offer a better webservice oriented tool that will work with websockets for efficient universal communications. There is no current ETA for this though as this is still on the drawing board.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/fast-push-communication-using-pubnub/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/fast-push-communication-using-pubnub/fast-push-communication-using-pubnub-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/fast-push-communication-using-pubnub/fast-push-communication-using-pubnub-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis came out 5 months ago but the guy from\u003cbr\u003e\n\u003ca href=\"http://www.pubnub.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nPubNub\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\ndidn’t update us on the status so we just didn’t notice this until now. That’s probably a good sign of us being too busy. There is now official PubNub integration for Codename One, which means you can get push like fast 2 way communications between devices without writing too much code.\u003c/p\u003e\n\u003cp\u003eHow does it work?\u003c/p\u003e","title":"Fast Push Communication Using PubNub"},{"content":"\nFacebook has changed the rules yet again, this time related to logging in to Facebook from 3rd party applications. Up until now we used the web based OAuth approach for logging into Facebook since that allowed us to keep the same implementation across Android, iOS, Blackberry etc. without changing anything. However, the new Facebook 2 factor authentication is a very complex process and Facebook really went overboard with a very elaborate mobile API.\nSo we had no choice but to integrate the native Facebook SDK when necessary (you will not \u0026ldquo;pay for it\u0026rdquo; if you don’t use it). This is currently in beta so the API is very likely to change which is why we are not docume\nnting it yet by writing a proper tutorial. This isn’t essential yet since the current Facebook API is still working and well documented. If you would like to take a look its within the social package, we would appreciate feedback, ideas and use cases.\nOn a different issue the just released version of the plugin addresses some issues with text input in the simulator (and Java SE port)\nrelated to\nthis issue\n. The crux of the issue lies in the usage of the highly broken AWT text field. Up until now we wanted to transition to the Swing text field but had serious flickering issues. I was finally able to resolve these issues in the latest version which will hopefully improve the simulators behavior in this regard.\nWe also made some changes to reduce the flickering of the native Webkit when interacting with JavaFX, this is a huge step towards producing a robust desktop app port in the future.\nWe had a lot of complaints and issues with the Google groups support forums, this is a huge problem but in the past most other solutions were either high maintenance or SPAM magnets. While we will probably keep and support the Google groups until Google actually kills the product (which might be next week with those guys) we are considering a Facebook group as a secondary support option.\nHowever, we will only do that if there is community interest in this so if you would like a Facebook group and promise to join then just vote below.\nLoading…\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — November 20, 2013 at 12:57 pm (permalink) Anonymous says:\nCan you elaborate on this line: (you will not \u0026ldquo;pay for it\u0026rdquo; if you don’t use it)\nAny idea on how much this will cost to use?\nAnonymous — November 20, 2013 at 12:59 pm (permalink) Anonymous says:\nIn size not financially 😉\nIt won’t increase your app size by bundling in the Facebook SDK if you don’t use it. I should be clearer on those things.\nAnonymous — November 20, 2013 at 11:51 pm (permalink) Anonymous says:\nUm, believe it or not – not every developer has a facebook account but almost all of them are in linkedin – linkedin groups may make more sense.\nAnonymous — November 21, 2013 at 2:46 am (permalink) Anonymous says:\nWe already have a LinkedIn group that isn’t very active. Its sort of a control to see whether a potential Facebook group will see more activity.\nAnonymous — November 21, 2013 at 5:27 am (permalink) Anonymous says:\nI have all Facebook domains mapped to 0.0.0.0 in my hosts file because I especially DON’T want those buggers tracking me all over the Net.\nGoogle Groups seem to work OK.\nYou could always use Usenet 🙂\nAnonymous — November 23, 2013 at 5:17 am (permalink) Anonymous says:\nI know spam is an issue when creating a forum. It would be nice to have things more organized with sub sections, especially if it was accessible using the Tapatalk app. Google Groups mobile website is an absolute pain and I enjoy reading while away from my computer.\nIt may be plausible to have a password generated from within codenameone settings in the IDE or something along those lines to access the forum, that way people who are actually using codenameone would get the password as that is the majority of users in the forum anyway, that may eliminate a lot of spamming. That way you could have a real forum site like XDA with multiple sections and would be much easier to find already asked and answered questions.\nAnonymous — November 23, 2013 at 5:29 am (permalink) Anonymous says:\nActually Google groups introduced the ability to use categories which is pretty similar to proper sections. That would be very useful.\nHowever, they neglected a proper migration path so if we add categories all our existing posts mostly disappear and you won’t see them under any category.\nAn admin can start going over messages and manually categorizing them one by one, however that’s obviously tedious and painful.\nAnonymous — November 27, 2013 at 8:55 am (permalink) Anonymous says:\nGo for project management system like Redmine. Then everything will be in one place: issue tracking, wiki, forum, etc. Easy to make relations, and build valuable documentation extended by tips \u0026amp; trick shared by community on forum. Keeping those things separated and using multiple providers does not help…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/facebook-better-input-improving-community-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/facebook-better-input-improving-community-support/facebook-better-input-improving-community-support-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Facebook Login\" loading=\"lazy\" src=\"/blog/facebook-better-input-improving-community-support/facebook-better-input-improving-community-support-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eFacebook has changed the rules yet again, this time related to logging in to Facebook from 3rd party applications. Up until now we used the web based OAuth approach for logging into Facebook since that allowed us to keep the same implementation across Android, iOS, Blackberry etc. without changing anything. However, the new Facebook 2 factor authentication is a very complex process and Facebook really went overboard with a very elaborate mobile API.\u003c/p\u003e","title":"Facebook, Better Input \u0026 Improving Community Support"},{"content":"\nWe are now finalizing the features for Codename One 2.0. Yes we are skipping the 1.2 revision and going up to the 2nd generation which we feel is warranted given the amount of features added since the May release of 1.1.\nWe will make the release in December which we will probably spend in code freeze so you won’t see new features from us during that month that are not bug fixes or completely separate features (e.g. IDEA plugin).\nMost of the features for 2.0 match the current version here is what we still don’t have and hope to include in 2.0:\nInteliJ IDEA plugin\nNative Facebook SDK support (ideally with native sharing on iOS too)\nFixes for Windows Phone issues\nThere are a many issues and features which we would like to push into the release so we will try to get as many of them out there. Time permitting we would like to add a new solution for ad’s that would hopefully solve those pains once and for all.\nOnce this is out we can probably start debating on the wishlist for 2.1, feel free to he\nchime in in the discussion here.\nIf you have an issue that you feel is particularly important and should be addressed for 2.0 please comment on that within the issue so we won’t miss it.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — November 19, 2013 at 11:53 am (permalink) Anonymous says:\nIntelliJ IDEA plugin with 2.0 – nice!\nAlbeit the answers in forum concerning web deployment but if there is even a slight chance exporting to some kind of JS or even GWT so we can target easily Web – this will be ideal.\nAnonymous — November 19, 2013 at 3:54 pm (permalink) Anonymous says:\nWe’d like to do something like this but there are some serious technical hurdles. I’m optimistic about http://wiki.apidesign.org/w… but they seem adamant about not supporting threads. Maybe this an be hacked in some way without violating their VM. Maybe something like this can be hacked with GWT, either way would work for us but we need threads.\nI occasionally have some thoughts about doing a threadless version of Codename One but that is a bit difficult to achieve with things such as Dialog.show etc. being so ingrained.\nAnonymous — November 19, 2013 at 8:03 pm (permalink) Anonymous says:\nWhat would really make my life easier is the ability to put a res file containing Forms into a CN1 Library Project, then run those Forms from multiple Apps. I am developing a suite of Apps each of which have 6 or 7 common forms and its a pain to redevelop them for each App. And it will be a pain to maintain them.\nAnonymous — November 20, 2013 at 8:19 am (permalink) Anonymous says:\nThanks for the feedback Steve. We are looking at some approaches to this especially with a pending rewrite of the designer tool. I’m not sure if that will make it to .2.1 though. Currently it seems that it will have to wait for the release after that.\nAnonymous — November 20, 2013 at 4:19 pm (permalink) Anonymous says:\nOn the Windows 8 front the biggest issue for me is the Database class. Last I checked is was not there, will it make it into 2.0?\nAnonymous — November 21, 2013 at 2:49 am (permalink) Anonymous says:\nThis won’t make it for 2.0.\nThe main issue with Windows Phone’s SQL support is that SQlite is only supported from the C layer and this is pretty difficult to circumvent.\nAnonymous — November 21, 2013 at 4:19 am (permalink) Anonymous says:\nI think the biggest issue for me is the ability to include files (res files, images, etc) from multiple folders.\nI too am developing a suite of apps and have about 600 files (mostly images, sound files, etc) included in my source folder.\nFor every app I create I have to manually sync these folders.\nAnother big issue – Graphics.\nI need to be able to use different width lines, anti aliasing, brushes, etc., in order to give an enriched experience. Really miss that!\nAnonymous — November 21, 2013 at 5:39 am (permalink) Anonymous says:\nYou should use multiple resource files for this. Using files in the src dir is a recipe for portability nightmares e.g. recently a developer in our forum had an issue because she named a PNG x.1.png and it worked on Android/Simulator while failing on iOS. You get all sorts of weird stuff when working with files and file hierarchies.\nYou can use the new team mode of the designer tool so you can incorporate resources from your designer more quickly.\nYou can also sync folders as part of the build script (ant is pretty powerful).\nGraphics is a HUGE issue for us, frankly I’m shocked we reached 2.0 without a complete rewrite of that. We are working hard to bring a new graphics engine to iOS (which will allow us to bring it to Android \u0026amp; the simulator too). The problem is that the native engine isn’t appropriate for what we need (its scene-graph) and most OpenGL based engines are geared for the needs of games. We have a project underway but there is no way it will be ready in time for the code freeze so it will have to wait for post 2.0. I’m hoping it will be ready for January but we are still in the exploratory stages (although outlook seems good).\nAnonymous — November 21, 2013 at 7:28 am (permalink) Anonymous says:\nWould be nice to add push capability to windows ports.\nAnonymous — November 23, 2013 at 1:40 pm (permalink) Anonymous says:\nIs there a date for database support in Windows Phone 8?\nDoes it have to be SQLite? I think your Database class is generic enough to support another implementation, if there were one.\nNow that we are out on Android and iOS all we hear is when will Windows phone support be available. Nobody is even talking about Blackberry anymore. I need to come up with a plan.\nAnonymous — November 23, 2013 at 2:36 pm (permalink) Anonymous says:\nMartin, if I recall correctly you have a pro account right? Contact me thru email about this, we can discuss options/schedules etc.\nAnonymous — November 24, 2013 at 11:27 am (permalink) Anonymous says:\nDo the 2.0 include the bluetooth support? I will really happy if 2.0 have bluetooth support, course this is the reason my project still stay in J2ME..\nThank you.\nAnonymous — November 24, 2013 at 4:48 pm (permalink) Anonymous says:\nAre you using the push capabilities in other platforms?\nAnonymous — November 24, 2013 at 4:53 pm (permalink) Anonymous says:\nThat’s currently not slated. We might do something small but right now most of our pro or enterprise subscribers didn’t ask for this and its a good thing because its REALLY hard (I think one might have mentioned it at some point but not sure about that either).\nBluetooth is implemented completely differently between OS’s, PhoneGap which has been around quite a while still doesn’t have a bluetooth plugin after all these years. So its pretty hard to abstract it in a portable way.\nAnonymous — November 25, 2013 at 5:36 am (permalink) Anonymous says:\nOn Android and iOs but not on CodenameOne. Thats why I want to port my products to use CodenameOne next year to support more platforms (Blackberry 10 previous and Windows 7.5 – 8) but sad to see its not supported on Windows. In fact, Windows port is quite immature at this stage compared to your other ports if I am not mistaken. As for BB10, I reckon its your Android port that will be running on there? Will there be a BB10 native port in the near future?\nAnonymous — November 25, 2013 at 9:57 am (permalink) Anonymous says:\nNone of our pro/enterprise customers asked for Windows Phone push so it isn’t there and so far isn’t planned. This can obviously change based on request from enterprise customers or several pro customers.\nWe won’t support the BB10 directly but our Android port works well on it (we have a couple of pro users for whom this is important so we made sure of that). The process is a bit awkward but it works.\nAnonymous — December 10, 2013 at 10:10 pm (permalink) Anonymous says:\nDo you have plans for including Socket support?\nAnonymous — December 10, 2013 at 10:11 pm (permalink) Anonymous says:\nDo you have plans for including Socket support on this release?\nAnonymous — December 11, 2013 at 9:34 am (permalink) Anonymous says:\nWe do have it in our wishlist for 2.1. It won’t be java.net.Socket but we do want to offer simple TCP client/server sockets.\nAnonymous — January 6, 2014 at 7:00 am (permalink) Anonymous says:\nHi,\nMy entreprise is planning to build mobile app using bluetooth. It’ll be great if you can include a support for that. Let us know when it’ll be done, so we’ll get an entreprise subscription.\nRegards\nAnonymous — January 6, 2014 at 8:00 am (permalink) Anonymous says:\nSorry for some reason I didn’t answer this. Odd.\nSockets are landing soon.\nAnonymous — January 6, 2014 at 8:04 am (permalink) Anonymous says:\nHi Kenny,\nit works the other way around. Get an enterprise subscription then we will implement the features you need.\nWe get a lot of similar requests like that for various features and its impossible for us to separate the serious customers especially thru the internet.\nRight now we are busy implementing the priorities of our existing enterprise subscribers none of which asked for bluetooth so this won’t get done for 2.1 either unless you actually purchase and make an official request.\nAnonymous — February 20, 2014 at 11:21 am (permalink) Anonymous says:\nHi Shai,\nI’m not very sure so can you confirm that the release 2.0 of Codenameone is available ?\nAnonymous — February 20, 2014 at 2:40 pm (permalink) Anonymous says:\nFor ages. Plugin version != general Codename One version.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/preparing-for-20/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/preparing-for-20/preparing-for-20-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/preparing-for-20-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/preparing-for-20/preparing-for-20-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eWe are now finalizing the features for Codename One 2.0. Yes we are skipping the 1.2 revision and going up to the 2nd generation which we feel is warranted given the amount of features added since the May release of 1.1.\u003c/p\u003e\n\u003cp\u003eWe will make the release in December which we will probably spend in code freeze so you won’t see new features from us during that month that are not bug fixes or completely separate features (e.g. IDEA plugin).\u003c/p\u003e","title":"Preparing For 2.0"},{"content":"\nThe guys at LTS just\npublished a post I wrote in their blog\n, if you are reading this thinking \u0026ldquo;I’d like to read another 5,000 words from that guy\u0026rdquo; then head to\ntheir blog\n.\nSpeaking of promoting other people I hope you filled the\ndeveloper economics survey\n, its really helpful for us and time is running out (they are closing the survey soon). They added additional language options which you can use that might make the process faster.\n**\nBack to our regular scheduled programming\n**\nWe have a few bits of news that might interest you. We just changed the filesystem behavior in the simulator\nto be more consistent with what you would see on the device. This might break some behaviors you might ave come to rely on but that is a good thing since its REALLY problematic to rely on filesystem layout. This started out as fixing\nissue 948\nbut the fix is pretty complex since the right thing to do is to normallize files for the simulator.\nThere are a lot of new features coming up next week but further down the road we just started work on an InteliJ IDEA plugin\n. If you are a developer who prefers working with IDEA we hope to release a new plugin within the next couple of months!\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — November 15, 2013 at 4:15 pm (permalink) Anonymous says:\nPlease keep us informed how things are going on IntelliJ plugin and post a link to a stable beta whenever time comes.\nAnonymous — November 15, 2013 at 6:38 pm (permalink) Anonymous says:\nThere will be posts on the blog etc. when everything is available, I hope to provide better details of our release plan next week.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/lts-blog-post-and-updates/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/lts-blog-post-and-updates/lts-blog-post-and-updates-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"IntelliJ IDEA\" loading=\"lazy\" src=\"/blog/lts-blog-post-and-updates/lts-blog-post-and-updates-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe guys at LTS just\u003cbr\u003e\n\u003ca href=\"http://www.luxoft.com/blog/salmog/cross-platform-mobile-development-recap/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\npublished a post I wrote in their blog\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, if you are reading this thinking \u0026ldquo;I’d like to read another 5,000 words from that guy\u0026rdquo; then head to\u003cbr\u003e\n\u003ca href=\"http://www.luxoft.com/blog/salmog/cross-platform-mobile-development-recap/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\ntheir blog\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n.\u003c/p\u003e\n\u003cp\u003eSpeaking of promoting other people I hope you filled the\u003cbr\u003e\n\u003ca href=\"http://www.visionmobile.com/DE1Q14CodenameOne\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\ndeveloper economics survey\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, its really helpful for us and time is running out (they are closing the survey soon). They added additional language options which you can use that might make the process faster.\u003c/p\u003e","title":"LTS Blog Post And Updates"},{"content":"\nShai Ifrach\nspent the weekend fixing one of the harder Windows Phone issues we had, sometimes on some Windows Phone devices the UI would start with a black screen but never when connected to the debugger! Ugh.\nTurns out this is a race condition related to using the wrong lifecycle callback (which is used by all of MS’s demos)!\nKudos to him because I spent just about ages trying to tackle that issue unsuccessfully, this should now allow us to move forward with some of the additional issues on Windows Phone and hopefully bring the port up to the level of the other ports we have or at least a little bit closer.\nOne of the changes in iOS 7 was the new 3d spinner component (not sure how that works with the flat design metaphor) this is a component that we were just completely unable to replicate no matter how hard we tried. So we are introducing a new native spinner API currently specifically for Date \u0026amp; Time picking but as we move along we might add additional options. This API will effectively popup a dialog and prompt the user to pick a date or time and use our Spinners where a native option doesn’t exist. Currently the native aspect is implemented for iOS/Android only.\nWhen we started working on this we wanted to use the amazing new Android widgets for date/time, but apparently these are specific to the Android calendar and not really available in the OS… So Google itself isn’t using native widgets for their own application and choosing to go with app specific widgets…. lovely.\nIf you aren’t an Android 4 calendar user check out the screenshot to the left, its a pretty sweet time picker UI that looks better in real life where it animates very nicely.\nSo we provide two API layers the first is a simple API with a fallback that just allows you to place a time/date widget. If a native picker is available it will be used otherwise our picker is used. This is the\nPicker API and although it looks likes a text field its really just a button that will popup a picker when pressed. Its really simple to use just add it to your UI either via the designer or in code and set/get the date/time. The only potential source of confusion is that time is defined as minutes since midnight and if you invoke setDate() this won’t work.\nOn the other hand if you use the Date And Time spinner then the Date object you use will have the time embedded in it and you should not use the time related functions.\nThe second API is the native calls we use for the pickers itself, they are in Display where we provide the methods:\nisNativePickerTypeSupported(int type) \u0026amp; showNativePicker(int type, Component source, Object currentValue, Object data).\nThere are currently 3 picker type constants in Display:\nPICKER_TYPE_DATE_AND_TIME, PICKER_TYPE_TIME, PICKER_TYPE_DATE.\nSo to show a native picker you must first verify that the picker type is supported then just show it, a source component would be important for tablets where we use a popup dialog instead of a regular dialog.\nThe value type depends on the picker type, for date/date and time a java.util.Date object is expected. For time and Integer value with minutes since midnight is expected.\nThe API is blocking like typical dialog API’s and will return with the value when finished.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/spinning-natively-and-windows-bug/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/spinning-natively-and-windows-bug/spinning-natively-and-windows-bug-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/spinning-natively-and-windows-bug/spinning-natively-and-windows-bug-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://twitter.com/future_soft\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nShai Ifrach\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nspent the weekend fixing one of the harder Windows Phone issues we had, sometimes on some Windows Phone devices the UI would start with a black screen but never when connected to the debugger! Ugh.\u003c/p\u003e\n\u003cp\u003eTurns out this is a race condition related to using the wrong lifecycle callback (which is used by all of MS’s demos)!\u003c/p\u003e\n\u003cp\u003eKudos to him because I spent just about ages trying to tackle that issue unsuccessfully, this should now allow us to move forward with some of the additional issues on Windows Phone and hopefully bring the port up to the level of the other ports we have or at least a little bit closer.\u003c/p\u003e","title":"Spinning Natively And Windows Bug"},{"content":"\nThe video of the LTS talk is now live, unfortunately during the talk we had audio issues due to the large number of viewers and had to turn off the camera. The picture that remains for the rest of the slides is a freeze frame of me frowning over not turning the camera sooner.\nWe are gearing up for some major updates and new features in the coming weeks and are now in the process of narrowing down the requirements for Codename One 2.0 (yes major version number). This will hopefully land before the years end but as you know these things are pretty hard to tune precisely.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/video-of-lts-talk/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/video-of-lts-talk/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe video of the LTS talk is now live, unfortunately during the talk we had audio issues due to the large number of viewers and had to turn off the camera. The picture that remains for the rest of the slides is a freeze frame of me frowning over not turning the camera sooner.\u003c/p\u003e\n\u003cp\u003eWe are gearing up for some major updates and new features in the coming weeks and are now in the process of narrowing down the requirements for Codename One 2.0 (yes major version number). This will hopefully land before the years end but as you know these things are pretty hard to tune precisely.\u003c/p\u003e","title":"Video Of LTS Talk"},{"content":"\nWe have constant Google alerts setup on various Codename One related keywords and the other day we got a lovely surprise in the form of this great presentation from Mateja Opacic who to my knowledge never contacted us or discussed this with us. Apparently he made this presentation at the\nCoding Serbia Conference\n, which is really cool!\nHe has a great presentation \u0026amp; demo.\nWe added a few interesting features and fixes this past week, we now support adding array arguments for connection requests e.g. it would now be possible to do something like myConnectionReuest.addArgument(\u0026ldquo;key\u0026rdquo;, new String[] {\u0026ldquo;val1\u0026rdquo;, \u0026ldquo;val2\u0026rdquo;}); this will essentially add two key entries e.g. key=val1 and key=val2.\nThe LocationManager’s getCurrentLocation\nSync method now allows an optional timeout argument which can be pretty useful.\nEric made an interesting contribution to the processing package expression language syntax\nproviding a contains operator\n.\nWe also added the AutoCompleteText and SpanLabel to the GUI builder and made some major fixes to the way the GUI builder handles composite components which should remove duplicate entries from such components property sheets.\nI’m about to commit a slightly compatibility wrecking change to Storage. We had an issue with files in storage that contained slashes and colons. This sometimes works but it can fail for many devices (justifiably). To solve this we will now sanitize storage names automatically and replace common illegal characters with underscore.\nThis should work rather seamlessly for most use cases, however if you have existing files that use illegal characters or you rely on behavior related to these problematic characters you might run into problems e.g. saving \u0026ldquo;x?\u0026rdquo; then listing the storage will return \u0026ldquo;x_\u0026rdquo; instead.\nTo disable this feature we are adding to Storage a flag called is/\nsetNormalizeNames(), you can use this flag to indicate whether entries should be normalized. The default is true for normalization.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — November 6, 2013 at 5:27 pm (permalink) Anonymous says:\nThanks for the updates.\nAnonymous — November 12, 2013 at 1:09 pm (permalink) Anonymous says:\nnice! when will the update be released?\nAnonymous — November 12, 2013 at 3:47 pm (permalink) Anonymous says:\nThis week, hopefully tomorrow.\nAnonymous — November 20, 2013 at 5:51 am (permalink) Anonymous says:\ni’ve got the update but the support for adding arrays as arguments in the connection request is not there or i’m missing something?\nAnonymous — November 20, 2013 at 1:00 pm (permalink) Anonymous says:\nI’m guessing you updated the plugin and not the library. Go to project properties and select update client libraries.\nAnonymous — November 21, 2013 at 5:12 am (permalink) Anonymous says:\nthanks! thought it was automatic when updating 😉\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/surprises-and-changes/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/surprises-and-changes/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe have constant Google alerts setup on various Codename One related keywords and the other day we got a lovely surprise in the form of this great presentation from Mateja Opacic who to my knowledge never contacted us or discussed this with us. Apparently he made this presentation at the\u003cbr\u003e\n\u003ca href=\"http://codingserbia.com/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nCoding Serbia Conference\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, which is really cool!\u003c/p\u003e\n\u003cp\u003eHe has a great presentation \u0026amp; demo.\u003c/p\u003e\n\u003cp\u003eWe added a few interesting features and fixes this past week, we now support adding array arguments for connection requests e.g. it would now be possible to do something like myConnectionReuest.addArgument(\u0026ldquo;key\u0026rdquo;, new String[] {\u0026ldquo;val1\u0026rdquo;, \u0026ldquo;val2\u0026rdquo;}); this will essentially add two key entries e.g. key=val1 and key=val2.\u003c/p\u003e","title":"Surprises And Changes"},{"content":"\nIts been a busy week with the\nLTS\nsession, we barely had time to do much. However, we did do quite a lot of work during this week including some improvements for l10n and new server deployments.\nThose of you who followed the l10n video in the\nHow Do I?\nsection or our\nUdemy course\nshould be familiar with the really cool seamless localization support available in Codename One. However, to translate the application we usually need to send the files to a professional translator…\nThis can be a problem, while most translators are familiar with Java properties files we did run into some bugs (on their side) with the process. To solve some of these we added the ability to export localization as CSV and just recently we also added the ability to export/import it as Android String bundles. This should make it pretty easy to import existing Android localizations but the main use case is to work with translators with tools that are already optimized for Android.\nThe CSV is also very convenient since it can be opened by any spreadsheet and edited freely. We went to great pains to make it excel compatible although there are some bug in Excel for Mac OS X.\nImporting for both formats and exporting Android XML’s will be available in the next plugin update.\nOur server architecture is pretty elaborate with many different tiers and nodes. We have been using Amazon for some of our build servers and our prices there have skyrocketed recently due to the uptake of Codename One in the community and apparently also due to our lack of familiarity with AWS.\nIt turns out Amazon has a\nreserved instance\nfeature which is pretty similar to standard hosting, rather than just migrate to using that we also decided to migrate to Linux which is both easier to maintain and stabler. So we created a new AWS image based on Linux and were able to setup part of the build cloud functionality on that which is really cool. This effectively means that our build servers for Android, J2ME \u0026amp; Blackberry will be stabler and more scalable as we move forward. They will also be slightly more cost effective which is a good thing for us. Unfortunately there is no similar solution for Mac or Windows Phone (Windows 8).\nI’m personally anxiously waiting for the new\nMac Pro\n,\nI think we will be looking at build times of under a minute when running on that beast. This is something we would like to offer our pro/enterprise users when we can finally get such a machine going.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-servers-and-internationalization/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-servers-and-internationalization/new-servers-and-internationalization-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/new-servers-and-internationalization-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/new-servers-and-internationalization/new-servers-and-internationalization-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eIts been a busy week with the\u003cbr\u003e\n\u003ca href=\"http://www.luxoft.com/lts-luxoft-technology-series/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nLTS\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nsession, we barely had time to do much. However, we did do quite a lot of work during this week including some improvements for l10n and new server deployments.\u003c/p\u003e\n\u003cp\u003eThose of you who followed the l10n video in the\u003cbr\u003e\n\u003ca href=\"/how-do-i.html\"\u003e\u003cbr\u003e\nHow Do I?\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nsection or our\u003cbr\u003e\n\u003ca href=\"http://udemy.com/codenameone101/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nUdemy course\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eshould be familiar with the really cool seamless localization support available in Codename One. However, to translate the application we usually need to send the files to a professional translator…\u003c/p\u003e","title":"New Servers And Internationalization"},{"content":"\nIts been a long time coming, the main delay in getting iOS 7 support into your hands has been with the need to upgrade all the servers. Apple seems to require OS upgrades as well when it updates xcode so we had to go one by one and update everything.\nThis is now all in place and you can start building apps that take advantage of iOS 7 functionality and are built using xcode 5.\nWhen you send an app to the build server without doing anything it will still be built with the existing iOS 6\ntheme and xcode 4.5 and will act like it has for the past year or so. However, we now provide you with the ability to use xcode 5 for building and indicate a theme mode.\nThere are 4 theme modes:\nDefault – this just means you don’t define a theme mode. Currently this is equivalent to legacy. In the future we will switch this to be equivalent to auto\nlegacy – this will behave like iOS 6 regardless of the device you are running on.\nmodern – this will behave like iOS 7 regardless of the device you are running on.\nauto – this will behave like iOS 6 on older devices and iOS 7 on newer devices\nYou can define these by setting the build argument ios.themeMode to legacy, modern or auto.\nOn NetBeans you can use the UI we just added in the latest plugin (seen in the screenshot here).\nTo use xcode 5 which you would probably want if you target the\nlatest iOS 7 devices just define ios.xcode_version=5.0\nThose of you who submitted apps to the store know that you need screenshots in the various resolutions to\nmatch, that is why we added iOS 7 versions of all the iOS device skins to the skin section. Just select More in the simulator skin menu to download additional iOS 7 skins.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — October 28, 2013 at 1:51 pm (permalink) Anonymous says:\nIs a build done with the \u0026ldquo;auto\u0026rdquo; flag bigger in size? I presume it must pack both versions’ resources and then decide which one to use at runtime?\nAnonymous — October 29, 2013 at 2:36 am (permalink) Anonymous says:\nNot noticeably. The resource file isn’t very big ~400k for each theme 800k for both.\nThis might sound like much for mobile developers but considering that a hello world currently starts at 4mb due to the overhead of the JVM this is small potatoes.\nKeep in mind that iOS apps are bundled as app bundle directories so there is no overhead in runtime for any amount of files included in the bundle (although there is overhead for compiled code size but that’s a different story).\nAnonymous — January 23, 2014 at 11:16 am (permalink) Anonymous says:\nAs per discussion earlier on on forum I was trying to \u0026ldquo;define OS by setting the build argument\u0026rdquo;.\nBut since I am using Eclipse – i cannot find WHERE I can do that manually as you mentioned before (to set ios.xcode_version=5.0) . Is it a part of build.xml (looked there could not find), or theme Constants (could not find it ether).\nPlease let me know\nAnonymous — January 23, 2014 at 4:30 pm (permalink) Anonymous says:\nIn this case you will want ios.xcode_version=4.5 since now 5.0 is the default. Right click the project-\u0026gt;Properties-\u0026gt;Codename One\nSelect \u0026ldquo;Build Hints\u0026rdquo; tab at the top and press \u0026ldquo;Add\u0026rdquo;.\nTheme constants are in the designer in the theme under the constants tab.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/seven/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/seven/seven-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/seven-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/seven/seven-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eIts been a long time coming, the main delay in getting iOS 7 support into your hands has been with the need to upgrade all the servers. Apple seems to require OS upgrades as well when it updates xcode so we had to go one by one and update everything.\u003c/p\u003e\n\u003cp\u003eThis is now all in place and you can start building apps that take advantage of iOS 7 functionality and are built using xcode 5.\u003c/p\u003e","title":"Seven"},{"content":"\nWe would very much appreciate it if you take the new Developer Economics\n10-minute survey\nyou can also win prizes as a result! VisionMobile has launched a new Developer Economics survey. If you’re an app developer, take the survey to have your say and win prizes, including an iPhone, a Galaxy S4, two Nokia Lumia 920 handsets and some cool gadgets.\nAlso – respondents who complete the survey and opt-in to VisionMobile’s panel can access the Developer Benchmarks, a visualised scorecard of how they compare to other developers in their country or region, across platforms used, revenue models, app categories and more.\nThe survey results will be available for free download on January 2014.\nThis is really important to us, it allows us to improve our positioning and awareness within the industry. Regardless of your subscription level it would be very helpful for us if you take those 10 minutes and click\nthe link\n.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — October 25, 2013 at 12:27 am (permalink) Anonymous says:\nI wanted to do the right thing by CN1 and take the survey, but I got half way through and the questions were more useless and frankly impossible to answer with any degree of precision.\nHow the hell would anyone expect to make any meaningful inferences from the imprecise garbage they collect is anyone guess.\nAnonymous — October 25, 2013 at 8:10 am (permalink) Anonymous says:\nYou can leave things blank. These are surveys for managers to gauge how developers feel so they are structured in a way that isn’t necessarily intuitive to us.\nThis is important to us because when you as a developer want to start working with a platform such as Codename One you need to get permission from your manager, he will look at the results of surveys like this one…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/please-help-us-by-taking-this-survey/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/please-help-us-by-taking-this-survey/please-help-us-by-taking-this-survey-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://www.visionmobile.com/DE1Q14CodenameOne\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Developer Economics\" loading=\"lazy\" src=\"/blog/please-help-us-by-taking-this-survey/please-help-us-by-taking-this-survey-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eWe would very much appreciate it if you take the new Developer Economics\u003cbr\u003e\n\u003ca href=\"http://www.visionmobile.com/DE1Q14CodenameOne\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\n10-minute survey\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nyou can also win prizes as a result! VisionMobile has launched a new Developer Economics survey. If you’re an app developer, take the survey to have your say and win prizes, including an iPhone, a Galaxy S4, two Nokia Lumia 920 handsets and some cool gadgets.\u003c/p\u003e\n\u003cp\u003eAlso – respondents who complete the survey and opt-in to VisionMobile’s panel can access the Developer Benchmarks, a visualised scorecard of how they compare to other developers in their country or region, across platforms used, revenue models, app categories and more.\u003c/p\u003e","title":"Please Help Us By Taking This Survey"},{"content":"\nI hope you registered for the upcoming\nLTS lecture\n, last week there were close to 1000 developers registered!\nSometimes the most important features we can add are really simple things that we just procrastinated on forever. Case in point: multi-line labels.\nFor years we have been explaining to people over and over again: \u0026ldquo;Just use TextArea and invoke setUIID(\u0026ldquo;Label\u0026rdquo;)\u0026rdquo;.\nThis has three major\nissues:\nPeople keep asking (always a bad sign, means the API isn’t intuitive enough).\nThey also need to do other stuff – setFocusable(false), setEditable(false) so this is starting to get pretty verbose.\nThis isn’t localizable!\nWhen we\nlocalize\nan app the labels/buttons etc. (buttons derive from labels) are localized seamlessly. However, TextArea’s are not localized since we assume they will contain data which you normally don’t localize (user data is already in the right language). The problem is that in this case we do want to localize the label since this is really \u0026ldquo;a label\u0026rdquo;.\nSo I broke down, climbed down from the tree and added a SpanLabel class which is\nsolving RFE 919\n.\nSimple yet very helpful.\nA similar situation exists in the location API code, we get a question once a week: why doesn’t getCurrentLocation() work?\nSo we start explaining that you need to bind a listener etc. bla, bla, bla…. Not very helpful…\nIf there is boilerplate you need to write maybe we should write it for you. This is what we did in the past when people had issues with the complex async version of capture. We added a synchronous version that was much simpler and the questions practically disappeared from the mailing list! So we are doing the same for the location API, we now have a new method:\ngetCurrentLocationSync();\nwhich will return your location or null if there is an error.\nSimple!\nYou should show a progress dialog while it is running since it might take some time.\nIts not an ideal way to track location, this is only for relatively simple use cases.\nOn a different note I was reviewing code for one of our enterprise customers and on a call with said customer he pointed out that they re-did some of our GoogleAnalitics work. Turns out that when we weren’t looking Google published a REST API for the tool that allows tracking applications more effectively!\nBack when they launched their new analytics for applications support, they didn’t have a REST API so we had to use the WEB API which sucks!\nThe customer in question agreed to contribute the code which I assimilated into our Analytics API. Its off by default but if you will invoke AnaliticsService.\nsetAppsMode(true) app tracking should start using the new Google API which might have quite a few advantages for you. We didn’t get a chance to test it much but it should be pretty cool.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — October 21, 2013 at 6:37 pm (permalink) Anonymous says:\nThanks. Mulitiline-Labels were really missing.\nCan we use SpanLabel to build Mulitline-Buttons somehow, for example by manipulating uuid?\nI have build Mullitiline-Buttons in LWUIT with Containers and leadComponent, the solution is quite long and event handling also got also more complex.\nAnonymous — October 22, 2013 at 3:08 am (permalink) Anonymous says:\nWe’ve had SpanButton for quite a while now, I think I even blogged about it.\nAnonymous — October 31, 2013 at 5:21 pm (permalink) Anonymous says:\nHow about updating the JavaDocs?\ncodenameone_docs_demos_2013… is the latest available on http://www.codenameone.com/…\nAnonymous — November 1, 2013 at 4:29 am (permalink) Anonymous says:\nThanks for the suggestion. We are slow with updating that file (only with major version updates) mostly because of the hassle required to do so.\nThe javadocs are all up here https://codenameone.googlec… with a pretty recent version.\nWe are looking into automating the creation of this file but in the past we ran into some issues there.\nAnonymous — September 25, 2020 at 11:38 am (permalink) Anonymous says:\n[deleted]\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/simple-stuff/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/simple-stuff/simple-stuff-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Simple\" loading=\"lazy\" src=\"/blog/simple-stuff/simple-stuff-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI hope you registered for the upcoming\u003cbr\u003e\n\u003ca href=\"http://www.luxoft.com/lts-luxoft-technology-series/java-mobile-applications/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nLTS lecture\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, last week there were close to 1000 developers registered!\u003c/p\u003e\n\u003cp\u003eSometimes the most important features we can add are really simple things that we just procrastinated on forever. Case in point: multi-line labels.\u003c/p\u003e\n\u003cp\u003eFor years we have been explaining to people over and over again: \u0026ldquo;Just use TextArea and invoke setUIID(\u0026ldquo;Label\u0026rdquo;)\u0026rdquo;.\u003c/p\u003e\n\u003cp\u003eThis has three major\u003c/p\u003e\n\u003cp\u003eissues:\u003c/p\u003e","title":"Simple Stuff"},{"content":"\nOne of the really useful features in Codename One that many developers are just unaware of is the client properties trick. Every component in Codename One has a Map (Hashtable) associated with it containing arbitrary objects you can store in association with that component.\nTo use this feature you can just invoke putClientProperty(propertyName, value); then getClientProperty(propertyName) to extract the property.\nWhen faced with this feature developers are often a bit stumped, why would I need this?\nWhy not just store a variable?\nThis is an immensely useful\nfeature that allows you to decouple your UI code from the business logic and store state information directly in the component. This is especially useful in a GUI builder application where you might not want to litter the state machine with variables. We use these methods extensively in Codename One itself e.g. the GridBagLayout stores constraint information right into the component state using the putClientProperty method. Tree indicates whether a node is expanded or folded right in the component itself, it also allows the tree to have a reverse lookup reference from the Component to the state node (so it \u0026ldquo;knows\u0026rdquo; the object that formed a specific component).\nOn a different subject altogether Fabrício Carvalho Cabeça of\nPumpop\ncontributed a patch that allows ImageViewer to be non-cyclic. Hopefully people will find this useful. I’m not sure if it made it to the update we released last night though.\nWe also added some basic support for showing the native OS hints when entering edit mode in iOS and Android. This won’t necessarily give you the best UX since the native hints might differ from ours which is why this feature is off by default. You can enable this by defining\nnativeHintBool=true in your theme constants.\nI’ve also made some changes to the notification API in Android allowing you to test whether notifications are supported (they only work for Android right now) and also allowing the passage of additional arguments, dismissal etc. You now have an isNotificationSupported() method in Display which will be true only on Android (at least for now). You should also use the new version of\nnotifyStatusBar\nwhich differs both in its return value (which can be used to\ndismiss the notification\n) and also allows you to pass more arguments.\nCurrently supported arguments include:\npersist=Boolean.TRUE – this will cause the notification to persist and won’t allow users to close it. You should then explicitly call dismiss to remove it.\nid=Integer(…) – a number indicating the unique id for a notification, if you want to show multiple notifications from the same app you will need to give them each a unique id.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/property-of-the-client/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/property-of-the-client/property-of-the-client-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Notifications\" loading=\"lazy\" src=\"/blog/property-of-the-client/property-of-the-client-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the really useful features in Codename One that many developers are just unaware of is the client properties trick. Every component in Codename One has a Map (Hashtable) associated with it containing arbitrary objects you can store in association with that component.\u003c/p\u003e\n\u003cp\u003eTo use this feature you can just invoke putClientProperty(propertyName, value); then getClientProperty(propertyName) to extract the property.\u003c/p\u003e\n\u003cp\u003eWhen faced with this feature developers are often a bit stumped, why would I need this?\u003c/p\u003e","title":"Property Of The Client"},{"content":"\nThis has been a busy week, I am gearing up for my\nLTS lecture\non the 30th. Its free for everyone and I hope you all tune in to watch it!\nThe subject matter should be interesting to all Java developers and its essentially how you build a cross platform solution implementation, you don’t need any knowledge of Codename One since I won’t be discussing it much. Its about device issues and how these work with the JVM. So feel free to distribute this to your friends who aren’t necessarily Codename one developers.\nBut this in’t why I’ve been busy, we had a major server failure this week which is rare since our architecture is highly redundant and should be resistant to failure. To understand what failed one needs to understand how Codename One servers actually work. When you send a build to the cloud you aren’t sending it to a build server. You are sending it to our cloud server which is based on Google’s App engine for Java.\nApp engine is highly redundant and pretty stable so its very unlikely that it will fail, a failure in app engine would mean that our web console (where you see the build results appear) would stop working and you would be unable to send builds. Even if a build server fails only a specific build will fail, since we have redundancy all servers would need to fail for service to stop entirely.\nThe first failure included an in-ability to send a build while the console itself and everything else worked as expected, to make matters worse on the server side we got no error whatsoever and no indication that something was going wrong. Investigating something like this is naturally remarkably difficult!\nApp engine uses a tool called the blob store to perform uploads, so when data is submitted to app engine it really reaches a Google\ninternal service after which it arrives at our Servlet where it is added to the database and delegated to a build server. Unfortunately, we weren’t getting to the servlet! The failure occured within the Google upload process which is effectively seamless to us.\nSo we started looking at whether upload or the blob store service were down, they were not. We were able to upload (e.g. device logs etc.).\nSince the blob store uses a Google internal URL the upload process consists of two distinct stages, the user needs to \u0026ldquo;request\u0026rdquo; an upload URL from google and then upload to that URL (after which he is redirected to the servlet). That was the culprit, when we requested a URL we passed the user credentials. The idea was to save blob store space/upload time in the case of a user who ran out of credits.\nGoogle extracted the arguments that we passed to the servlet (notice that these arguments are never explicitly passed to the blob store which doesn’t get the request context)!\nThese arguments were then appended to the URL returned (which is naturally a post URL) creating an illegal URL that can’t be fixed.\nWe made several attempts at patching this such as editing the URL dynamically (using substring, url encoding etc.) all of which produced cases such as uploads getting \u0026ldquo;swallowed\u0026rdquo; with no redirect to the actual build servlet. Eventually, we just redirected without the arguments and this worked around the issue.\nThis was the second time this year where we had a failure of this type (the first was due to Google App Engine being down for a couple of hours). This still puts us at a 99.999\n% uptime on an annual basis which is pretty good.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/you-are-cordially-invited/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"https://img.youtube.com/vi/L4Rxlc_oUaQ/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis has been a busy week, I am gearing up for my\u003cbr\u003e\n\u003ca href=\"http://www.luxoft.com/lts-luxoft-technology-series/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nLTS lecture\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\non the 30th. Its free for everyone and I hope you all tune in to watch it!\u003c/p\u003e\n\u003cp\u003eThe subject matter should be interesting to all Java developers and its essentially how you build a cross platform solution implementation, you don’t need any knowledge of Codename One since I won’t be discussing it much. Its about device issues and how these work with the JVM. So feel free to distribute this to your friends who aren’t necessarily Codename one developers.\u003c/p\u003e","title":"You are cordially invited"},{"content":"\nThis is one of the biggest FAQ’s we get on the mailing list: I followed the iOS\nsigning tutorial\nor\nvideo tutorial\nand still didn’t succeed in signing (notice that you need to actually read the links above, the certificate you get from the apple website is not enough!).\nHow do I debug something like this?\nNotice that some of these signing failures will sometimes manifest themselves during build and sometimes will manifest during the install of the application.\nWell, there are several steps we always need to follow when troubleshooting such issues:\nYou\n_\n**\nmust\n**\n_\nuse a Mac to generate the P12 certificates. There is no way around it! (tutorials that show otherwise will not work).\nWe would like to automate it in the future (in a similar way to our Android signing tool), but for now you can use\nMacInCloud\nwhich has a free version.\nNotice that this is something you need to do once a year (generate P12), you will also need a Mac to upload your final app to the store though.\nWhen exporting the P12 certificate make sure that you selected BOTH the public and the private keys as illustrated in the image to the right.\nMake sure the package matches between the main preferences screen in the IDE and the iOS settings screen (see pictures below).\nMake sure the prefix for the app id in the iOS section of the preferences matches the one you have from Apple\n(see pictures below)\n.\nMake sure your provisioning profile’s app id matches your package name or is a * provisioning profile. Both are sampled in the pictures below, notice that you would need an actual package name for push/in-app-purchase support as well as for app store distribution.\nMake sure the certificate and provisioning profile are from the same source (if you work with multiple accounts), notice that provisioning profiles and certificates expire so you will need to regenerate provisioning when your certificate expires or is revoked.\nIf you declare push in the provisioning profile then ios.includePush (in the build arguments) MUST be set to true, otherwise it MUST be set to false\n(see pictures below)\n.\nDid this help you? Let us know in the comments.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — October 8, 2013 at 12:37 pm (permalink) Anonymous says:\nMacCloud has a free option, I did not see that.\nThis blog was a life-saver. I just went through this, and had a myriad of problems, compounded by my own stupidity, and my ignorance of ios App development and Mac in general.\nThe saving of the two keys tripped me up. Seemed subtle in the video, and easily missed.\nRegarding the AppId, Might I suggest, since you are taking both properties,\ncodename1.packageName, and codename1.ios.appid,\nyou have Ant or some other preprocessor check to see that the ending of the appid conforms to the packageName before the build is sent to the server. I had this wrong yesterday and was able to initiate a server side build (followed) certificate errors.\nAnonymous — October 8, 2013 at 5:38 pm (permalink) Anonymous says:\nThanks!\nThere are indeed a lot of things we need to do and can do on the client side before actually sending the build to the server. I think there is even an issue for the various types of static analysis we can perform locally, unfortunately we never got around to doing that.\nAnonymous — March 6, 2014 at 3:25 pm (permalink) Anonymous says:\nThank you, this is an extremely useful post. One thing to add (in case someone stumbles upon the same problem):\nWhen exporting private key / certificate pair from Mac’s keychain you will be prompted for a password to protect your private key. You MUST enter a password that is at least 4 characters long – there will be no warnings / errors if you don’t, but build signing will quietly fail.\nAnonymous — July 14, 2014 at 9:47 pm (permalink) Anonymous says:\n(3) Make sure the package matches between the main preferences screen in the IDE and the iOS settings screen (see pictures below).\nIm my mac, dont existe option to \u0026ldquo;export 2 files\u0026rdquo;\nAnonymous — July 14, 2014 at 9:48 pm (permalink) Anonymous says:\nAnonymous — August 9, 2014 at 3:56 pm (permalink) Anonymous says:\nI return to this problem once a year. How do I extract proper mobile provision files from development environment? I spend around hour each time, macos is very alien environment.\nAnonymous — August 10, 2014 at 3:19 am (permalink) Anonymous says:\nThere is a tutorial covering this in the How Do I section.\nAnonymous — September 22, 2014 at 3:50 am (permalink) Anonymous says:\nAn important omission is that sometimes install fails on the device the first time around thru the link/QR code but succeeds via itunes. This is due to provisioning profile configuration on the device and seems to be an Apple bug.\nAfter installing once with itunes future installations should work thru the QR code.\nAnonymous — February 13, 2015 at 5:57 am (permalink) Anonymous says:\nI just wanted to share with you that (despite what it says in Point 1.) I have successfully created a development P12 certificate on my Windows machine using XCA. I followed the steps described here:\nhttp://smarttechie.org/2013…\nAnonymous — February 13, 2015 at 1:30 pm (permalink) Anonymous says:\nDid you get a build passed?\nWith the old VM? New VM?\nAnonymous — February 13, 2015 at 4:16 pm (permalink) Anonymous says:\nI don’t know which VM. I just sent the build to the build servers along with the p12 certificate and it installed all right on my iPhone.\nAnonymous — February 14, 2015 at 3:33 am (permalink) Anonymous says:\nThe default is the new VM with xcode 6. If you set ios.newVM=false I’m guessing your build will fail. Can you verify this?\nIf so it might mean the new VM has another nice advantage over the old VM.\nAnonymous — February 17, 2015 at 10:48 am (permalink) Anonymous says:\nIt also works with set ios.newVM=false but the new VM seems to work better.\nTom\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/ios-code-signing-fail-checklist/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/ios-code-signing-fail-checklist/ios-code-signing-fail-checklist-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/ios-code-signing-fail-checklist-large-8.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Export P12\" loading=\"lazy\" src=\"/blog/ios-code-signing-fail-checklist/ios-code-signing-fail-checklist-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eThis is one of the biggest FAQ’s we get on the mailing list: I followed the iOS\u003cbr\u003e\n\u003ca href=\"/signing.html\"\u003e\u003cbr\u003e\nsigning tutorial\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nor\u003cbr\u003e\n\u003ca href=\"/how-do-i.html\"\u003e\u003cbr\u003e\nvideo tutorial\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nand still didn’t succeed in signing (notice that you need to actually read the links above, the certificate you get from the apple website is not enough!).\u003c/p\u003e\n\u003cp\u003eHow do I debug something like this?\u003c/p\u003e\n\u003cp\u003eNotice that some of these signing failures will sometimes manifest themselves during build and sometimes will manifest during the install of the application.\u003c/p\u003e","title":"iOS Code Signing Fail Checklist"},{"content":"\nThere is absolutely no way I can recall everything that went on in JavaOne but I will try to do my best. I arrived sick and on pretty strong medication for my sinuses so my recollection might be a bit hazy, I did meet great people and had loads of fun.\nBefore JavaOne started I had a meeting with\nArno\nof the\nXMLVM\nproject, I was hoping to get more facetime with him and to maybe actually code something together but he was on his way for the rest of the week due to other duties. We discussed some of the issues with XMLVM and the potential of forking vs. merging our changes with the main XMLVM code base. The way things look it seems that we will have to take over XMLVM or at least the iOS/Windows Phone ports.\nLater in the conference I had a meeting with\nNiklas Therning\nof\nRoboVM\n, who like Arno is a great and interesting fellow.\nI’ve been giving a lot of thoughts to XMLVM and RoboVM over the past few months, both have done a lot of work and each has its advantages/disadvantages. I’ve asked\nSteve Hannah\nto run his benchmarks for me on devices with some settings I asked for. Initially it seemed that RoboVM smoked XMLVM but when running on the devices the differences became far less pronounced.\nBecause of the way Codename One is built, we could potentially just flip a switch to our servers and builds will be performed with RoboVM instead of XMLVM (this would require a lot of work on our side but would be seamless to you). The main holdback for me is my conservative nature. XMLVM is a very safe choice:\nWe can debug it (although its inconvenient).\nWe can maintain it, I’m sure we can maintain RoboVM too if Niklas decides to quit but we already know we can maintain XMLVM.\nIf Apple changes something (e.g. new architecture like the 64 bit they just announced) we can support it instantly since we just use xcode.\nSo currently we will stick with XMLVM but there are no final decisions here since we could potentially offer both backends as we move forward.\nJavaOne started with a great\nNetBeans party\non Saturday night, I met a lot of great people at that party doing some interesting stuff (although its all hazy with the medication and the beer). I met\nJoonas Lehtinen\nat that party he is the founder and CEO of\nvaadin\n(who now have a great\nnew NetBeans plugin\n), which is a name that I saw popup every now and again. I’m a heavy GWT user and love it but it has its limitations, I guess I didn’t pay enough attention (too busy with mobile) to notice that\nvaadin\nis really a hybrid solution that tries to merge the stuff I liked about Echo2 with the stuff I like about GWT. Very cool! One of the great things about their booth is that they literally had a pile of vaadin books as the giveaway, finally a show giveaway that is actually useful!\nKudos on that one, we should definitely do something like that as well. It also gave me a chance to read something on takeoff and landing (3 connections on the way home) so I was able to finish that pretty hefty book (honestly I skimmed some parts such as installation).\nAnother cool thing about vaadin is that they are an open source startup that has ±70 employees, really encouraging stuff on a personal level.\nOn NetBeans day itself I was on my way to Moscone (if you are a long time alumni this alone should provide you the reason to attend NB day, its at Moscone), when I ran into\nGeertjan\n. We both walked to the first session of the day entered the room and there sitting and working bright and early is Dr. James Gosling. Alone.\nPeople reading this blog can probably imagine my feeling at that moment, but I’m an entrepreneur first and human being second… I instantly descended on him like locust pitching Codename One and giving him the birds eye view pitch.\nHe was great and expressed interest, at the end of the day I asked that he would join our advisory board and I have his email so I can continue begging thru that medium! So that alone was a huge thing for me on a personal and professional level.\nGosling demoed his cool robots to the crowd, being a mobile/embedded guy (and having worked on robots as a kid) I really appreciate a lot of the stuff they are doing at\nliquid robotics\n. They have amazing visualization tools for controlling these robots which I’m sure will really benefit from Codename One… I promised him that if he accepts my invitation I will personally port everything to Codename One and give him a great tablet UI to play with the robots.\nGosling told the story of the NetBeans acquisition, having worked at Sun I can pretty much attest to the mindset behind it. The gist of the story is that Sun at some point decided they want a \u0026ldquo;big play\u0026rdquo; on development tools and didn’t have anything good (because they kept killing internal projects so as not to compete with Borland et. al.). So they were looking for a billion dollar acquisition and came across Forte which was making mainframe tools (totally unrelated), Gosling tried to convince management to buy NetBeans but they decided that the price was too low so its not a \u0026ldquo;big play\u0026rdquo;. Eventually the compromise was to buy both (he put it as: the price for NetBeans was a rounding error on the Forte deal).\nYears later Forte is effectively nothing and NetBeans has 1.4m active users.\nThere were a lot of other great talks that day but frankly I was all jagged up on Gosling and I don’t remember anything. I vaguely remember my talk on that day too although from feedback I got it was apparently given. I think I also had a sugar rush from all the great cupcakes\nTinu\nordered for the event celebrating 15 years of NetBeans (Google is also 15 years old this week, coincidence???).\nNathan Howard wrote a\ngreat blog post highlighting the NetBeans plugins\nthat were presented that day.\nIn the middle of the NetBeans day we left for the keynote (in Moscone again which was cool), there were quite a few technical glitches in the keynote which is pretty shocking. I remember working on keynote presentations when at Sun, the level of work and rehearsal is astounding and having tech issues in that setting is really surprising.\nThe keynote talked about what a great year this was for Java, I understand the need to get people enthusiastic and excited in a keynote (and be positive) but ignoring the security issues and NSA warnings etc. (within the keynote) is a bit much.\nThe thing is Oracle actually has a security track in JavaOne now and is doing a lot of things to fix the problems we saw this year, I’d much rather hear \u0026ldquo;we had a tough year on this front but here is how we are fixing it\u0026rdquo;. The keynote was mostly anemic talking a lot about the embedded effort which is very interesting (the internet of \u0026ldquo;things\u0026rdquo;), but there was very little content there that was interesting to me personally as a mobile developer that isn’t a mobile HTML developer or an embedded developer.\nThe day ended with a BoF about contribution to the JDK narrated by Daniel Sachse and Helio Frota, I came because of the description of the BoF which was pretty in line with Daniel’s presentation. However, it seems the committee that approved the BoF unified two separate and unrelated talks into one causing some frustration in the audience most of whom came for the description which was taken from Daniels talk.\nThe next day started with a session of notify your mobile clients by\nJay Balunas\nand\nMatthias Wessendorf\nof the JBoss team at RedHat, they talked about sending push messages from the server. The talk was good, geeky and coherent. I think they made the problem seem a bit easier than it really is in the real world, they have an open source project called\nAeroGear\nwhich I will be sure to check out the next time I look at our push code.\nNext on\nRichard\nand\nJasper\ngave their annual what’s new in JavaFX talk which was pretty interesting. To me the biggest announcement by far: one thread!\nUp until now if you wanted to touch JavaFX from Swing you had to mix the threads since both have their own EDT. This is pretty similar to Codename One only imagine having 2 EDT’s and keeping track of both while you have your own code running. That isn’t horrible for simple use cases but in the case of our webkit and graphics implementation this is something that is REALLY hard to get right. They added an experimental flag that effectively unifies both threads into one thread, this should make migrating code way easier. They announced a lot of other stuff from 3d to embedding Swing in FX (up until now you could only embed in the opposite direction).\nI grabbed Richard for a chat, we have known each other online for quite a while mostly thru the work I did for SwingX’s open source project and in my properties work later on (and now thru Codename One). We ended up going to lunch with Richard, Jasper and\n_\nSteve\n_\nNorthover. Apparently they now work very closely with Daniel Blaukopf who is a great friend from the Sun Microsystems WTK team days and one of the smartest people I know. We had some lunch and chatted a bit about FX and Codename One. It was a very interesting conversation but there is no point of going into details at this point in time.\nI missed a session and arrived at a session on Clojure, I didn’t like Clojure when it was called Lisp and that feeling remains the same. Trying to push a language like Clojure is like trying to get us all to use superior keyboard layout (e.g. Dvorak), probably won’t happen. These things are rooted too deep, but maybe I’m old (strike that, I am old who knows?).\nI ran into a friend so I was late to the multi-device session by\nDavid Campelo\n. I think I met David years ago when working for Sun, Chen and him know each other from our work on GingaJ which effectively put LWUIT on TV screens in Brazil. He gave an interesting demo about connecting tablets to the currently playing content on a TV, that is indeed an interesting direction to explore. I understand that the level of engagement in such experiences is tremendous and this is probably the future for such tools.\nUnfortunately his demo didn’t work, I can feel his pain. Its really hard to show network/device stuff especially with proprietary chains involved. There are so many points of failure which is why I always bring a ready made video of the demo in case of such a failure. This works like Murphy’s law, when you take that precaution the demo never fails…\nI then went on the\nMatthew\n‘s GIT on NetBeans Hands On Lab. I am not a fan of Hand On Labs and rarely take them (I never liked sitting in classrooms), I went simply because I was so impressed by Matthew following his JavaZone talk and wanted to see more. Matthew is indeed as great a teacher as he is a speaker, he was very interactive and I feel I understand GIT better now. If you happen to see his name at a conference you are attending I highly recommend you check it out, I think its always a good policy to just go to sessions with good speakers. Even if the subject isn’t interesting to you right now you can learn so much.\nIn the past we had a lot of issues with GIT especially for Chen who is using Windows where the GIT GUI support isn’t as good as the SVN integration. I’m assuming some of this got fixed and it also seems we used GIT somewhat like Teamware (the gradfather of GIT) which I always loved and Chen really hates with a vengeance. Maybe its time to switch back to github, I love their UI and a lot of the things about it. I wonder how easy it would be to migrate a Google code project (probably should have asked Matthew).\nI then rushed to the JCP party on the roof of the Hilton, it had nice food and some interesting people but I couldn’t stay and ran off to a BoF on Swing \u0026amp; JavaFX. On my way to the BoF room I ran into\nTinuola Awopetu\nwho does the marketing for the NetBeans team, we started chatting and it turns out she had her own panel BoF starting just then titled: \u0026ldquo;So You Want to Be a Published Technical Author?\u0026rdquo;.\nA friend from Sun and one of the best technical writers I know\nJonathan K\nnudsen\n(who also wrote one of the first LWUIT tutorials) used to describe book authoring as torture. So I don’t want to write a book.\nHowever, I had fun talking with Tinu and\nthought I might as well check out the BoF. I’m glad that I did.\nIt featured 5 panelists:\nErol Staveley\n– publisher at Packt\nJoel Murach\n– who is both an author and publisher at Mike Murach \u0026amp; Associates\n[\nMeghan Blanchette\n](https://twitter.com/MeghanORM)\n– editor at O’Reilly Media\nArun Gupta\n– needs no introductions but in this case he came as an\nauthor\n.\n[\nDavid Heffelfinger\n](https://twitter.com/ensode)\n– an established author of\nseveral books\n.\nThis was a very interesting/fun panel, I hadn’t thought about the option of writing a Codename One book before this panel but I am now entertaining the thought.\nJust goes to show that you should always be open at Java One.\nThe next day started by touring the exhibition floor, I was on a tight schedule running around to very specific booths of interest. Last year I was so busy I didn’t get to see the pavilion even once, so I was very careful and methodological this year. There were many interesting booths from IBM, RedHat, ARM etc. but the startups were more bold. CloudBees literally dressed all their personnel as bees, including head of marketing and (male) CEO. Amusing, but I think I’m too dry to do something like that.\n\u0026ldquo;Practical Pros and Cons of Replacing Swing with JavaFX in Existing Applications\u0026rdquo; was the title of a surprisingly interesting session. I added it to my list because it was lead by\nGeertjan\nbut pretty much everyone on the panel had an interesting story. It focused on developers using the NetBeans platform (platform not just the IDE) for their development who incorporated JavaFX in various ways to reap the benefits of improved UI visualizations.\nSean Phillips\npresented the app he has been working on for NASA (later on he showed it in the\ncommunity keynote\n, I think he got a dukes choice award for it), it is a NetBeans platform/FX based visualization of spacecraft motion in formation. This includes amazing visualizations for NASA scientists, I suggest checking out a small portion of his demo in the community keynote, very compelling. What doesn’t really show in the keynote is how excitable, enthusiastic and passionate he is about this technology.\nTimon Veenstra\npresented a pretty cool NetBeans platform app that enables\ncrop management for farmers\ninteresting stuff. They won a Duke’s choice award. Its pretty cool.\nRob Terpilowski\npresented the work that he has been doing at\nLynden\nwhich is a major shipping company. They are using FX to make the UI’s of their rather elaborate tables more visually appealing and usable.\nI then went to watch \u0026ldquo;Play Framework Versus Grails Smackdown\u0026rdquo; which was delivered by two brilliant speakers:\nJames Ward\n\u0026amp;\nMatt Raible\n. The talk was great however they gave a member of the audience in the front seat a really loud bell (or gong) and whenever one of them \u0026ldquo;delivered a smackdown\u0026rdquo; he rang the bell really loudly. I was in the back and had a headache 20 minutes into the talk. Left to the speaker room next door where the bell was also heard only softly.\nThere are two reasons I went to the BoF \u0026ldquo;Teaching Java with Minecraft, Greenfoot, and Scratch\u0026rdquo;,\nDaniel Green\n\u0026amp;\nArun Gupta\n. My daughter is still a bit too young for programming I’ll probably have to start next year when she is 4. The session was fun and engaging, but the real kicker came later… All thru the session Arun dropped references to teaching his son to work on the Minecraft source code. In the general session his son (Aditya) got on stage and stole the entire JavaOne show, he launched Eclipse and went into a compelling demo (and anyone who ever demoed source code modification on stage knows this is HARD and BORING). The kid had the audience eating out of the palm of his keyboard, it was one of the best demos I saw on the JavaOne stage and the audience was totally with him as he complained about Eclipse or lamented on a method needing to be overriden \u0026ldquo;not sure why\u0026rdquo;. James Gosling followed him noting that now he wants to become a minecraft hacker!\nWednesday started with a session by\nNuvos\nwho are launching a WORA mobile solution in Java using a build cloud (sounds familiar?). They had a booth at the pavilion so I got a chance to talk to them and figure them out a bit.\nKevin\nis the founder/CEO of the company, they effectively started as a consulting project that grew into a solution for mobile.\nKevin is a great guy, we spent quite a while talking before and after his session. It might surprise some readers but we do wish them the best of luck, a rising tide raises all boats and our shared success would mean the success of Java \u0026amp; WORA for mobile as a whole.\nJaroslav Tulach\nA bit later I attended a great session \u0026ldquo;The Chuck Norris Experiment: Running Java in Any Browser Without a Plug-in\u0026rdquo; which was given by\nJaroslav Tulach\n(co-founder of NetBeans or Xelfi for us old timers) and\nAnton Epple\n. The session presented the\nBck2Brwsr\nJVM that JIT’s bytecode to JavaScript (yep), this isn’t GWT… The JIT literally takes a JAR opens it and jits the content to JavaScript which is then executed pretty efficiently on the V8-JIT (JIT nesting at its best).\nThe ridiculous part is that it works and works well including debugging and decent IDE environment pretty shocking stuff. Unfortunately it doesn’t support threading (and no WebWorkers aren’t threads). The session itself was great and surprisingly even the Chuck Norris jokes were funny, both Anton and Jaroslav have a great sense of humor coupled with the technical chops to make this session one of the better sessions I attended at Java One.\nI tried to talk to them after the session but it was a bit too busy and I started talking with\nYusuke Yamamoto\nwho I thought I didn’t know. Turns out he wrote an\narticle about us\nlast year and also apparently a\npresentation\n. He is also a former Twitter employee and the author of\nTwitter4J\na very cool Twitter API allowing Java developers to work with the Twitter webservice easily. It would be great to port that to Codename One.\nAfter the community general session I ran into\nJaroslav \u0026amp; Anton hacking their way in the hall. I naturally descended on them and went into a long discussion with Jaroslav on thread support for Bck2Brwsr so we can add Codename One support for in browser apps. He is pretty adamant against this saying that it would impact performance considerably (he is right, this would require state transferal which is pretty tough), he pointed me at\nDoppio\nwhich is doing something similar but I can’t see a community working on this so I’m unsure of where they stand.\nRegardless you should check out\nthe\nBck2Brwsr\nJVM, its pretty amazing.\nThe last J1 session I attended was the\nRoboVM\nsession,\nNiklas was great although he needs to seriously simplify his message to the audience some of whom didn’t really understand what LLVM meant. He had great attendance considering the fact that this session was announced just before J1 started so most people wouldn’t have seen it in their schedule builder tool (even moreso considering the fact that some people already left as the conference was winding down they literally started folding up the room around us).\nI would describe RoboVM as a Xamarin for Java based on LLVM. Its an LLVM front end for Java that allows using the toolchain to build native iOS apps with native iOS API’s. Unlike Codename One which aims for WORA, RoboVM is targeted at avoiding Objective-C and giving a Java facelift to iOS development. Niklas did an amazing job in terms of tooling and the underlying technology and we are keeping a keen eye on this project, we spent a great deal of time talking about making a living from open source projects. I do hope that Niklas will find the model that works for him with RoboVM and is able to keep the amazing rate of progress he has shown so far.\nJavaOne ended with the usual party at Moscone, however this year they merged it with the Open World party which was too big and sucked as a result. I miss the old garden party which was crowded yet intimate, where you actually knew some of the people in attendance.\nRegardless, it was a fun JavaOne for me on a personal note. Hopefully next year will be as good or even better.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — September 30, 2013 at 7:15 pm (permalink) Anonymous says:\nI’m wondering whether RoboVM has better stack trace support than XMLVM.\nAnonymous — October 1, 2013 at 3:53 am (permalink) Anonymous says:\nGood question.\nYes and no. You will still have issue on devices since symbols are stripped and since we won’t be using the native simulator you won’t see most of that anyway.\nI think that if we will start maintaining XMLVM we will make radical changes to it which will improve performance, size and stack trace support. I have some ideas on the matter which I discussed with Arno to verify their feasibility. Naturally this all boils down to time/effort.\nAnonymous — October 4, 2013 at 2:07 pm (permalink) Anonymous says:\nI’m afraid I’m going to sound like a broken record, but thank you so much for this detailed report, it’s almost like being there! Do you know if/when the session videos will be available for viewing, like they did for 2012? Keynotes can only tell you so much… Also, I’m very intrigued by your JavaFX comment \u0026ldquo;It was a very interesting conversation but there is no point of going into details at this point in time.\u0026rdquo; We’ll stay tuned, I guess 😉 Congrats on the 21 millions devices! Love the ticker!\nAnonymous — October 4, 2013 at 4:20 pm (permalink) Anonymous says:\nThanks!\nAs far as I know they should upload everything to parleys.com but its not there yet. I wanted to reference some things I saw and checked there today.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/java-one-detailed-trip-report/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/java-one-detailed-trip-report/java-one-detailed-trip-report-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://twitter.com/SeanMiPhillips\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Uh\u0026hellip; I\u0026rsquo;m standing on stage next to James Gosling during rehearsal. Achievement unlocked.\" loading=\"lazy\" src=\"/blog/java-one-detailed-trip-report/java-one-detailed-trip-report-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eThere is absolutely no way I can recall everything that went on in JavaOne but I will try to do my best. I arrived sick and on pretty strong medication for my sinuses so my recollection might be a bit hazy, I did meet great people and had loads of fun.\u003c/p\u003e\n\u003cp\u003eBefore JavaOne started I had a meeting with\u003cbr\u003e\n\u003ca href=\"http://www.puder.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nArno\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nof the\u003cbr\u003e\n\u003ca href=\"http://xmlvm.org/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nXMLVM\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nproject, I was hoping to get more facetime with him and to maybe actually code something together but he was on his way for the rest of the week due to other duties. We discussed some of the issues with XMLVM and the potential of forking vs. merging our changes with the main XMLVM code base. The way things look it seems that we will have to take over XMLVM or at least the iOS/Windows Phone ports.\u003c/p\u003e","title":"Java One Detailed Trip Report"},{"content":"\nI’m writing this from the lobby of the Hilton hosting the JavaOne conference a bit jetlagged,\nGeertjan\ninvited me to speak at the NetBeans day which was great. However, the best thing was meeting\nJames Gosling\nand talking to him about Codename One!\nI had a lot of doubts about making the trip so soon after\nJavaZone trip\nbut\nGeertjan\nconvinced me by mentioning that there is a chance of meeting\nGosling\nwhich was pretty much the thing that convinced me. So for me the trip is now a huge success.\nI’ve also got a chance to meet\nArno\nagain which is great, I was hoping for more face time with him so we could actually do some coding together but he had some unfortunate scheduling conflicts at the last moment. This is really important for me since we are currently in the position of re-evaluating and reimagining our iOS infrastructure especially in terms of graphics but also in VM capabilities.\nMet a lot of great people and companies around here so far, too many to mention. I’ll try to write a more detailed report as the conference winds down.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/javaone-trip/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/javaone-trip/javaone-trip-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/javaone-trip/javaone-trip-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eI’m writing this from the lobby of the Hilton hosting the JavaOne conference a bit jetlagged,\u003cbr\u003e\n\u003ca href=\"https://blogs.oracle.com/geertjan/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nGeertjan\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\ninvited me to speak at the NetBeans day which was great. However, the best thing was meeting\u003cbr\u003e\n\u003ca href=\"http://nighthacks.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nJames Gosling\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nand talking to him about Codename One!\u003c/p\u003e\n\u003cp\u003eI had a lot of doubts about making the trip so soon after\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/3/post/2013/09/javazone-trip-report.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nJavaZone trip\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nbut\u003cbr\u003e\n\u003ca href=\"https://blogs.oracle.com/geertjan/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nGeertjan\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nconvinced me by mentioning that there is a chance of meeting\u003cbr\u003e\n\u003ca href=\"http://nighthacks.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nGosling\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nwhich was pretty much the thing that convinced me. So for me the trip is now a huge success.\u003c/p\u003e","title":"JavaOne Trip"},{"content":"\nA lot has happened with the side menu bar (the\nHamburger Menu\n) since we initially launched it. We now support a lot of new features seamlessly such as swiping the sidemenu in/out and various other capabilities. The other day we added support for side menus on the right and top as well as multiple buttons on the side menu title bar.\nSo lets get started with the features, first is one of the newer features up our sleeve, the ability to place a side menu on the right, top or on both sides of the title (as in the facebook app). You can\naccomplish this by using something like cmd.putClientProperty(SideMenuBar.COMMAND_PLACEMENT_KEY, SideMenuBar.COMMAND_PLACEMENT_VALUE_RIGHT);\nOr as you might see in this more detailed example where you can just swap menu placements on the fly:\nOne of the nice things about the side menu bar is that you can add just about anything into the side menu bar by using the SideComponent property e.g.:\nThis is remarkably useful but its also somewhat problematic for some developers, the SideMenuBar is pretty complex so if we just set a button to the custom component and invoke showForm() we will not have any transition out of the side menu bar. Thankfully we added several options to solve these issues.\nThe first is actionable which you enable by just turning it on as such: cmd\n.putClientProperty(\u0026ldquo;Actionable\u0026rdquo;, Boolean.TRUE);\nThis effectively means that the custom\ncomponent will look exactly the same, but when its touched/clicked it will act like any other command on the list. This uses a lead component trick to make the hierarchy (or component) in customCmp act as a single action.\nThere are several additional options that allow you to just bind action events and then \u0026ldquo;manage\u0026rdquo; the SideMenuBar e.g.:\nSideMenuBar.\nisShowing() – useful for writing generic code that might occur when the SideMenuBar is on the form.\nSideMenuBar.closeCurrentMenu() – allows you to close the menu, this is useful if you are not navigating to another form.\nSideMenuBar.closeCurrentMenu(Runnable) – just like closeCurrentMenu() however it will invoke the run() method when complete. This allows you to navigate to another form after the menu close animation completed.\nThe TitleCommand property allows you to flag a command as something you would want to see in the right hand title area and not within the SideMenu area. Just place it into a component using cmd.putClientProperty(\u0026quot;TitleCommand\u0026quot;, Boolean.TRUE);\nLast but not least w\ne also have some helpful theme constants within the side menu bar that you might not be familiar with:\nsideMenuImage – pretty obvious, this is the hamburger image we use to open the menu.\nsideMenuPressImage – this is the pressed version of the image above. Its optional and the sideMenuImage will be used by default.\nrightSideMenuImage/rightSideMenuPressImage – identical to the sideMenuImage/sideMenuPressImage only specific to the right side navigation.\nsideMenuFoldedSwipeBool – by default a swipe will open the side menu. You can disable that functionality by setting this theme constant to false.\nhideBackCommandBool – often comes up in discussion, allows hiding the back command from the side menu so it only appears in the hardware button/iOS navigation.\nhideLeftSideMenuBool – allows hiding the left hand menu which is useful for a case of top or right based side menu.\nsideMenuShadowImage – image that represents the drop shadow drawn on the side of the menu.\nsideMenuTensileDragBool – allows disabling the tensile draw within the side menu command area.\nI hope you will have fun exploring the new features of the side menu bar.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — September 19, 2013 at 8:55 pm (permalink) Anonymous says:\nOh these new additions to side menu are great, thanks.\nAnonymous — September 20, 2013 at 12:46 am (permalink) Anonymous says:\nGreat work on this guys.\nAnonymous — February 21, 2015 at 4:16 am (permalink) Anonymous says:\nwow great tutorial, much helpfull\nAnonymous — March 6, 2015 at 10:18 am (permalink) Anonymous says:\nHi Shai,\nIm trying to hide the bar at the top of the screen it creates in the example. I want to add a image in one of my containers that will trigger the side menu bar. Any suggestions on this? Regards,\nDante\nAnonymous — March 6, 2015 at 2:41 pm (permalink) Anonymous says:\nThat would be tough since we rely on this a bit. You can do a trick where you set the menu image to a small sized image and set the padding/margin to the title area to 0. Also set the title and title area UIIDs to be transparent.\nTo show your icon just use a layer in the layered layout and when its tapped just invoke open sidemenu.\nMahmoud — March 14, 2016 at 11:39 am (permalink) Mahmoud says:\nwhen i put Side Menu Bar to right Side (Menu Bar Image show in black color)\nbut my SideMenuBarImage in my theme is white color\nShai Almog — March 15, 2016 at 3:20 am (permalink) Shai Almog says:\nYou need to use the theme constant rightSideMenuImage as you can have two different side menu bars and each can have its own image. You are seeing the default image whose color you can control by styling the foreground property.\nMahmoud — March 15, 2016 at 12:13 pm (permalink) Mahmoud says:\nthanks Shai\nMahmoud — March 26, 2016 at 8:45 pm (permalink) Mahmoud says:\nhi Shai,\ni have right side menu and my background is white but i have gradient line at the first of menu\nhow i can remove it\nthanks\nShai Almog — March 27, 2016 at 4:27 am (permalink) Shai Almog says:\nThat is the shadow for the sidemenu set the theme constant sideMenuShadowBool=false\nMahmoud — March 27, 2016 at 5:46 am (permalink) Mahmoud says:\nThank you very much\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/on-the-side-up-on-top/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/on-the-side-up-on-top/on-the-side-up-on-top-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/on-the-side-up-on-top-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Sidemenu\" loading=\"lazy\" src=\"/blog/on-the-side-up-on-top/on-the-side-up-on-top-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eA lot has happened with the side menu bar (the\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/3/post/2013/02/hamburger-sidemenu.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nHamburger Menu\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n) since we initially launched it. We now support a lot of new features seamlessly such as swiping the sidemenu in/out and various other capabilities. The other day we added support for side menus on the right and top as well as multiple buttons on the side menu title bar.\u003c/p\u003e\n\u003cp\u003eSo lets get started with the features, first is one of the newer features up our sleeve, the ability to place a side menu on the right, top or on both sides of the title (as in the facebook app). You can\u003c/p\u003e","title":"On The Side, Up On Top"},{"content":"\nBefore we get into the subject of today’s post a small public service announcement: we recently added the ability to create annual pro subscriptions. This provides a 10% discount over our standard pro subscription rates.\nI’m writing this while preparing for my JavaZone flight. What you see in the picture on the right is the typical content of my backpack which I carry with me everywhere in case there is a problem I need to debug, this is somewhat of a visual tutorial of \u0026ldquo;what it takes\u0026rdquo; to be a mobile developer today. I took this picture for the JavaZone presentation I’m making and I think it illustrates well why Codename One exists (BTW it is missing some of my testing devices such as the iPad 2, the Android tablets and a few J2ME phones). From left to right top to bottom:\nWindows 8 Machine (for building Windows Phone apps)\niPad 3 (retina – iOS 7 beta)\nMac (for building iOS apps)\nBlackberry Z10 (BB OS 10)\nNokia Asha (S40)\niPod Touch (iOS 6)\nNexus One (Gingerbread)\nGalaxy Nexus (Jelly Bean)\nBlackberry Torch (BB OS 6)\nNokia Lumia 520 (Windows Phone 8)\nWho said mobile development isn’t back breaking work!\nAnd now for something completely different: On iOS the translation tool we use for converting bytecode to xcode applications is tuned for compatibility more than it is tuned for speed. This means that generated code performs a lot of null pointer checks (so it can throw a NullPointerException) and performs array boundary checks. Both of these effectively slow the execution of your application significantly.\nWe now have a new build flag for iOS called:\nios.unsafe\nIf you define that build argument as true:\nios.unsafe=true\nYou will get an application that won’t throw ArrayIndexOutOfBounds exceptions or NullPointerExceptions, however it might crash for such cases!\nThis is one of those flags that you will need to test REALLY well before using in production, however once enabled it should drastically improve the performance of Codename One.\nNotice that some things are never tested by the translated code such as class cast exception etc. (so code that relies on those will just crash).\nWe are now in the process of re-designing our iOS backend which includes some tough decisions regarding backend technology, our goals are:\nShortening build times.\nImproved crash analysis\n.\nFaster execution.\nImproved graphics support.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — September 9, 2013 at 8:55 am (permalink) Anonymous says:\nhow much weight this total stuff 😉 ?\nAnonymous — September 20, 2013 at 8:33 am (permalink) Anonymous says:\nIf we don’t use the ‘unsafe’ flag, do unnecessary null pointer checks get optimised out anyway?\nIf the Java-\u0026gt;C conversion just converts the opcodes, you’ll get a lot of unnecessary ones. e.g. References to ‘this’ will still have the check, as will references returned from the ‘new’ operator. I think you can also cut out quite a lot by only checking references stored in local variables once after each assignment.\nI think you can make considerable speed savings with those techniques, and they aren’t that hard to implement. Importantly, you don’t change the semantics of the code at all…\nAnonymous — September 20, 2013 at 2:17 pm (permalink) Anonymous says:\nBack breaking weight…\nAnonymous — September 20, 2013 at 2:18 pm (permalink) Anonymous says:\nTrue, the main cost though is in loops.\nAnonymous — September 23, 2013 at 5:50 am (permalink) Anonymous says:\nYes, there are a few things you can do to speed loops up, though mostly only when you’re using final/local variables due to potential threading issues.\nAnyway, my question was: do you do any of those optimisations when ios.unsafe = false?\nAnonymous — September 23, 2013 at 8:56 am (permalink) Anonymous says:\nNo. The only thing the unsafe flag does is remove the checks, most of the optimizations in the LLVM compiler from Apple are actually pretty great although we can/should definitely improve threading/monitors.\nI’m now in the process of overhauling our entire VM/graphics infrastructure so I’m looking into improvements there as well.\n(Replying to myself since blog software supports limited nesting)\nAnonymous — January 10, 2014 at 12:07 am (permalink) Anonymous says:\nSo what happens when things crash with this flag set? App just vanishes with no message? Im going to turn it on right now!!!\nAnonymous — January 10, 2014 at 12:12 am (permalink) Anonymous says:\nps – does this mean it will run faster than Android? or not ?\nAnonymous — January 10, 2014 at 2:50 am (permalink) Anonymous says:\nIt will crash. You can disable exception messages without using this by defining an error handler.\nAndroid has a JIT, static compilation can’t beat JIT for some use cases.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/faster-ios-runtime-javazone-edition/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/faster-ios-runtime-javazone-edition/faster-ios-runtime-javazone-edition-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/faster-ios-runtime-javazone-edition-large-2.jpg\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Content of Shai\u0026rsquo;s Backpack\" loading=\"lazy\" src=\"/blog/faster-ios-runtime-javazone-edition/faster-ios-runtime-javazone-edition-1.jpg\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eBefore we get into the subject of today’s post a small public service announcement: we recently added the ability to create annual pro subscriptions. This provides a 10% discount over our standard pro subscription rates.\u003c/p\u003e\n\u003cp\u003eI’m writing this while preparing for my JavaZone flight. What you see in the picture on the right is the typical content of my backpack which I carry with me everywhere in case there is a problem I need to debug, this is somewhat of a visual tutorial of \u0026ldquo;what it takes\u0026rdquo; to be a mobile developer today. I took this picture for the JavaZone presentation I’m making and I think it illustrates well why Codename One exists (BTW it is missing some of my testing devices such as the iPad 2, the Android tablets and a few J2ME phones). From left to right top to bottom:\u003c/p\u003e","title":"Faster iOS Runtime – JavaZone Edition"},{"content":"\nOur email api only supported a single attachment until now. We just added an api that allows for multiple attachments which we will add in the next update. Notice that multiple attachments will only work on iOS/Android at the moment.\nAlso in this update you would find a fix for the Twitter service (see the TwitterRESTService class) and some other capabilities such as support for network performance issues.\nThe simulator now allows you to simulate a case of no network connectivity and slow connectivity. This simulation isn’t accurate but it should help in gauging the feel for such cases and debugging complex scenarios. To see this in action just select the Network section in the simulator menu and select the mode for the simulator to run in.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/attachments-network-speed-and-more/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/attachments-network-speed-and-more/attachments-network-speed-and-more-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/attachments-network-speed-and-more/attachments-network-speed-and-more-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eOur email api only supported a single attachment until now. We just added an api that allows for multiple attachments which we will add in the next update. Notice that multiple attachments will only work on iOS/Android at the moment.\u003c/p\u003e\n\u003cp\u003eAlso in this update you would find a fix for the Twitter service (see the TwitterRESTService class) and some other capabilities such as support for network performance issues.\u003c/p\u003e","title":"Attachments, Network Speed and More"},{"content":"\nWe’ve had pull to refresh for quite some time which is a really nice feature useful for pulling new updates. We also always had infinite lists using a smart list model approach, however up until now we didn’t have a standard implementation of an infinite container with arbitrary components.\nIn some of the newer web UI’s such as Tumblr and Twitter the data is fetched dynamically when you reach a fixed location in the form, this is a simpler approach than the one demonstrated by the list model but in some regards its more practical. A user can’t just start jumping around and fetching the entire list, this works better with most REST API’s and is pretty powerful on its own.\nMy initial thought was to create a Container subclass or even add support for this into Container itself, but eventually I came to the conclusion that this is really unnecessary and we can accomplish something like this without modifying the internal code. For this purpose we created the\nInfiniteScrollAdapter which is a really simple class that binds to a container and gives you the ability to add components to it. The API is remarkably simple you just invoke the static method InfiniteScrollAdapter.createInfiniteScroll() with an empty container then wait for it to invoke the runnable you submit to it.\nThe runnable will be invoked on the EDT so be sure not to block it (unless you use an AndWait or invokeAndBlock method), in it you can fetch data and once you are done add any set of components you like using the\naddMoreComponents() method. Notice that you shouldn’t just add/remove components on your own since this will mess up the container.\nHere is a simple example that adds buttons and sleeps to simulated slow network activity:\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — September 2, 2013 at 11:15 am (permalink) Anonymous says:\nNice !\nAnonymous — January 4, 2014 at 11:20 am (permalink) Anonymous says:\nI want to add/remove components dynamically not infinitely like here.\nFor example if click on ‘make’ button it will create new 5 buttons. When i again click on ‘make’ again it should remove previous 5 buttons and add new 5 buttons (like a search application where new search appears with new keywords and previous one is gone)….\nAny help appreciated ….\nAnonymous — January 4, 2014 at 5:00 pm (permalink) Anonymous says:\nI don’t understand the problem?\nJust place the 5 entries in a container and replace the container when the button is pressed. That isn’t infinite scrolling.\nAnonymous — January 28, 2014 at 9:16 am (permalink) Anonymous says:\nHello,\nThe above example works, but not when I’m asynchronously creating Components in the invokeAndBlock code.\nI’m actually creating a List of components which I’ll pass to addMoreComponents; but it seems the invokeAndBlock method doesn’t wait until all netwerk processing is done and the list is fully available. Because when the addMoreComponents is called, the list is still empty.\nI must be missing something…\nWim\nAnonymous — January 28, 2014 at 10:39 am (permalink) Anonymous says:\nHello,\nI managed to workaround the threading issue by using the list in my network call back by checking the size of it. If it contains an equal number of items then my network calls then I know that my network code is currently processing the last request.\nWhen that is the case I can call addMoreComponents, and clear the list afterwards.\nOne catch was that I had a deadlock when another form (not displayed yet) did a new WebBrowser() in the constructor =\u0026gt; in InfiniteScrollAdapter the infiniteContainer.animateLayoutAndWait(300); blocked everything.\nFixed this by initalizing the webBrowser only when I needed it.\nPS: Passing an array with one element to addMoreComponents gives an ArrayOutOfBounds exception.\nAnonymous — January 28, 2014 at 5:02 pm (permalink) Anonymous says:\nYour basic premise is wrong. InvokeAndBlock runs off the EDT so changing components from there will fail and is wrong. You should use the EDT violation detection tool in the simulator to detect such bugs.\nOnce you do stuff off the EDT things will fail in odd and unpredictable ways, what you got working might not work on the device.\nAnonymous — January 29, 2014 at 4:25 am (permalink) Anonymous says:\nI created the Component objects in the invokeAndBlock, but didn’t add them to the adapter with addMoreComponents, I just added them to a List. Later when I’m back on the EDT, I called addMoreComponents with that List.\nI’ll check the EDT violation detection tool to be sure though.\nWim\nAnonymous — August 22, 2014 at 3:11 am (permalink) Anonymous says:\nI think that I have same problem:\nFor example:\nWe have 100 elements in container. When user goes to the end of the list, I want to add 10 elements to the end of the list and remove first 10 elements and vice versa. I want to get constant number of elements in container.\nAnonymous — August 22, 2014 at 1:20 pm (permalink) Anonymous says:\nWe designed this for adding only but it should be possible to remove the first 10 elements from the container just as well. What did you try?\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/till-the-end-of-the-form/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/till-the-end-of-the-form/till-the-end-of-the-form-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/till-the-end-of-the-form/till-the-end-of-the-form-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve had pull to refresh for quite some time which is a really nice feature useful for pulling new updates. We also always had infinite lists using a smart list model approach, however up until now we didn’t have a standard implementation of an infinite container with arbitrary components.\u003c/p\u003e\n\u003cp\u003eIn some of the newer web UI’s such as Tumblr and Twitter the data is fetched dynamically when you reach a fixed location in the form, this is a simpler approach than the one demonstrated by the list model but in some regards its more practical. A user can’t just start jumping around and fetching the entire list, this works better with most REST API’s and is pretty powerful on its own.\u003c/p\u003e","title":"Till The End Of The Form"},{"content":"\nExciting news this week, Chen FINALLY did what we procrastinated on for so long and wrote an auto-complete text field!\nThis is really easy to incorporate\ninto your code, just replace your usage of TextField with AutoCompleteTextField and define the data that the auto complete should work from. There is a default implementation that accepts a String array or a ListModel for completion strings, this can work well for a \u0026ldquo;small\u0026rdquo; set of thousands (or tens of thousands) of entries.\nHowever, if you wish to query a database or a web service you will need to derive the class and perform more advanced filtering by overriding the\nfilter method and the getSuggestionModel method. You might also need to invoke updateFilterList() if your filter algorithm is asynchronous.\nHere is a sample of a simple auto-complete that doesn’t use the advanced features:\nAs part of that feature Chen also added something very interesting to Form… Up until now the best way to draw on top of a Form was to create a glass pane create your own layered layout for the internal content pane.\nChen added a cool new method to form:\ngetLayeredPane().\nEssentially a layered pane sits on top of your content pane and you can just place any component you want there just like you would in the content pane. Only difference is that it will be drawn on top of the content pane. Unlike the glasspane which is a drawing API and lacks interactivity the layered pane allows you to place pretty much any component there.\n**\niOS 7 Update\n**\nAccording to the latest rumors Apple is about to release iOS 7 by September 10th, so here is a quick update on where we stand and what you need to know moving forward.\nJust so we are 100% clear, all current builds work on iOS 7 devices. We have already migrated our devices to the latest beta’s and have verified that builds keep working!\nHowever, iOS 7 is a major departure in terms of design and some application behaviors. The biggest change is the move to\nflat design\n, Tope has a great blog post\ndetailing some of the migration efforts\nfrom a designers perspective.\nYou can already update your user interface and theme to be more flat and modern (as well as your icon design etc.).\nWe would ideally update some of our themes to match those expectations.\nAs people start migrating to OS 7 you might want to make your app OS 7 only and thus take advantage of the taller title area (the title area in OS 7 stretches behind the battery/time/network indicator) as well as some minor OS 7 tweaks and the default OS 7 look. To do that you will need to have your application compiled with XCode 5 which is currently in beta. We already tested this process and we will allow a build argument to use XCode 5 once the tools are released from beta. Naturally, our recommendation is that you do not use these tools until most users migrate (which I assume will be slow given how some people feel about iOS 7).\n**\nTraction, Testimonials \u0026amp; Trips\n**\nYou might have noticed the big counter of installed devices we added to the home page, we are pretty thrilled having crossed the 20M device install base. Now lets work on adding a couple of zeros there…\nWe also added a testimonials popup to the home page (commented out due to an issue in Firefox), if you have a testimonial you would like to contribute to appear on our home page and an impressive public linked in profile we would really appreciate it\nif you take the time to\nwrite something about us\n(please include the linked in public profile link).\nI will be speaking at both JavaZone and JavaOne (NetBeans day) this year. So I will be in both Oslo and San Francisco, if any of you are coming to these conference or live in the area I’d love to meet, just contact us via the\ncontact form\n.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — August 29, 2013 at 3:45 am (permalink) Anonymous says:\njust thought you should know, that the title to this post is different, from the title on the front page of the website\nAnonymous — August 29, 2013 at 3:50 am (permalink) Anonymous says:\nThanks Kevin!\nThe dangers of Copy \u0026amp; Paste…\nAnonymous — September 11, 2014 at 1:25 pm (permalink) Anonymous says:\nIs there any setModel method to pass the autocomplete data other than putting it in the contructor\nAnonymous — September 12, 2014 at 6:12 am (permalink) Anonymous says:\nNo but you can override the filter method to get more elaborate filtering capabilities.\nAnonymous — January 27, 2015 at 6:55 am (permalink) Anonymous says:\nalways saying \u0026ldquo;you can filter\u0026rdquo;. please show us one example..\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/completion-ios-7-update-and-the-20m-mark/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/completion-ios-7-update-and-the-20m-mark/completion-ios-7-update-and-the-20m-mark-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/completion-ios-7-update-and-the-20m-mark-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/completion-ios-7-update-and-the-20m-mark/completion-ios-7-update-and-the-20m-mark-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eExciting news this week, Chen FINALLY did what we procrastinated on for so long and wrote an auto-complete text field!\u003c/p\u003e\n\u003cp\u003eThis is really easy to incorporate\u003c/p\u003e\n\u003cp\u003einto your code, just replace your usage of TextField with AutoCompleteTextField and define the data that the auto complete should work from. There is a default implementation that accepts a String array or a ListModel for completion strings, this can work well for a \u0026ldquo;small\u0026rdquo; set of thousands (or tens of thousands) of entries.\u003c/p\u003e","title":"Completion, iOS 7 Update And The 20M Mark"},{"content":"\nWho would have thought Hungarian folk dance would be so entertaining! Can’t. stop. watching….\nIts been a busy week mostly spent on updating the build server code so its iOS 7 ready, during that time we also managed to get some other things done… These are some of the highlights:\nYou may recall the\nImageViewer class that I mentioned a while back\n, it will now be a part of the designer and has some small improvements to its event handling as well as keyboard handling.\nWe now have a new set of image rotation API’s designed for camera images. These API’s can rotate or flip an image by square angles, which is important for rotating an image that isn’t a perfect square (e.g. taken by camera). These API’s are really simple to use e.g.: image.rotate90Degrees(true);\nWhere the boolean argument indicates whether the image is opaque (e.g. for the case of a camera image). There are also methods for 180 and 270 degrees as well as vertical and horizontal flip methods.\nUp until recently we always told people to avoid the scaled method as much as possible, the main issue was that an image gets decoded and then is very expensive to hold in RAM. This is not necessarily the case anymore. Now if you invoke the scaled() method on an EncodedImage (assuming you are not on a feature phone) the ImageIO class will be used to re-encode the resulting image and allow you the same benefits as any other encoded image.\nWe still don’t recommend scaled since its still less efficient than drawing and not as sharp as multi image. It will now also be slightly slower but it will have a better memory footprint.\nWe also added a feature that allows you to create an encoded image from ARGB data, again using the ImageIO class, this isn’t guaranteed to work (since ImageIO doesn’t necessarily exist in all devices) but when it does it should be more efficient for most use cases.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — August 27, 2013 at 3:46 am (permalink) Anonymous says:\nImageViewer is deleted in new version have any class for instead for it ?\nAnonymous — August 27, 2013 at 4:51 am (permalink) Anonymous says:\nNo its not, its under components.\nAnonymous — August 29, 2013 at 7:49 am (permalink) Anonymous says:\nTell me your scaled() works for j2me.\nAnonymous — August 29, 2013 at 4:27 pm (permalink) Anonymous says:\nSure, but it doesn’t feature this optimization.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/folk-dancing-and-general-updates/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/folk-dancing-and-general-updates/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWho would have thought Hungarian folk dance would be so entertaining! Can’t. stop. watching….\u003c/p\u003e\n\u003cp\u003eIts been a busy week mostly spent on updating the build server code so its iOS 7 ready, during that time we also managed to get some other things done… These are some of the highlights:\u003c/p\u003e\n\u003cp\u003eYou may recall the\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/3/post/2013/08/in-a-pinch.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nImageViewer class that I mentioned a while back\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, it will now be a part of the designer and has some small improvements to its event handling as well as keyboard handling.\u003c/p\u003e","title":"Folk Dancing And General Updates"},{"content":"\nRemember the\nPoker app we teased a couple of weeks ago\n?\nNow you can\nread all about it in SDJ, the entire article is in the downloadable PDF\n(please buy the magazine!).\nWe’ll try to post the full source code into SVN and get into more details about it here. If you have any questions/comments related to the article feel free to ask in the comments section right here.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-article-in-sdj/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-article-in-sdj/codename-one-article-in-sdj-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://sdjournal.org/game-development-how-to-become-a-millionaire-teaser-download-for-free/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\n\u003cimg alt=\"SDJ\" loading=\"lazy\" src=\"/blog/codename-one-article-in-sdj/codename-one-article-in-sdj-1.jpg\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eRemember the\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/3/post/2013/08/you-can-bet-on-it.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nPoker app we teased a couple of weeks ago\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n?\u003c/p\u003e\n\u003cp\u003eNow you can\u003cbr\u003e\n\u003ca href=\"http://sdjournal.org/game-development-how-to-become-a-millionaire-teaser-download-for-free/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nread all about it in SDJ, the entire article is in the downloadable PDF\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n(please buy the magazine!).\u003c/p\u003e\n\u003cp\u003eWe’ll try to post the full source code into SVN and get into more details about it here. If you have any questions/comments related to the article feel free to ask in the comments section right here.\u003c/p\u003e","title":"Codename One Article In SDJ"},{"content":"\nGridBag that is. So GridBagLayout is\none of the most notorious of the layout managers in Java\nin fact for many developers it symbolizes the failure of the layout manager concept. That is the main reason why we never added it.\nLast week I had a very interesting conversation with a very prominent Swing developer\nand he asked me whether we had gridbag support. I answered that we do not and repeated the regular \u0026ldquo;no one likes it\u0026rdquo; line, turns out he does like it and has a lot of Swing code that uses GridBag!\nInteresting…\nPorting a Swing/AWT layout manager to Codename One is pretty close to trivial, there are very few things you need to actually change.\nCodename One doesn’t have Insets, I added some support for them in order to port gridbag but components in Codename One have a Margin they need to consider instead of the insets (the padding is in the preferred size).\nAWT layout managers also synchronize a lot on the AWT thread. This is no longer necessary since Codename One is single threaded like Swing.\nComponents are positioned relatively to container so the layout code can start at 0, 0 (otherwise it will be slightly offset).\nOther than those things its mostly just fixing method signatures and import statements which are slightly different. Pretty trivial stuff and GridBagLayout from project Harmony is now working on Codename One.\nSo to show this off I\ntook this code from the Java tutorial\nand ported it to Codename One, pretty easy stuff:\nThe code is almost the same although I did need to make some adaptations e.g. JButton to Button, add to addComponent and reverse the order of arguments to addComponent. Other than that it was pretty trivial.\nNow this stuff probably won’t make it into the GUI builder in the forseeable future, but if you are hellbent on GridBag or porting some Swing code this should be pretty convenient. Its also a great case study if you want to port some of your other favorite layout managers such as MiG or FormLayout.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — August 19, 2013 at 11:51 pm (permalink) Anonymous says:\nI agree that GridBagLayout was hell to configure by hand, however I learned to like it more since the NetBeans team created their fancy customizer a few years ago… I wonder how easy/hard it would be to reuse it in CN1’s own designer ?\nAnonymous — September 5, 2013 at 3:35 pm (permalink) Anonymous says:\nYeah, I used gridbag a lot. It might be painful, but sometimes it was the best thing to do. I tried some of the other replacements and they were even more difficult and were not hand modifiable.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/its-in-the-bag/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/its-in-the-bag/its-in-the-bag-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/its-in-the-bag-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"GridBagLayout Swing vs. Codename One\" loading=\"lazy\" src=\"/blog/its-in-the-bag/its-in-the-bag-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eGridBag that is. So GridBagLayout is\u003cbr\u003e\n\u003ca href=\"http://madbean.com/anim/totallygridbag/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\none of the most notorious of the layout managers in Java\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nin fact for many developers it symbolizes the failure of the layout manager concept. That is the main reason why we never added it.\u003c/p\u003e\n\u003cp\u003eLast week I had a very interesting conversation with a very prominent Swing developer\u003c/p\u003e\n\u003cp\u003eand he asked me whether we had gridbag support. I answered that we do not and repeated the regular \u0026ldquo;no one likes it\u0026rdquo; line, turns out he does like it and has a lot of Swing code that uses GridBag!\u003c/p\u003e","title":"It's In The Bag"},{"content":"\nWhile Java rocks for teamwork because of its strict and streamlined heuristics, our resource files are less ideal. However we are changing that in the next update to Codename One!\nThe reason we chose to put everything into a binary resource\nfile should be obvious: small size, portability. These are two critical features we had in mind when we designed the resource file format, we also wanted it to be really simple so we can e-mail it to our designer and so people could use it without an IDE (which back in 2006 was far more common). We initially thought about creating an XML file format which a special tool will convert into the res file format (and we had some prior work on the matter such as the XML ant tasks) but these proved to be cumbersome to maintain.\nThe reason we looked at XML was team support, a binary file can only be modified by one person in the team which forced us to use \u0026ldquo;a wireless protocol for file locking contention based on sonic broadcasts\u0026rdquo; (otherwise known as shouting in the office: I’m changing the resource file, don’t make any changes to it).\nWith the advent of Codename One a lot of the initial constraints are no more, resources are in the root of the source folder and so we can make various assumptions that can keep the compatibility \u0026amp; ease of the existing resource file while provid\ning the full team capabilities and history support you expect. As a bonus this also allows for various capabilities such as scripting/automating file replacements etc.\nThe new version of the designer tool includes a checkbox option for XML team support (under the file menu), notice that it is in the version we released earlier\nthis week but it isn’t working properly.\nWhen you activate\nthe option every time you save the resource file we will automatically store an XML file in a \u0026ldquo;res\u0026rdquo; directory under your project root and a directory hierarchy containing all the data from within the resource file. When you load a res file (notice you always work with the res file never with the XML file) we will automatically detect that an XML file exists (assuming the XML option is turned on) and load that instead of the res file.\nWhat this means is that if the option is turned on, XML overrides resource. So even though you will have conflicts in the res file the XML file can just override the conflicts every time and its far more team friendly! Also because of the way it is laid out you can actually change things such as images without using the designer tool (you will need to reopen the file for changes to take effect). It is however important to save within the design tool for your changes to actually apply to the running project.\nRight now a lot of the internal data such as the actual screen designs is still in binary form mostly due to the logistics of changing this, we will look at changing this to XML too as we move along.\nImproved iOS Settings \u0026amp; New Features We’ve made some UI improvements to the project settings for iOS. We just had so many build arguments it was getting out of hand. Ideally we will add most build arguments to the UI so the configuration will be simpler.\nIn other news the side menu now allows you to swipe the menu in by just swiping the screen\nand it is also more robust in terms of \u0026ldquo;regret\u0026rdquo; e.g. if you start swiping it to close and don’t drag it enough it will bounce back to open state.\nThere are also some changes for dSYM files but these will have to wait for their own blog post.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/teamwork-and-other-things/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/teamwork-and-other-things/teamwork-and-other-things-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Team\" loading=\"lazy\" src=\"/blog/teamwork-and-other-things/teamwork-and-other-things-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWhile Java rocks for teamwork because of its strict and streamlined heuristics, our resource files are less ideal. However we are changing that in the next update to Codename One!\u003c/p\u003e\n\u003cp\u003eThe reason we chose to put everything into a binary resource\u003c/p\u003e\n\u003cp\u003efile should be obvious: small size, portability. These are two critical features we had in mind when we designed the resource file format, we also wanted it to be really simple so we can e-mail it to our designer and so people could use it without an IDE (which back in 2006 was far more common). We initially thought about creating an XML file format which a special tool will convert into the res file format (and we had some prior work on the matter such as the XML ant tasks) but these proved to be cumbersome to maintain.\u003c/p\u003e","title":"Teamwork (and other things)"},{"content":"\n**\nUpdate:\n**\nminor correction to the build process about the build.xml issue in the Codename One project.\nTo me the biggest advantage in Codename One over pretty much any other mobile solution is that its realistically open source. Realistically means that even an average developer can dig into 90% of the Codename One source code, change it and contribute to it!\nHowever, sadly most developers don’t even try and most of those who do focus only on the aspect of building for devices rather than the advantage of much easier debugging. By incorporating the Codename One sources you can instantly see the effect of changes we made in SVN without waiting for a plugin update. You can, debug into Codename One code which can help you pinpoint issues in your own code and also in resolving issues in ours!\nIts REALLY easy too!\nStart by\nchecking out the Codename One\nsources from SVN\n, use the following URL\nhttp://codenameone.googlecode.com/svn/trunk/\nwhich should allow for anonymous readonly checkout of the latest sources!\nNow that you have the sources open the CodenameOne project that is in the root and the JavaSEPort that is in the Ports directory using NetBeans. Notice\nthat these projects might be marked in red and you will probably need to right click on them and select Resolve Reference Problems. You will probably need to fix the JDK settings, and the libraries to point at the correct local paths.\nOnce you do that you can build bot\nh projects without a problem. Notice that you will probably get a minor compilation error due to a build.xml line in the Codename One project, don’t fret. Just edit that line and comment it out.\nNow the fun part, select any Codename One project in NetBeans, right click and click properties.\nNow select \u0026ldquo;Libraries\u0026rdquo; from the tree to your right select all the jars within the compile tab. Click remove.\nClick the Add Project button and select the project for Codename One in the SVN.\nNow select the Run tab and remove the JavaSE.jar file from there by selecting it and pressing remove.\nAdd the JavaSEPort project using the Add Project\nbutton and then use the Move Up button to make sure it is at the top most position since it needs to override everything else at runtime.\nYou are now good to go, now you can just place breakpoints within Codename One source code, edit it\nand test it. You can step into it with the debugger which can save you a lot of time when tracking a problem.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMaaike Z — May 22, 2015 at 6:45 pm (permalink) Maaike Z says:\nFor people who also use this post regularly and wonder how to do it in the new situation, you should read this blog post: http://www.codenameone.com/…\nDon’t forget to add the demos (not necessary), skins and binaries in the root of the project and to execute build_skins.sh from codenameone-skins (maybe add this also in the developer guide?).\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/use-the-source/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/use-the-source/use-the-source-1.gif\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://www.valeriovalerio.org/?p=62\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/use-the-source/use-the-source-1.gif\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e**\u003cbr\u003e\nUpdate:\u003cbr\u003e\n**\u003cbr\u003e\nminor correction to the build process about the \u003ccode\u003ebuild.xml\u003c/code\u003e issue in the Codename One project.\u003c/p\u003e\n\u003cp\u003eTo me the biggest advantage in Codename One over pretty much any other mobile solution is that its realistically open source. Realistically means that even an average developer can dig into 90% of the Codename One source code, change it and contribute to it!\u003c/p\u003e\n\u003cp\u003eHowever, sadly most developers don’t even try and most of those who do focus only on the aspect of building for devices rather than the advantage of much easier debugging. By incorporating the Codename One sources you can instantly see the effect of changes we made in SVN without waiting for a plugin update. You can, debug into Codename One code which can help you pinpoint issues in your own code and also in resolving issues in ours!\u003c/p\u003e","title":"Use The Source"},{"content":"\nCodename One has supported multi-touch and effectively pinch to zoom events from the very first release. However, it wasn’t intuitive to write code that would handle pinch to zoom. We just committed new pinch callback events to component which effectively allows you to zoom in/out with gestures.\nEffectively if you are interested in handling pinch you would just override protected boolean pinch(float scale) and return true after handling the pinch operation. We did this to support our new\nImageViewer class\n(where you can see a working sample of pinch), the image viewer allows you to inspect, zoom and pan into an image. It also allows swiping between images if you have a set of images (using an image list model).\nNow to simulate the pinching we needed a simpler solution than just building for the device, which is why we added right click dragging. Now when you drag using the right mouse button (or by pressing 2 fingers on a Mac laptop and dragging together) you will get a pinch effect. We do this by hardcoding the second finger at position 0,0. So effectively if you drag towards the top left corner you will be zooming out (fingers closer together) and by dragging away you will be zooming in.\nHere is a simple example of using the ImageViewer:\nNotice that we use a list to allow swiping between images (unnecessary if you have only one image), we also create a placeholder image to show while the image is still loading. Notice that encoded images aren’t always fully loaded and so when you swipe if the images are really large you might see delays!\nThis leads me to one of the more important aspects here: image locking.\n**\nImage Locking\n**\nOnce of the big performance improvements we got in swiping was through image locking, unfortunately this is so unclear in our current docs that when Nokia forked LWUIT they actually removed the usage of EncodedImage instead of fixing a minor locking bug.\nTo understand locking we first need to understand EncodedImage. EncodedImage stores the data of the image in RAM (png or JPEG data) which is normally pretty small, unlike the full decoded image which can take up to width X height X 4. When a user tries to draw an encoded image we check a WeakReference cache and if the image is cached then we show it otherwise w\ne load the image, cache it then draw.\nNaturally loading the image is more expensive so we want the images that are showing to stay in cache (otherwise GC will thrash a lot).\nThat’s where lock() kicks in, we automatically invoke image loading when necessary but when lock() is active we keep a hard reference to the actual native image so it won’t get GC’d.\nThis REALLY\nimproves performance!\nInternally we invoke this automatically for bg images, icons etc. which results in a huge performance boost. However, if you use a complex renderer or custom drawing UI you should lock() your images where possible!\n**\nGenerics Update\n**\nYou might have noticed from the code above that the list model is now generified, the same is also true now for the list renderer and list. We are working on modernizing as much of our code as we can while maintaining backwards compatibility.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — August 12, 2013 at 8:28 am (permalink) Anonymous says:\nThis is one of missing APIs,what I am waiting for. Great!!\nMahmoud — April 3, 2016 at 7:35 am (permalink) Mahmoud says:\ndear shai\ni have dynamic list in ImageViewer( images from url)\ni want to swipe images not on touch only but in pressing button too (swiping left and right)\nhow can i do it\nthanks,\nShai Almog — April 4, 2016 at 2:30 am (permalink) Shai Almog says:\nHi,\nthere is a code sample within the JavaDocs that covers just that use case: https://www.codenameone.com…\nIt’s also included in the developer guide section of the ImageViewer:\nhttps://www.codenameone.com…\nMahmoud — April 5, 2016 at 8:11 am (permalink) Mahmoud says:\nhi Shai,\nthank you …\ni use setSelectedIndex method in ImageList\nint myNewIndex=myImageViewer.getImageList().getSelectedIndex()(+1 or -1); to swiping left and right\nand\nmyImageViewer.getImageList().setSelectedIndex(myNewIndex);\nBR,\nMahmoud — June 25, 2016 at 1:24 am (permalink) Mahmoud says:\ndear shai,\ni have ImageViewer the image size 800X400\nwhen i run my app on small device the image looks like attached image (there’s a space on top and bottom of image )\nany idea please\nShai Almog — June 25, 2016 at 5:56 am (permalink) Shai Almog says:\nImages default to \u0026ldquo;scale to fit\u0026rdquo; in the image viewer.\nMahmoud — June 25, 2016 at 11:05 pm (permalink) Mahmoud says:\nok how i can change it\nShai Almog — June 26, 2016 at 4:48 am (permalink) Shai Almog says:\nYou can change the zoom level, but are you trying to show a static image or allow the user to change that? If the former then image viewer is the wrong component to use.\nMahmoud — June 26, 2016 at 7:13 am (permalink) Mahmoud says:\ndynamic list in ImageViewer( images from url) i show it as slider\nShai Almog — June 27, 2016 at 3:06 am (permalink) Shai Almog says:\nSo if you have multiple images in the viewer and flip between them zooming in will be a mistake.\nThis can create an image whose edges are wider than the screen so when you try to swipe you will really pan within the image…\nYou can replicate that behavior by zooming in with pinch and trying to swipe to see what I mean.\nMahmoud — July 1, 2016 at 4:09 pm (permalink) Mahmoud says:\ni have list of images not multi-images and i have Image Viewer\nif you understand what i mean , is any way to create slider images without space on top and bottom of image in small device\nthanks a lot\nShai Almog — July 2, 2016 at 4:29 am (permalink) Shai Almog says:\nIf I understand correctly you want to do something similar to the phone picture gallery where you swipe between the photos you took.\nIf you look at that native OS UI you will notice space above or on the sides to keep the aspect ratio of the image in place as you swipe. If you are speaking of a different UI/UX I’ll need a reference.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/in-a-pinch/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/in-a-pinch/in-a-pinch-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/in-a-pinch/in-a-pinch-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One has supported multi-touch and effectively pinch to zoom events from the very first release. However, it wasn’t intuitive to write code that would handle pinch to zoom. We just committed new pinch callback events to component which effectively allows you to zoom in/out with gestures.\u003c/p\u003e\n\u003cp\u003eEffectively if you are interested in handling pinch you would just override \u003ccode\u003eprotected boolean pinch(float scale)\u003c/code\u003e and return true after handling the pinch operation. We did this to support our new\u003cbr\u003e\n\u003ca href=\"http://code.google.com/p/codenameone/source/browse/trunk/CodenameOne/src/com/codename1/components/ImageViewer.java\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nImageViewer class\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n(where you can see a working sample of pinch), the image viewer allows you to inspect, zoom and pan into an image. It also allows swiping between images if you have a set of images (using an image list model).\u003c/p\u003e","title":"In A Pinch"},{"content":"\nRecently the guys from Software Developer Journal contacted us about writing a\nmobile gaming article\n, since quite a few Codename One developers use it to write games we decided to accept the offer and I wrote an article titled: \u0026ldquo;Writing casual games In Java for mobile devices\u0026rdquo;. In this article we create a simple poker game mockup that is fully functional (although it doesn’t include betting, AI or networking), but you can drag the cards to have them replaced and click the deck to deal new cards.\nThe game took 270 lines of code (including imports,\nits a bit larger now since I commented the code quite a bit\n), it took me roughly 2 hours to write that code.\nThe issue will be published in the 19th of August but you can\npreorder it here\n. If there is major interest in this I can expand the demo a bit more to include additional features.\nAs a teaser I took a very unique approach to writing the game, rather than use graphics I used components and leveraged the resolution independence of Codename One as much as possible.\nBTW I understand that a\nYaniv Nitzan of SOOMLA\nwho wrote a\npopular guest post\nhere will also be\nfeatured in this issue\n.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — March 13, 2015 at 7:05 am (permalink) Anonymous says:\nWow, CN1 is becoming more and more versatile all the time! I’d be curious to know if you had to bend some parts in unexpected ways to make this work…any new animations? a new layout manager? I don’t suppose so since you mentioned it took only a handful of lines of code… After trying the \u0026ldquo;components\u0026rdquo; approach instead of directly painting stuff yourself, is this something you would recommend for other casual games? This could open up a whole new family of CN1 apps!\nGood job Shai!\nAnonymous — March 13, 2015 at 7:05 am (permalink) Anonymous says:\nThanks.\nNot really. I did make one small change that all game developers using Codename One asked: I added the ability to open a resource file based on a specific DPI. This is useful in overriding the default Codename One behavior for DPI. For game development you expect tablets to act somewhat differently.\nAll the logic is standard Codename One animations and action listeners. The dragging is just the builtin drag and drop support and the layouts are just border layout, layered layout, grid layout and BoxLayout X. Nothing unique.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/you-can-bet-on-it/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/you-can-bet-on-it/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eRecently the guys from Software Developer Journal contacted us about writing a\u003cbr\u003e\n\u003ca href=\"http://sdjournal.org/game-development-how-to-become-a-millionaire-preorder/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nmobile gaming article\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, since quite a few Codename One developers use it to write games we decided to accept the offer and I wrote an article titled: \u0026ldquo;Writing casual games In Java for mobile devices\u0026rdquo;. In this article we create a simple poker game mockup that is fully functional (although it doesn’t include betting, AI or networking), but you can drag the cards to have them replaced and click the deck to deal new cards.\u003c/p\u003e","title":"You Can Bet On It"},{"content":"\nWe got a\nrequest from one of our pro-subscribers\nto support push notification on Blackberry devices. Normally we just implement the feature pro-developers ask for. However, in this case we were cautious… Building anything for/on top of a Blackberry device is often an exercise in futility.\nThe gist of it though is that we were able to get it working despite the huge hassles. The main issue here isn’t the lack of documentation, its the over abundance of irrelevant, conflicting and misleading documents about a multitude of separate features of push related functionality on Blackberry devices.\nSo we decided to use this chance to go over the whole process of creating a push application for iOS, Android \u0026amp; RIM.\nFirst there are several prerequisites you will need in order to get started with push:\nAndroid – you can find the full instructions from Google\nhere\n. You will need a project id that looks something like this:\n4815162342.\nYou will also need the server key which looks something like this: AIzaSyATSw_rGeKnzKWULMGEk7MDfEjRxJ1ybqo.\niOS – You will need to create a provisioning profile that doesn’t have the * element within it. For that provisioning profile you will need to enable push and download a push certificate. Notice that this push certificate should be converted to a P12 file in the same manner we used in the signing tutorials. You will need the password for that P12 file as well. You will need a distribution P12 and a testing P12. Warning! The P12 for push is completely different from the one used to build your application, don’t confuse them! You will need to place the certificate on the web so our push server can access them, we often use dropbox to store our certificates for push.\nBlackberry – you need to register with Blackberry for credentials to use their push servers\nhere\n. Notice that initially you need to register for evaluation and later on move your app to production. This registration will trigger an email which you will receive that will contain all the information you will need later on. Such as your app ID, push URL (which during development is composed from your app ID), special password and client port number. To start using push (on any platform) you will need to implement the PushCallback interface within your main class. The methods in that interface will be invoked when a push message arrives.:\nYou will then need to register to receive push notifications (its OK to call register every time the app loads) by invoking this code below (notice that the google project id needs to be passed to registration):\nSending the push is a more elaborate affair, we need to pass the elements to the push that are necessary for the various device types depending on the target device. If we send null as the destination device our message will be sent to all devices running our app. However, if we use the device key which you can get via Push.getDeviceKey() you can target the device directly. Notice that the device key is not the argument passed to the registration confirmation callback!\nOther than that we need to send various arguments whether this is a production push (valid for iOS where there is a strict separation between the debug and the production push builds) as well as the variables discussed above.\nUnfortunately we aren’t done yet!\nWe must define the following build arguments in the project\nproperties:\nios.includePush=true\nrim.includePush=true\nrim.ignor_legacy=true\nrim.pushPort=…\nrim.pushAppId=…\nrim.pushBpsURL=…\nOnce you define\nall of these push should work for all platforms.\nWe hope this small guide has made the development of a push enabled application a bit simpler.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — July 29, 2013 at 11:12 am (permalink) Anonymous says:\nIs this for premium subscribers only?\nAnonymous — July 29, 2013 at 1:52 pm (permalink) Anonymous says:\nYes, I neglected to mention in the article that push is for pro users only.\nAnonymous — August 20, 2013 at 3:45 pm (permalink) Anonymous says:\nIt was mentioned earlier that CN1 uses/used Urban Airship for push. Urban Airship supports tags to send to a subset of users. Will CN1 support tags in the future?\nAnonymous — August 21, 2013 at 3:23 am (permalink) Anonymous says:\nWe do not use Urban Airship at this time. We allow you to send a push to a specific device but we don’t have their level of refined targeting.\nWe don’t currently have any plans on supporting this or Urban Airship however, our plans are fluid and depend on the requirements of our pro/enterprise account subscribers.\nAnonymous — August 28, 2013 at 5:27 pm (permalink) Anonymous says:\nAt first I had trouble adding the build arguments properly (ie. ios.includePush=true)\nAnyone following the instructions above might find this helpful to get them added in the proper way:\nhttp://www.codenameone.com/…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/pushing-it/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/pushing-it/pushing-it-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Push Demo\" loading=\"lazy\" src=\"/blog/pushing-it/pushing-it-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe got a\u003cbr\u003e\n\u003ca href=\"http://code.google.com/p/codenameone/issues/detail?id=799\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nrequest from one of our pro-subscribers\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nto support push notification on Blackberry devices. Normally we just implement the feature pro-developers ask for. However, in this case we were cautious… Building anything for/on top of a Blackberry device is often an exercise in futility.\u003c/p\u003e\n\u003cp\u003eThe gist of it though is that we were able to get it working despite the huge hassles. The main issue here isn’t the lack of documentation, its the over abundance of irrelevant, conflicting and misleading documents about a multitude of separate features of push related functionality on Blackberry devices.\u003c/p\u003e","title":"Pushing It"},{"content":"\nWhen you have so many features as Codename One has things sometimes slip, a feature gets lost and even the guys who created it forget it was there. There are two such stories in this post one dates back to the very start of Codename One….\nBut first lets start with the other one. A month or so ago we added a component called SpanButton which has been requested by developers for quite a while. This is effectively a button that can break lines like a text area, its really a Lead Component internally (but that’s another post).\nHowever, someone (me) forgot to make the class public before committing and we just didn’t notice that.\nI\nn the release\nwe made today the class is both public and it is also in the designer tool so you can just drag it into place just like any other button.\nIt has features and behaviors similar to MultiButton since it too is a lead component based composite.\n**\nCachedDataService\n**\nThe CachedDataService is one of those services we added ages ago because we thought its important to have, then completely forgot about it. As it happens we forgot to write about it and so no one really used it to any extent (since it didn’t work). These past two weeks a developer on the forum (Fabrice Kabongo) drew my attention to the fact that this class doesn’t work and also provided helpful suggestions for fixes, I wrote it yet didn’t even recall its purpose.\nThis is a shame since the class is actually pretty useful and its possible we should update our internal code to use it E.g. say you have an image stored locally as\nimage X. Normally the ImageDownloadService will never check for update if it has a local cache of the image. This isn’t a bad thing, its pretty efficient.\nHowever, it might be important to update the image if it changed but you don’t want to fetch the whole thing…\nThe cached data service will fetch data if it isn’t cached locally and cache it. When you \u0026ldquo;refresh\u0026rdquo; it will send a special HTTP request that will only send back the data if it has been updated since the last refresh.\nImage copyright: Inspiration in a box\n**\nUsing Helvetica on iOS\n**\nChen was dealing with some designers this week and was facing requirements to incorporate Helvetica derivatives into an iOS application. Normally we allow developers to just embed a\nTTF into the application\nand it \u0026ldquo;just works\u0026rdquo; but Helvetica is builtin to iOS and shouldn’t be used on other platforms (due to copyrights). So how do you use a font such as HelveticaNeue?\nSimple: Font helveticaNeue = Font.createTrueTypeFont(\u0026quot;HelveticaNeue\u0026quot;, null);\nThis will \u0026ldquo;just work\u0026rdquo; even though the TTF file name is null it will just search the system. Notice that it will crash if the font doesn’t exist so use it carefully!\nTo get a specific size in pixels e.g. 14p just go with: Font fontNeue14 = helveticaNeue.derive(14, Font.STYLE_PLAIN);\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — July 25, 2013 at 9:49 am (permalink) Anonymous says:\nThanks guys. I was thinking of how to implement that in an upcoming project. 🙂\nAnonymous — July 25, 2013 at 10:43 am (permalink) Anonymous says:\nI was wondering how CachedData was supposed to work, now I will give it a shot.\nAbout the TT fonts, I believe it is possible to add this support to j2me/BB devices, at least I was able to do some basic rendering without anti-aliasing\nAnonymous — July 25, 2013 at 2:36 pm (permalink) Anonymous says:\nTTF files are supported on RIM. On J2ME they can’t be supported though. We have bitmap font support for J2ME devices but we don’t recommend using it.\nAnonymous — July 25, 2013 at 3:59 pm (permalink) Anonymous says:\nNice to know RIM supports TTF, about J2ME I do believe it can support TTF, and it would replace the bitmap font for sure.\nAnonymous — September 10, 2014 at 6:28 pm (permalink) Anonymous says:\nThe example code shown above for CacheDataService has a bug (aside from the second related bug that prevents it from even compiling).\nThe actionPerformed method body shown is trying to re-save the old CachedData object, not the new one with the updated data ( d does not get updated in-place inside CachedDataService.updateData ). The updated value is sent in the ActionEvent to the ActionListener).\nThe actionPerformed method body should be something like this instead:\nNetworkEvent ne = (NetworkEvent)ev;\nCachedData newCachedData = (CachedData)ne.getMetaData();\nStorage.getInstance().writeObject(\u0026ldquo;LocallyCachedData\u0026rdquo;, newCachedData);\nAnonymous — September 11, 2014 at 1:43 am (permalink) Anonymous says:\nThanks 😉\nAnonymous — November 6, 2014 at 6:46 am (permalink) Anonymous says:\nI have created one bitmap to change the font style and the create LabelFont and add the font .\nThe LabelFont uiid is used in Label and test on emulator , the new font is displayed but the font is not displayed in Mobile and tablet , why?\nAnonymous — November 6, 2014 at 3:27 pm (permalink) Anonymous says:\nDo you mean bitmap font?\nWhich font are you using?\nAnonymous — November 7, 2014 at 3:47 am (permalink) Anonymous says:\nyes its bitmap font\nAnd I am using these magneto monospaced fonts but the font is shown in emulator but not the font is not displayed in mobile and tablet\nAnonymous — November 8, 2014 at 12:15 pm (permalink) Anonymous says:\nDon’t use bitmap fonts, we deprecated those. Use TTF fonts.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/spanning-caching-native-fonts-and-more/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/spanning-caching-native-fonts-and-more/spanning-caching-native-fonts-and-more-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/spanning-caching-native-fonts-and-more-large-3.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/spanning-caching-native-fonts-and-more/spanning-caching-native-fonts-and-more-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eWhen you have so many features as Codename One has things sometimes slip, a feature gets lost and even the guys who created it forget it was there. There are two such stories in this post one dates back to the very start of Codename One….\u003c/p\u003e\n\u003cp\u003eBut first lets start with the other one. A month or so ago we added a component called SpanButton which has been requested by developers for quite a while. This is effectively a button that can break lines like a text area, its really a Lead Component internally (but that’s another post).\u003c/p\u003e","title":"Spanning, Caching, Native Fonts and more"},{"content":"\nDon’t change the classpath\nSupport for JAR files in Codename One has been a source of confusion despite\nmy previous post on the matter\nso its probably a good idea to revisit this subject again and clarify all the details.\nThe first source of confusion is changing the classpath. You should\n**\nNEVER\n**\nchange\nthe classpath or add an external JAR via the NetBeans/Eclipse 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.).\nThere are two use cases for wanting JAR’s and they both have very different solutions:\nModularity – you want to divide your work to an external group. For this purpose use the cn1lib approach.\nWork with an existing JAR. For this you will need native interfaces.\n**\nCN1Lib’s\n**\nLets start with modularity since its simpler and you can pretty much read\nmy previous post on the matter\nwhich covers it pretty accurately.\nYou can create a cn1lib in NetBeans although its really just a simple ant project with some special targets and a simple ant task for stubbing. In it you can write all your source code (including native code and libs as described below), when you build the file you will get a cn1lib file that you can place in your projects lib directory.\nAfter a right click and refresh project libs completion will be available for you and you will be able to work as if the code was a part of your project.\n**\n**\n**\nNative JAR’s/Libs\n**\nFor the second use case of existing JAR’s we have a more complex situation, the JAR could depend on features unavailable in Codename One and even if it doesn’t it might be compiled in a way that isn’t supported by Codename One.\nSo taking an arbitrary JAR off the internet and expecting it to work on a mobile device is something that will probably never happen for any platform.\nAndroid supports using JAR’s since it is based around the java language\n, some JAR’s might even work on J2ME/RIM. To make use of this capability we can just place the JAR’s as is under the native/android directory (and respectively for J2ME/RIM). The way to go for iOS support would be to use .a files (iOS static libraries) which will get linked with your app in the same way that the JAR’s get linked.\nThe problem is that you still won’t be able to use the JAR (or .a file) from\nwithin your code, this JAR would be platform specific and you would need to write the \u0026ldquo;bridging\u0026rdquo; code to connect it to the native layer. To learn more about native interfaces I suggest reading the developer guide but basically what you need to do is define a native interface e.g.:\nHere you can define the interface between your application (which can’t directly access the jar or .a file) and the native code which can. Now you can right click the interface select: Generate Native Access and go the native directory where you can edit the native code.\nNotice that the jar will not appear in your IDE’s code completion and the code might be marked as \u0026ldquo;red\u0026rdquo; with error messages. That is because we can’t compile that code on the client, only on the server since we don’t have the native Android/iOS SDK’s installed on your PC or Mac (and even if we did, integrating so many difference pieces of software is problematic).\n**\nFinal words\n**\nSupporting\nan arbitrary JAR off the internet is something no one will ever be able to fully deliver on, although we do hope the cn1lib format will take off since it is pretty open and has many advantages over the standard jar format (proper javadoc based code completion is HUGE).\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — October 6, 2014 at 10:32 am (permalink) Anonymous says:\nHello. Sorry for noob question, but I not fully understand, Codename1 supported JNI libraries? I have Android project with few JNI dependencies (source code – C/C++) and would be great to port this project to WinPhone/Blackberry, but I don’t understand is this real with Codename1?\nAnonymous — October 7, 2014 at 3:17 am (permalink) Anonymous says:\nJNI makes sense on Android where you call from Java to C you can use JNI in the Android port by wrapping in an andlib. In iOS we support an Objective-C bridge not JNI so you can invoke your C code from objective-c. Blackberry has no ability to define native C code, in Windows Phone we support C# not C but you might be able to do something with unsafe although I haven’t tried this.\nAnonymous — October 16, 2014 at 11:42 am (permalink) Anonymous says:\n\u0026ldquo;Supporting an arbitrary JAR off the internet is something no one will ever be able to fully deliver on\u0026rdquo;\nI’m very skeptical about this claim after working with robovm, almost 99.99% of the time the arbitrary jar libraries that I downloaded from the internet and used worked out of the box.\nAnonymous — October 16, 2014 at 10:33 pm (permalink) Anonymous says:\nBesides the obvious problems of huge size and other problems generated in that approach there is a much bigger problem. JDK IS HUGE, we had a rooms full of QA engineers running TCK’s on our JVM ports which were CLDC grade at Sun, tonnes of tests for a WAY smaller API. OSS doesn’t test at that level.\nThis isn’t some theoretical debate. java.io.File is problematic since the iOS filesystem structure is very limited on iOS. Sockets (hence the entire network stack) can’t be implemented correctly in iOS. It will work for you in the testing environment but when you see disconnects in the field know that there is a reason for that.\nThis can be OK for some games to hack something together, but its not an option if you need something to be forward compatible and warranted.\nAnonymous — October 18, 2014 at 7:19 am (permalink) Anonymous says:\nthe java.lang., java.util., etc in robovm are based on Android’s runtime, they don’t suffer from the size problems as in Java SE but still allows a lot of flexibility regarding the usage of third party libraries. I hope codenameone could learn something from robovm’s approach in using Java for IOS developement\nAnonymous — October 18, 2014 at 8:54 am (permalink) Anonymous says:\nAndroid VM is just as big as JavaSE. In an Android device it takes up that space ONCE for all the apps. On iOS you need to package it with the app so its HUGE.\nI’ve spoken at length with Niklas at the last JavaOne and briefly in this one (we were both quite busy). I like him, hes very smart and a nice guy to boot. Unfortunately I think he picked a wrong and remarkably risky approach for building iOS apps.\nTo understand why you need to understand that:\nworks for me right now != works for all use cases always\nAnonymous — October 24, 2014 at 4:07 am (permalink) Anonymous says:\nThanks for your replies,\npackaging a run-time for each and every app is a bad idea. I agree.\na better approach would be to have some sort of a separate \u0026ldquo;run-time app\u0026rdquo; that manages all the java apps.\nan analogy to this could be the python run-time app in Symbian.\nAnonymous — October 24, 2014 at 10:02 am (permalink) Anonymous says:\nApple disallows that just like it disallows a JIT or downloadable code.\nBoth RoboVM and us take a very similar approach with the difference that we took a far more conservative route.\nAnonymous — November 24, 2014 at 6:16 pm (permalink) Anonymous says:\nI think i can use codename one for my project, but I wonder if It’ll support some complex libraries like Picasso or retrofit… and as there is no iOS alternative for those libraries what can i do about it. If not i may try it anyway for less complex projects. Thanks\nAnonymous — November 25, 2014 at 4:50 am (permalink) Anonymous says:\nBoth of these don’t make sense in Codename One since they are there to solve Android specific problems and use Android networking API’s (unavailable in Codename One).\nPicasso is redundant since we have URLImage which is even more seamless in its image handling builtin to the system e.g. http://www.codenameone.com/…\nRetrofit is nice but if you have access to the server a more portable (and much faster) approach would be to use the webservice wizard http://www.codenameone.com/…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/jaring-and-libraries/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/jaring-and-libraries/jaring-and-libraries-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Classpath\" loading=\"lazy\" src=\"/blog/jaring-and-libraries/jaring-and-libraries-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eDon’t change the classpath\u003c/p\u003e\n\u003cp\u003eSupport for JAR files in Codename One has been a source of confusion despite\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/3/post/2013/02/new-preliminary-library-support.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nmy previous post on the matter\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nso its probably a good idea to revisit this subject again and clarify all the details.\u003c/p\u003e\n\u003cp\u003eThe first source of confusion is changing the classpath. You should\u003cbr\u003e\n**\u003cbr\u003e\nNEVER\u003cbr\u003e\n**\u003cbr\u003e\nchange\u003c/p\u003e\n\u003cp\u003ethe classpath or add an external JAR via the NetBeans/Eclipse 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. \u003ccode\u003ejava.io.File\u003c/code\u003e etc.).\u003c/p\u003e","title":"Jaring And Libraries"},{"content":"\n**\nNote:\n**\nwe decided to go in a different direction than the content of this blog post. We will make a new post with further details when we complete the new feature. Generally we found a way to allow deobfuscation of release binaries as well so you would be able to get a crash report on standard applications.\nIn an ideal world your app would work perfectly on the device just as it does on the simulator, however that ideal world never exists under any development environment. Performance is different and unfortunately you occasionally get crashes on the device that you don’t get on a simulator. The reasons for this are many and varied, usually a crash means we did something wrong, but sometimes it might mean an exception was thrown and never caught or an API was misused.\niOS allows you to extract crash logs from the device using itunes or xcode, this allows your beta testers to send you a log that allows you to gleam some information related to the cause of the crash. If you use Log.p() all your entries will appear in the device log (System.out will not appear). The log will also contain stacks indicating the thread stacks including the reason for the crash, this isn’t always helpful but sometimes can provide important clues as to what went wrong. Unfortunately for performance reasons XCode strips out the compiled binary and the stacks just contain memory addresses that provide very little indication applicable to your app.\nWe now have a feature for pro users allowing them to build an unstripped binary, we are limiting it to pro users since the size of the binary is double and the so is the time it takes to produce such a binary (its a server hog). This can be achieved using the ios.no_strip=true build argument which should allow logs to include symbol information in them by default.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/crashing/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/crashing/crashing-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/crashing/crashing-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e**\u003cbr\u003e\nNote:\u003cbr\u003e\n**\u003cbr\u003e\nwe decided to go in a different direction than the content of this blog post. We will make a new post with further details when we complete the new feature. Generally we found a way to allow deobfuscation of release binaries as well so you would be able to get a crash report on standard applications.\u003c/p\u003e\n\u003cp\u003eIn an ideal world your app would work perfectly on the device just as it does on the simulator, however that ideal world never exists under any development environment. Performance is different and unfortunately you occasionally get crashes on the device that you don’t get on a simulator. The reasons for this are many and varied, usually a crash means we did something wrong, but sometimes it might mean an exception was thrown and never caught or an API was misused.\u003c/p\u003e","title":"Crashing"},{"content":"\n**\nClarification update:\n**\nFor some reason people read this as a rebuttal of\nDrew Crawford\narticle,\n**\nit is not\n**\n. It is merely a response, I accept almost everything he said but have a slightly different interpretation on some of the points.\nOver the weekend quite a few people wrote to me about a\nwell researched article written by Drew Crawford\nwhere he gives some insights about why the mobile web/JavaScript is slow and will not (for the foreseeable future) compete with native code. My opinion of the article is mixed, it is well written and very well researched, I also agree with a few of the points but I think that despite getting some of the conclusions wrong I think his reasoning is inaccurate.\nBut first lets start with who I am (Shai Almog) and what I did, I wrote a lot of Java VM code when consulting for Sun Microsystems. I did this on mobile devices that had a fracti\non of the RAM/CPU available for today’s devices. Today I’m the co-founder of Codename One where I regularly write low level Android, iOS, RIM, Windows Phone etc. code to allow out platform to work everywhere seamlessly. So I have pretty decent qualification to discuss devices, their performance issues etc.\nLets start by the bottom line of my opinion:\nI think Drew didn’t cover the slowest and biggest problem in web technologies: the DOM.\nHis claims regarding GC/JIT are inaccurate.\n**\nSo why is JavaScript slow?\n**\nPeople refer to performance in many ways, but generally most of us think of performance in terms of UI sluggishness.\nIn fact JavaScript can’t technically perform slowly since it is for most intents and purposes single threaded (ignoring the joke that is web workers), so long running JavaScript code that will take 50 seconds just won’t happen (you will get constant browser warnings). Its all just UI stalls or what w\ne call \u0026ldquo;perceived performance\u0026rdquo;.\nPerceived performance is pretty hard to measure but its pretty easy to see why it sucks on web UI’s: DOM.\nTo understand this you need to understand how DOM works: every element within the page is a box whose size/flow can be determined via content manipulation and style manipulation. Normally this could be very efficient since the browser could potentially optimize the living hell out of rendering this data. However, JavaScript allows us to change DOM on the fly and actually requires that to create most UI’s. The problem is that \u0026ldquo;reflow\u0026rdquo; is a really difficult concept, when you have a small amount of data or simple layout the browsers amazing rendering engines can do wonders. However, when dependencies become complex and the JavaScript changes a root at a \u0026ldquo;problematic\u0026rdquo; point it might trigger deep reflow calculations that can appear very slow. This gets worse since the logic is so deep in the browser and its performance overhead you can end up with a performance penalty that’s browser specific and really hard to track.\nTo make matters worse, many small things such as complex repeat patterns, translucency layers etc. make optimizing/benchmarking such UI’s really difficult.\nWhy Java Is Fast \u0026amp; Objective-C Is Slow The rest of the article talks a lot about native code and how fast it is, unfortunately it ignores some basic facts that are pretty important while repeating some things that aren’t quite accurate.\nThe first thing people need to understand about Objective-C: it isn’t C.\nC is fast, pretty much as fast as could be when done right.\nObjective-C doesn’t use methods like Java/C++/C#, it uses messages like Smalltalk. This effectively means it always performs dynamic binding and invoking a message is REALLY slow in Objective-C. At least two times slower than statically compiled Java.\nA JIT can (and does) produce faster method invocations\nthan a static compiler since it can perform dynamic binding and even virtual method inlining e.g. removing a setter/getter overhead! Mobile JITs are usually simpler than desktop JITs but they can still do a lot of these optimizations.\nWe used to do some pretty amazing things with Java VMs on devices that had less than 1mb of RAM in some cases, you can check out the rather\nold blog from Mark Lam\nabout some of the things Sun used to do here.\n**\nBut iPhone is faster than Android?\n**\nIs it?\niPhone has better perceived performance. Apps seem to launch instantly since they have hardcoded splash images (impractical for Android which has too many flavors and screen sizes). The animations in iOS are amazingly smooth (although Android with project butter is pretty much there too), these aren’t written in Objective-C… All the heavy lifting animations you see in iOS are performed on the GPU using CoreAnimation, Objective-C is only a thin API on top of that.\nGetting back to the point though\nhe is 100% right about JavaScript not being a good language to optimize, it doesn’t handle typing strictly which makes JITs far too complex. The verification process in Java is HUGELY important, once it has run the JIT can make a lot of assumptions and be very simple. Hence it can be smaller which means better utilization of the CPU cache, this is hugely important since bytecode is smaller than machine code in the case of Java.\nCPU cache utilization is one of the most important advantages of native code when it comes to raw performance. On the desktop the cache is already huge but on mobile its small and every cache miss costs precious CPU cycles. Even elaborate benchmarks usually sit comfortably within\na CPU cache, but a large/complex application that makes use of external modules is problematic. But I digress….\nProving that JavaScripts strictness is problematic is really easy all we need to do is look at\nthe work Mozilla did with ASM.js\nwhich brings JavaScript performance to a completely different place. Remove abilities from JavaScript and make it strict: it becomes fast.\n**\nAre GCs Expensive\n**\nYes they have a cost, no its not a big deal.\nARC is an Apple \u0026ldquo;workaround\u0026rdquo; for their awful GC.\nWriting a GC is painful for a language like Objective-C which inherits the \u0026ldquo;problematic\u0026rdquo; structure of C pointers (pointer arithmetic’s and\nmemory manipulation) and adds to it plenty of complexities of its own. I’m not saying a GC is trivial in a managed language like Java but it is a panacea by comparison.\nThe problem with GC is in its unpredictable nature. A gc might suddenly \u0026ldquo;decide\u0026rdquo; it needs to stop the world and literally trash your framerate, this is problematic for games and smooth UI’s. However, there is a very simple solution: Don’t allocate when you need fast performance. This is good practice regardless of whether you are using a GC since allocation/deallocation of memory are slow operations (in fact game programmers NEVER allocate during game level execution).\nThis isn’t really hard, you just make sure that while you are performing an animation or within a game level you don’t make any allocations. The GC is unlikely to kick in and your performance will be predictable and fast. ARC on the other hand doesn’t allow you to do that since ARC instantly deallocates an object you finished working with (just to clarify: reference counting is used and instantly means when the ref count reaches 0). While its faster than a full GC cycle or manual reference counting its still pretty slow\n. So yet you can hand code faster memory management code in C and get better performance in that way, however for very complex applications (and UI is pretty complex not to mention the management of native peers) you will end up with crashes. To avoid your crashes you add checks and safeties which go against the basic performance penalties you are trying to counter.\nFurthermore, good JITs can detect various pattens such as allocations that are tied together and unify the memory allocation/deallocation. They can also reallocate elements into the stack frame rather than heap when they detect specific allocation usage. Unfortunately, while some of these allocation patterns were discussed by teams when I was at Sun I don’t know if these were actually implemented (mostly because Sun focused on server GCs/JITs that have a very different type of requirements).\nThe article also mentions desktop GCs being optimized for larger heap spaces and\na study from 2005\nthat \u0026ldquo;proves it\u0026rdquo;. This is true for desktop GCs but isn’t true for mobile GCs, e.g. Monty (Sun’s VM) had the ability to GC the actual compiled machine code. So effectively if your app was JITed and took too much space in RAM for an execution path you no longer use much, Monty could just collect that memory (the desktop JIT to my knowledge was never this aggressive).\nA proper GC optimized for mobile devices and smaller heap overhead will be slower than some of the better desktop GCs but it can actually reduce memory usage compared to native code (by removing unused code paths). Just so we can talk scales, our code performed really well on a 2mb 240×320 Nokia device and weaker devices than that. It ran smoothly animations and everything, including GC.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — July 15, 2013 at 10:22 am (permalink) Anonymous says:\nNote that the title of this post is not proper English.\nAnonymous — July 15, 2013 at 11:19 am (permalink) Anonymous says:\nThe number one thing I’m seeing here is that you have absolutely no data to back you up whatsoever. For example,\n\u0026ldquo;A JIT can (and does) produce faster method invocations than a static compiler since it can perform dynamic binding and even virtual method inlining e.g. removing a setter/getter overhead!\u0026rdquo;\nNice theory. Here’s another theory. Since JITs have to run side by side with the application, and every cycle a JIT spends optimizing, the application can’t spend executing, a JIT can never match a static compiler. Not to mention, congratulations on inlining your shitty unnecessary getters and setters- in other languages, they wouldn’t be written in the first place.\nProve me wrong- but since you present absolutely no evidence for anything you’ve said, then I’m not really feeling the pressure here.\nAnonymous — July 15, 2013 at 11:27 am (permalink) Anonymous says:\nYour unconditional statements are simply incorrect\n\u0026ldquo;in fact game programmers NEVER allocate during game level execution\u0026rdquo;\nThat’s simply not true. Complicated games might use pooling memory managers, but from the point of actual code, it’s freeing and allocating data allright. On some operating systems using pooling memory might just not be needed for a fast execution, because normal allocators can cope with the task.\n\u0026ldquo;So yet you can hand code faster memory management code in C and get better performance in that way, however for very complex applications (…) you will end up with crashes. To avoid your crashes you add checks and safeties which go against the basic performance penalties you are trying to counter.\u0026rdquo;\nYou are assuming the only ways to use manage memory is either raw C or fully GCed Java. How exactly is \u0026ldquo;pretty slow\u0026rdquo; for ARC we’re talking about? You seem to forget that deterministic destruction does exactly mean we can destruct when it’s convenient, not when the GC chooses so. As for crashes, I think you simply lack knowledge about alternatives to the extreme ends of the scale.\nAnonymous — July 15, 2013 at 11:30 am (permalink) Anonymous says:\nFair enough, I was far more lazy than Drew and just pulled out of my experience rather than worked 😉\nYou can google project monty and read some of the stuff that came out from Sun regarding mobile JIT’s http://www.slideshare.net/C…\nYou can also pick up an Asha device and play with it a bit after reading its CPU/RAM spec… Its no iPhone, but with those specs its pretty amazing.\nIn objective C you use properties which map to… getters/setters and the same applies for all property types.\nJIT’s do have an overhead, however since every application spends most of its time doing nothing there is plenty of time for a JIT to optimize. Unless a JIT is a caching JIT you will notice some overhead on startup (unless its a caching JIT).\nNotice that I don’t think this can be \u0026ldquo;proved\u0026rdquo;, perceived performance is too difficult to measure properly and the JIT overhead is a flaky hard to measure property. I would prefer that people understand the difference between \u0026ldquo;soft facts\u0026rdquo; and \u0026ldquo;hard facts\u0026rdquo; e.g. JavaScript as it is now is hard to optimize is a hard fact. JIT/GC’s are inherently slow is debateable (and I take the position that they are not).\nAnonymous — July 15, 2013 at 11:38 am (permalink) Anonymous says:\nNever might have been a strong word, but I think we generally agree.\nI pulled that out of my experience working for EA’s Janes franchise in the 90’s (that was C++ code) and with newer mobile game developers today. If you have a rendering intensive operation you want every bit of CPU. Allocators and deallocators are slow and generate memory fragmentation which requires compacting.\nTrue ARC is more predictable in terms of performance, I specifically made a point of mentioning how a GC cycle can crash framerate even for a fast GC.\nMy point is that you can use GC and get both decent performance without a major memory overhead increase. Yes you would need to be aware of memory management, but you need to be even more aware of that when using ARC.\nAnonymous — July 15, 2013 at 11:51 am (permalink) Anonymous says:\nARC does not \u0026ldquo;Immediately dealloc\u0026rdquo; the object unless you specifically gave it a weak (Auto zeroing) reference. A strong referenced object will be held onto until you zero it out yourself so if there’s a specifc reason not to dealloc an object while you’re executing then just don’t until you’re done doing whatever Uber important process. Now this is almost never an issue however I bring it up in reply to your equally unlikely case of specific object dealloc actually slowing something down. Also lets keep in mind you can jump in and out of C at any time so if you have some really low level stuff just write it in C, use the correct tool for the Job OR .. Why we don’t use JS to do jobs that C should be used for and don’t use C to do jobs JS should be used for. Got it? Kthx Bye.\nAnonymous — July 15, 2013 at 11:56 am (permalink) Anonymous says:\nWhere did I imply that ARC immediately deallocates? If I did so I need to fix that.\nI specifically discussed the approach of going into C where I covered the iOS performance explaining why core animation is so fast.\nDeallocating is a slow operation in any language, its slow in C. Its slower in C++ (destructors) and slower yet in Objective-C. Arc also adds the overhead of reference counting pools (which isn’t big but its there).\nGC arguably has a bigger overhead and is less predictable than ARC, I never denied that.\nAnonymous — July 15, 2013 at 11:56 am (permalink) Anonymous says:\nSo, your response to a very well researched and documented post is to post your gut feeling, and then argue that the reader should be doing the research to back up your claim? Show us the numbers. And it is nonsense to say that it can’t be measured properly. Of course it can. Maybe you can’t. More likely you just haven’t. Which is fair, but it does mean that this post is just empty words.\nAnonymous — July 15, 2013 at 12:05 pm (permalink) Anonymous says:\n@jalf I don’t see the animosity here?\nI started by explaining that I write an opinion out of my personal experience of writing VM’s for Sun Microsystems. I don’t need to research the field in which I have been coding for the past 14 years (this specific field I have been coding MUCH longer than that).\nWhich statement specifically do you have an issue with? I don’t think a single statement outright contradicted a fact claimed in Drew’s article other than the GC paper which is pretty flawed for the mobile use case (it measured desktop VM’s you can’t take that into mobile).\nIf you think JIT’s have an overhead (which is a claim I didn’t see in Drew’s article) you are correct, that’s a fact. Is it a big deal?\nThat depends.\nI linked to Mark’s article in the blog where he provides some deeper technical assembly opcodes to back some of the claims of JIT overhead. What sort of proof are you looking for?\nAnonymous — July 15, 2013 at 1:11 pm (permalink) Anonymous says:\nThanks! Finally some deeper thought on Drew’s article. I think the major problem is that Drew pulls out a lot of references and citations, but I don’t necessarily think they back up his claims fully since they apply for different situations.\nIn my experience, C-style languages are hard to beat, but it does require an extraordinary amount of time to get that code right and optimized. Usually, a GC will buy you some development speed and if you know what you are doing, it also takes some quite nitpicky tuning to get C to be more allocation efficient than a wel-written GC.\nAnd for the nonbelievers: Many malloc()/free() routines nowadays are multi-core aware and they do contain garbage-collection style tricks to speed them up. So even manual memory management uses some of the same tricks as state-of-the-art garbage collectors.\nAnonymous — July 15, 2013 at 1:50 pm (permalink) Anonymous says:\n\u0026ldquo;ARC on the other hand doesn’t allow you to do that since ARC instantly deallocates an object you finished working with.\u0026rdquo;\nAnonymous — July 15, 2013 at 3:09 pm (permalink) Anonymous says:\nArghhh, one doesn’t put an apostrophe with plural cases: GCs, JITs, VMs, etc.!!!!\nAnonymous — July 15, 2013 at 3:14 pm (permalink) Anonymous says:\nGreat follow-up article, Shai. I think the criticism you’re receiving by some commenters here isn’t really fair.\nI posted the following comment on Drew’s article, that I’m reposting here just because I think it supports what you’re trying to say here:\nI just want to offer an alternate take on the paper cited (http://www-cs.canisius.edu/…) regarding performance vs heap-size of garbage collectors.\nIf you focus on the \u0026ldquo;best\u0026rdquo; garbage collection algorithm they used in their experiments (GenMS) the performance hit is only about 1.75x with a heap size of twice the minimum required footprint. By the time you reach available memory of 3 to 4 times, the size, performance reaches about parity with manual memory management.\nGiven that this study was done in 2005, and assuming that GC architects are aware of these results, I think it is fair to assume that modern day garbage collectors will perform at least as well as the best algorithms in this study.\nTherefore, the conclusion that you need 6 times more memory available than your app requires in order to have good performance in a managed environment is an exaggeration. In reality you can probably achieve good results with less than twice the amount of memory.\nThis certainly seems like a reasonable trade-off in all cases except the most performance-critical applications.\nAnonymous — July 15, 2013 at 3:20 pm (permalink) Anonymous says:\nPerhaps the phrasing was wrong here, I didn’t want to get into the details of the reference counting algorithm and how it works internally.\nAnonymous — July 15, 2013 at 3:25 pm (permalink) Anonymous says:\nFinally a comment I can answer with \u0026ldquo;fixed that\u0026rdquo;.\nAnonymous — July 15, 2013 at 3:26 pm (permalink) Anonymous says:\nTerms like \u0026ldquo;perceived performance\u0026rdquo; and \u0026ldquo;speed\u0026rdquo; are too vague. Think: thoughput,latency and the jitter on them. Android does have at least one enormous problem relative to iOS, and it’s latency/jitter; which is really obvious when making real-time audio apps (ie: audio responds to finger movements within 5ms latency and jitter). Most of the Android devices I have used exhibit high latency in the user interface for everything, including the web browser. A lot of IOS apps use very little Objective-C and are mostly in C for the exact reasons you mentioned; to have the app stop doing alloc/free while the app runs (some places you have no control, like with touches coming in from the OS, etc). It’s really unfortunate that none of the popular operating systems are based on real-time operating systems, and none of the common languages are appropriate for making real-time applications; and actually kind of ironic given that mobile devices fit the profile of embeded devices doing signal processing (phone signals, accelerometers, audio, camera, etc).\nAnonymous — July 15, 2013 at 3:32 pm (permalink) Anonymous says:\nExactly, also high performance games in Android are mostly written in C. I’m not a huge Dalvik expert and as far as I understand they optimized for very different things (Sun engineers claimed Sun’s JIT’s were MUCH faster than Dalvik but I didn’t measure it myself).\nHowever, from my experience working with Android I’d bet this is more due to the shoddy work they did with media than anything else. They implemented the media in the native layer where you have to go back and forth from Dalvik to native for every little thing and those trips back and forth (and through threads) are just performance killers. Obviously this is a complete guess.\nAnonymous — July 15, 2013 at 3:32 pm (permalink) Anonymous says:\n\u0026ldquo;[…] congratulations on inlining your shitty unnecessary getters and setters- in other languages, they wouldn’t be written in the first place\u0026rdquo;\nIgnoring the tone of your post for second, are you saying that C++ for example does not have getters/setters ? Besides inlining in the JVM goes beyond getters and setters.\nOf course you forgot to mention that a JIT compiler has access to information about the actual HW it is running on (memory, CPU type \u0026amp; version, cache size, …) and program hotspots that a static compiler have no access to. But it would not fit your story …\nAnonymous — July 15, 2013 at 3:55 pm (permalink) Anonymous says:\nIn a this-tech-vs-that-tech debate, there is another variable only touched on in Drew’s article, which is the the programmer’s quality of execution of development itself. That could be limited by skill level or even by the rush of dealing with deadlines. Even though manual C-style memory management helps with writing a program that fits in a small memory profile, that really doesn’t matter if it only runs for 3 seconds before segfaulting. GC languages make it impossible at the lowest level to accidentally release an object that’s in use. I think Obj-C ARC deserves credit for narrowing the avoiding-stupid-mistakes gap to some degree, but it still can’t offer the guarantees that a GC’ed language can.\nThis is not theoretical for me, I’m actually writing a cross platform OpenGL/DirectX graphics intensive app using MonoGame and Xamarin’s cross platform C#. Using C# on an iOS game while keeping a high framerate means doing manual memory management. In that situation, the GC ironically isn’t really used for memory management for most of the program’s execution, but rather as just a a part of basic architectural protection from access violations. And it’s awesome.\nIn my opinion, this discussion really boils down to memory management, since (outside the DOM, as Shai noted) execution speed differences don’t add up to enough to matter for probably 99% of apps. If you’re writing heavy numerical calculations etc., then you’re probably invoking a native library for that part.\nThe goal is not to run out your project’s budget due to being a perfectionist: \u0026ldquo;real artists ship.\u0026rdquo;\nAnonymous — July 15, 2013 at 3:59 pm (permalink) Anonymous says:\nAgreed, the biggest factor in performance is developer skill.\nAnonymous — July 15, 2013 at 4:32 pm (permalink) Anonymous says:\nThe \u0026ldquo;Class 3\u0026rdquo; argument from scripting language people assumes that the hardware is underutilized – like a big desktop machine.\nIf each instruction expands into 10 for the sake of it being in FooScript, and you run it at 100% utilization on your desktop… then port it to C and it runs at 10% utilization…but they might complete in roughly the same time because the C code spends 90% of its time waiting on devices and network responses. And here it looks like there was no justification for porting it to C.\nBut if you assume that battery consumption is proportional to utilization, then it matters. If the demand spikes to 10x what it previously was, then the FooScript implementation can no longer keep up, queueing work at 10x the rate that it can do it. The FooScript app is already at 100% utilization and won’t go faster, running at 10% of the C implementation which is now also at 100% but keeping up.\nThis is what will happen when your have 10 cloud-based instances that would ran at 10% on separate VMs, and your cloud provider stuffs all 10 apps into one machine to reduce its own power consumption. (I think this a lot of why Google is pushing Go, btw.)\nPower consumption is proportional to the cube of clockspeed, from what I have read. That implies slowing down the cores as much as possible while having as many cores as possible.\nThen you have the phenomenon where 1 user request hits 100 servers in the background, and 99 of them come back in a few milliseconds, but 1 comes back in 1 second; which would cause the entire request to take 1 full second. Etc. You get to the point where real-time responses start to matter a lot on what seemed like a throughput oriented system when you started.\nDon’t get me wrong… C is a horrible language for writing applications in, because it’s so unsafe, and pointer aliasing blinds the compiler to the obvious. People raised on desktop systems see the answer in Python/Java/C#, etc. But they bring convenience while throwing all resource consumption guarantees out the window.\nBetween handling massive concurrency (to not bottleneck at any one core or resource), to the extra complexity in dealing with distributed computing… The current tools don’t resemble the problems we are dealing with now…. (… SIMD/Vector/GPU, co-routines, real-time deadlines, lock-free algorithms, message-passing, power reduction …). The underlying OS needs to be real-time to support any real-time applications. A lot of apps will need to be real-time. Most of them will need strong guarantees on resource consumption as well.\nAnonymous — July 15, 2013 at 4:34 pm (permalink) Anonymous says:\nRob,\nWhat really matters at the end is what is perceived by the user.\nAs far as I know the best Android devices are getting better – and cost as much as Apple ones -, though they don’t feel as fast as iOS ones, even \u0026ldquo;old\u0026rdquo; phones like iPhone 3GS or 4 (I have a 4 and even heavy games are pretty fast).\nThe problem would be the that most Android phones are in the cheap market, using old Android versions, with poor hardware. In that niche, maybe Firefox OS could do a better job.\nThat might not be the problem with Java itself, that always takes the blame, but the ecosystem it’s built. Also, for newer Android versions, it seems that even thought we still have a very fragmented market, which makes the devices not be as good as iOS ones, Google has done a lot of improvements.\nParticularly, I think we all benefit from free market and having more than one good device, but I stick with Apple for the moment [and it’s usability].\nAnonymous — July 15, 2013 at 4:39 pm (permalink) Anonymous says:\nWhile I agree with most of your points I think Java is ideal for mobile exactly for these reasons. Embedded systems (as phones are) are really hard to optimize for, by having a relatively high abstraction layer you allow the OS vendor a lot of leeway in performing such optimizations.\nIf you will read Marks posts which I linked in the article you will see that a lot of the cost in Java VM is actually very low in terms of power supply.\nAnonymous — July 15, 2013 at 4:53 pm (permalink) Anonymous says:\n\u0026ldquo;So yet you can hand code faster memory management code in C and get better performance in that way, however for very complex applications (and UI is pretty complex not to mention the management of native peers) you will end up with crashes. To avoid your crashes you add checks and safeties which go against the basic performance penalties you are trying to counter.\u0026rdquo;\nFalse dichotomy.\nIn modern programming languages, like Rust or Parasail, we can get zero-overhead automatic resource management and 100% memory safety:\n– http://pcwalton.github.io/b…\n– http://air.mozilla.org/regi…\nIt’s worth contrasting this with older, traditional languages, like Java or OO-COBOL, which use very old and inefficient methods, that don’t even work well anyway, like GC (which only applies to memory [instead of resources, like threads, in general], doesn’t guarantee memory safety [hello java.lang.NullPointerException!], and is very hard to get it right in an increasingly complex parallel environment [hello GC thread contentions!]), and leads to lower programmer productivity (who wants to manually deal with managing resources with manually writing boilerplate constructs like try/finally pattern, or try-with-resources? weren’t we supposed to leave manual resource management in the old C days? oh, wait, I forgot, Java hasn’t really improved upon C other than some extremely limited aspects of memory management, and still fails hard for all of the other resources).\nGC was invented in the 1950s, it’s ancient, unnecessarily slow, and limited; the world is moving on — let’s not be stuck in the GCed past! 😉\nAnonymous — July 15, 2013 at 4:54 pm (permalink) Anonymous says:\n\u0026ldquo;ARC on the other hand doesn’t allow you to do that since ARC instantly deallocates an object you finished working with.\u0026rdquo;\ninstantly\nAnonymous — July 15, 2013 at 4:55 pm (permalink) Anonymous says:\nI clarified that in the post, instantly when the ref count reaches 0.\nAnonymous — July 15, 2013 at 5:02 pm (permalink) Anonymous says:\nFair enough.\nThe discussion was about Objective-C, C, JavaScript and other managed languages though.\nObviously we should throw away all ideas invented in the 20th century like that damn microprocessor and move forward to those optical quantum machines 😉\nAnonymous — July 15, 2013 at 5:08 pm (permalink) Anonymous says:\nWell, OK, fair enough back at you, since RBSM was also invented in the 20th century (just later than GC) I guess we can keep some stuff 😉\nI guess I just get occasionally tired/frustrated of that false dichotomy, all too prevalent in the managed-vs-native discussions, where it’s all too often black-and-white (especially with statements suggesting getting crashes without GC, as if the NullPointerException didn’t exist).\nI wish we could move beyond that and consider more modern solutions, that’s all 🙂\nAnonymous — July 15, 2013 at 5:21 pm (permalink) Anonymous says:\n\u0026ldquo;doesn’t guarantee memory safety [hello java.lang.NullPointerException!]\u0026rdquo;\nActually a null pointer exception is an example of memory safety in action. In unmanaged languages, if you try to access uninitialized memory, you don’t get a null pointer exception. You just get access to the memory containing who knows what. This is the source of most serious software security exploits.\nAnonymous — July 15, 2013 at 5:53 pm (permalink) Anonymous says:\nI think the reason you are getting so much animosity is that you have taken Drew’s post as an excuse to fight a battle which is not the battle Drew is interested in — and you’ve jumped into this hijacking with nothing useful to add to the situation.\nDrew’s point was that Javascript is slow, and that it therefore inappropriate for certain types of code.\nHe gave some hypotheses for why it is slow, but the hypotheses are less important than the claim.\nYou have taken his point to ignore the issue of Javascript performance and launch another round of \u0026ldquo;rah rah Java is awesome; Objective C sux\u0026rdquo;. It’s your blog, you’re entitled to do that. But don’t be surprised when people who read this post and hope for something as informed as Drew’s post are disappointed to see yet another damn content-free argumentative post of the sort we’ve all read a million times in our lives.\nAnonymous — July 15, 2013 at 5:59 pm (permalink) Anonymous says:\nGlad someone is making a counter argument. I posted on the other thread and got moderated away when I disagreed. For the record DOM performance is definitely the biggest hit in my experience. I discovered the Mac version of Chrome appears to not be H/W accelerated when drawing – made painfully clear when a web app I was working on was smooth in VMWare in IE8 on XP(!), but running at about 10-15 FPS native OS. Safari (native) ran it at 60FPS. The code was a simple JQuery transition, so hardly anything unusual.\nRegarding the language war, you seem keen to add Objective-C into the mix. Objective-C has a vital secret weapon you make light of – just recode the slow bit in C. This has a much larger effect than all the JITing of Java, and Obj-C makes it trivial. E.g. Arbitrary JSON parser took 50 milliseconds on a certain block of data in Objective C. This became 10 microseconds when converted to a raw C SAX style parser – yes its convoluted, but this type of performance boost is much harder to come by with JITter clutter in the way.\nPS Sometimes memory must be freed and you don’t mention that you can null objects giving a clue to the GC to free memory now – I found it a huge boost in complex realtime Java UI.\nAnonymous — July 15, 2013 at 6:42 pm (permalink) Anonymous says:\nActually, it depends on the definition you’re using:\n\u0026ldquo;Memory safety is a crucial and desirable property for any piece of software. Its absence is a major source for software bugs which can lead to abrupt termination of software execution, but also, and sometimes even more dangerous, can be turned into a malicious tool: most of the recent security vulnerabilities are due to memory safety violations. \u0026quot;\nSource: http://dl.acm.org/citation….\nYes, in the Java world the second part is usually assumed the sole focus (and it’s granted that it can be \u0026ldquo;even more dangerous\u0026rdquo; to access memory this way, I don’t think anyone disputes that), but that doesn’t mean the first part (abrupt execution termination) is not a problem. It’s certainly a problem for the end-user, who in practice doesn’t care whether the software crashed because of a segmentation fault of a C program or an unhandled java.lang.NullPointerException in a Java program.\nAnd GC is not enough to guarantee that — it’s worth noting that this is the official stance taken in the draft JSR-302 Safety Critical Java (SCJ) specification:\nhttp://dl.acm.org/citation….\nSo, in fact, SCJ has stronger memory safety guarantees while dropping GC (would you call it \u0026ldquo;unmanaged\u0026rdquo;? :]).\nSimilarly, modern programming languages also offer stronger memory safety guarantees while dropping GC (see above).\nAnd I think it’s fair to characterize some of these as unmanaged, too.\nAnonymous — July 15, 2013 at 7:13 pm (permalink) Anonymous says:\nMy thoughts:\nThe jazz about DOM is absolutely true. JavaScript can affect any element in a DOM tree and changing elements within the DOM tree forces a web-engine to perform relayout, which just plain sucks. Additionally, all open source web engines (Gecko, any WebKit flavor ad Blink) have that their rendering stack is entirely imperative. The punchline is this: imperative rendering is fine for CPU’s but horror slow for GPU’s. Most WebKit flavors essentially do all drawing to offscreen buffers with the -CPU- and then instruct the GPU to perform compositing of those buffers to the screen. Sadly, the way that WebKit works, this is the best path. Indeed, if one were to use GL backed SKIA (or for that matter a GL backed QPainter for QtWebKit), performance is often SLOWER than with the CPU backed rendering (this is the case for mobile strongly at times). Needless to say, web rendering is much, much slower than it should be.\nWhen folks say keep all allocations out of one’s main loops to make sure GC does not activate, I cringe inside. What that means is this: for games all objects and memory must be allocated at start up. The result is that the game then make it’s own \u0026ldquo;object/memory\u0026rdquo; manager to make sure the GC does not kick in. The net effect is that then such games in reality end up doing manual memory management anyways. For UI’s it sucks. It sucks because then a developer needs to somehow make a user event driven program that somehow delays allocating until after it display the response to an event.. that means that objects needs to be pre-allocating before the event, and that after the screen is updated, the application generates it’s own event to itself to perform the next pre-allocation and one must home that the user does not send another event too fast if the GC gets invoked. So that just plain sucks.\nOn the subject of GC and graphics. In an application that uses hardware to render (for example uses OpenGL, JS woubd be WebGL), an application will need to -by hand- make the necessary GL calls to release graphics resources. So all the graphic stuff, needs to be freed manually. The up shot is that in a GC environment, one then needs to make sure that all the objects using the release graphics resource and \u0026ldquo;not in use\u0026rdquo;, just as the case for manual memory allocation.\nThat GC to perform well requires something like 2-6 times the actual memory used (depending on what one references) can be a major show stopper. Additionally, that GC is not deterministic can also me a major show stopper.\nAs for the war between JIT/interpreted languages and compiled languages: compiled is just going to win. Indeed, the Java.asm jazz at best is only twice as slow as native C code. You read that right, at best only twice as slow.\nThe sick twisted thing about the Java.asm thing: it is an asm like spittle to which to compile C programs with the hope that the JavaScript interpreter will run fast. In all honesty this is somewhat silly: the correct solution is to pass along LLVM byte code and let the local system convert that to native code. That conversion is very, very fast and can more often than not be performed while the resources(graphics, audio, etc) of a WebApp are downloading.\nNevertheless, WebApps are going to suck because they must render their UI’s through CSS/HTML and get them respond to user events by modifying the DOM with JavaScript. The only way out of this mess, is to not use CSS/HTML to format the UI, but rather bring up a canvas and draw the UI one self. Before anyone jumps up and down and says that is slow, it is only quasi-slow. For WebKit the 2D Canvas is implemented with the exact same stuff as the drawing of web page elements anyways. The only catch is that when doing the canvas thing, there might be an extra blit of your UI (from canvas offscreen buffer to screen or offscreen buffer of the layer of the canvas).\nAnonymous — July 15, 2013 at 9:20 pm (permalink) Anonymous says:\nmd, so tell me what really large applications have been written in these languages you’re talking about. Applications I can buy or use. New languages are infinitely fast and they can do everything better than languages that are already deployed. Until a few tens of millions of dollars have been spent writing applications with them. Then a realistic view is possible. Not before.\nI remember the all the promise of Java and C#. But at this point I know of companies that have spent hundreds of thousands and in some cases millions or tens of millions of dollars to attempt to build significant business critical applications in these languages and failed. Tell me why your new shiny magical languages are better. And provide proof. Proof means successfully delivered, non-trivial applications.\nThe languages you cite may be better. But maybe not. And you can’t tell yet.\nAnonymous — July 15, 2013 at 10:52 pm (permalink) Anonymous says:\nOne benefit of native language is that is something is slow you can optimise it. Objective-C messaging slow you down in a tight loop? Stick to C for that loop or a well known technique since the NextStep days is to use methodForSelector: and get direct access to what you want to call to remove the messaging cost where it matters. On the other hand, if the GC gets in your way, you’re done.\nSo yes, you are right about the cost of messaging, but the programmer can fix the problem where it matters. It’s pretty hard to bypass the JIT or GC if I would need to…\nAnonymous — July 16, 2013 at 1:13 am (permalink) Anonymous says:\nFair enough, I did take his post in a different direction although the reason I responded was that so many people turned to me asking for my take on it.\nIt seems that people weren’t clear about my opinion regarding Drew’s post (which is pretty positive I clarified it further on the top).\nI don’t think I changed the subject, I said that reflows are the problems most people perceive when they see slow web performance which is the one thing he didin’t discuss and is very widely documented online. Then I discussed my personal experience (and gave some relevance) links where the situation he describes isn’t black and white where JIT/GC == slow.\nI did flamebait Objective-C that’s true. But I’m kind of tired of Objective-C developers calling themselves \u0026ldquo;native\u0026rdquo; when it really isn’t C. You pay a price for Objective-C that you don’t pay even in Java for messages, so deriding slow performance of all managed code in the world and while being an iOS developer is something that needs to be taken down a notch.\nI’m surprised by the animosity from some people who seem to actually agree with most of my points?\nAnonymous — July 16, 2013 at 1:28 am (permalink) Anonymous says:\nThanks for the detailed comment.\n2. I don’t like that either. However, I clarified this a bit. This is only true for high rendering FPS games where you code in OGL anyway. Allocations would be done in the GL memory which is native anyway and so do not fall under the GC allocator.\n3. I don’t think the 2 times memory overhead is factual. It is based on a study conducted on the desktop. As I said, just pick up an Asha device and benchmark it, Nokia has 2mb devices and they are very fast with the GC.\nTrue since the GC is proprietary I can’t benchmark using the studies methodology but I can tell you that mobile device GC’s are very different from desktop GC’s. It is non-deterministic though which is problematic for some use cases and requires some defensive programming.\nLet’s agree to disagree on JITs 😉\nAnonymous — July 16, 2013 at 1:31 am (permalink) Anonymous says:\nAgreed, the ease of writing C in Objective-C is great!\nIts also possible (although not as easy) in Java to invoke native C code and that is done for critical code.\nAnonymous — July 16, 2013 at 3:42 am (permalink) Anonymous says:\nIf you are rendering on the CPU you are doing it wrong.\nWhich might explain a bit of the other nonsense.\nAnonymous — July 16, 2013 at 4:35 am (permalink) Anonymous says:\nRead the other comments here (rather than being Anti) specifically about Webkit and GPU optimizations for DOM.\nThe heavy lifting is done by the GPU but want to keep the CPU in low utilization to feed the GPU so this doesn’t really negate anything. Furthermore, with mobile system on a chip design the separation of CPU/GPU isn’t as clean as it is on the desktop.\nHopefully you will be less \u0026ldquo;anti\u0026rdquo; and more proactive.\nAnonymous — July 16, 2013 at 6:15 am (permalink) Anonymous says:\nWe’ve been doing that with Android, and I can say this is a yuck solution. Firstly all the debuggers are broken. You can sometimes get them stable enough to debug, but going seamlessly between Java and C? No. This leaves you log debugging one side and then log debugging the other. A big time waster. Admittedly tools can be fixed, and beaten into something sort of working, but they aren’t easy or clean.\nSecond Java contexts just look alien in C. Manipulating the data leads to lots of construction code. Double (different) prototypes of every function. Linker fun with C++ vs C… the list is long.\nObjective-C or should I say (Objective-C++?) really is in a different world here.\nAnonymous — July 16, 2013 at 6:15 am (permalink) Anonymous says:\n\u0026ldquo;This is only true for high rendering FPS games where you code in OGL anyway\u0026rdquo;\nThat statement does not really make any sense: OGL is an API, that API has bindings to multiple languages where the languages spread across compiled, interpreted, managed and unmanaged. On the subject of managed language, the whole point of GC is so that a a developer does not need to devote the time, and hence the skill investment, to do manual memory management. Once you have something OGL where graphics resources need to be allocated and deallocated by using the API, a developer needs to do it. The terrible catch is this: if a developer has not done this a great deal and does not have the skill to do it, they are hosed.\nGoing further: for an application where performance guarantees are required (essentially any user event driven UI) then managed memory is a liability. In an idea world, it would be nice to have an option to be able to turn the GC on and off. Off during a loop, on during idle. The catch is that for user event driven programs, the GC needs to be done when an event comes… or the ability to interrupt the GC when the event comes, but that requites support within the VM and language. Atleast it is doable on paper though.\nIn an ideal, potentially fantasy, world a GC would not stop the program at all. I think that the overhead to do that though would be horrible.\nAt any rate, from my perspective, if a developer cannot accurately track what they have or have not allocated then that developer does not have any real idea how many bytes their application really consumes, as such it’s suitability on a mobile device is questionable. What remains for the main use cases of GC’s is for to handle the icky case of multiple users for a single object together with circular references.. the exact cases where reference counting and object owner ship are unclear… however, more often that not a little clear thinking kills those issues off.\nI admit though, from a get code out the door faster point of view, GC can be great and it stops memory leaks… but it has a huge performance penalty that is very spiky and unpredictable.\nAnonymous — July 16, 2013 at 6:18 am (permalink) Anonymous says:\nCalling C code(or other compiled languages) from a Java VM has a pretty high overhead though, so it needs to be done with care and taste. Additionally getting the data between the two is a pain.\nAnonymous — July 16, 2013 at 7:01 am (permalink) Anonymous says:\nI agreed with Sandy’s post and with both your comments. JNI is painful, doable but painful.\nAnonymous — July 16, 2013 at 7:09 am (permalink) Anonymous says:\nDid you use OGL bindings for Java?\nThey require that you manage texture memory manually (just like OGL in C).\nThere are hard realtime GC’s for Java that have consistent predictable GC pauses but they aren’t used in mobile programming since that isn’t considered an RTOS. There are also concurrent GC’s but those are designed for huge server heaps where stopping the world to GC can take many seconds.\nThere are many things GC authors can do and actually do, however when it comes to framerate sensitive games its hard to rely on that vagueness. Just to be clear, I’m not advocating the writing of framerate sensitive OGL code in Java. I’m just having a fun theoretical debate 😉\nFor mobile game programming, if you need FPS nothing beats C.\nAnonymous — July 16, 2013 at 8:57 am (permalink) Anonymous says:\nSorry, but thats the problem with your article. Too many guesses and wild claims with very 0 backup. You know, computer science is still considered ‘science’ for a reason 😉\nAnonymous — July 16, 2013 at 9:04 am (permalink) Anonymous says:\nPip. I’m using my actual name and experience here as a reference. Feel free to check my work on OSS software and linked in page to see that I am fully aware of the facts here.\nWhere did I claim something I can’t substantiate as a fact without explicitly separating it as an assumption that is hard to substantiate?\nWhere did I make a wild claim that contradicted something? DOM reflow having an overhead? Google it. Pretty obvious. Objective-C messages being slow (linked in the comments), memory allocation/dealocation being expensive (pretty easy fact). GC has an overhead but its manageable?\nScience also includes interpretation for the data, the facts here are still in the flexible stage where they can fit many different theories otherwise we would all be programming with the \u0026ldquo;best language\u0026rdquo; and \u0026ldquo;best OS\u0026rdquo;.\nAnonymous — July 16, 2013 at 9:27 am (permalink) Anonymous says:\nI would agree, if the option of semi-automatic GC were there. but, no!\nAnonymous — July 16, 2013 at 9:32 am (permalink) Anonymous says:\n\u0026ldquo;Are GCs Expensive\nYes they have a cost, no its not a big deal.\u0026rdquo;\nI think this is the best example ever of what i meant !!\nYou simply say it is negligible, while there are so many article already showing that that is not the case, and that is not the case with Java !!!\nAnonymous — July 16, 2013 at 9:41 am (permalink) Anonymous says:\nActually the article Drew linked to showed that GC’s perform REALLY well they only take up too much memory (that’s in 2005). Embedded GC’s used in J2ME have no such overhead (e.g. Nokia devices with less than 2mb of RAM performing really well). Problem is that you can’t really test those GC’s against \u0026ldquo;no GC at all\u0026rdquo;.\nHowever, my claim isn’t about that. If you are writing an FPS heavy game (for which C is still the best, not Objective-C or Java) or a quick animation within your app you would do anything to avoid GC and GC aware allocations (just pre-allocate the memory). This isn’t hard to do.\nThe lovely part about a GC is that even if it is 5 times slower it runs on idle CPU. If you don’t have plenty of idle CPU on a mobile device then your problem isn’t GC, its battery life.\nAnonymous — July 16, 2013 at 10:17 am (permalink) Anonymous says:\nOn that note, I know of companies that have spent millions of dollars building business critical applications with java and c# and have gotten a good return on investment for them.\nAnonymous — July 16, 2013 at 10:24 am (permalink) Anonymous says:\nNot to mention, most companies build their business around C, Java, Objective-C and C++, if we are not mentioning only web languages.\nIf we were not to consider Desktop or foundation software, probably we would mostly see Java on top and then C# and PHP.\nI guess for most business what matter is the value delivered to the user. I mean, it can’t be slow, but it doesn’t need to be real-time or close to it.\nTiobe index: http://www.tiobe.com/index….\nAnonymous — July 16, 2013 at 12:27 pm (permalink) Anonymous says:\nSure it’s only true how the user perceives the performance in the end. But it’s not just lag waiting for web pages to download on a mobile device; the battery life plays a lot into the perception of how good a mobile device.\nBut my perspective: I spent a few years building music instruments on iPad/iPhone where an extra 10ms of latency is the difference between something that’s playable and something that’s a useless piece of junk (ie: you can’t do fast arpeggio and scale runs with high latency/jitter).\nI use Java/C#/Python, etc in my day job for server apps, with only a few spots in C, and wish the port all of that work to Java.\nBut on mobile devices, the apps are small enough that C is usually ok, and there isn’t enough headroom for a nice language. Real-Time is the main issue, battery life the second issue. Maybe at some point, Go/Rust/Parasail might be alternatives; even thinking about Ada now. As ubiquitous as C is, every API you use has its own set of (possibly undocumented) rules on what it does with its pointers, and it’s basically a useless partner in peer-reviewing for the kind of bugs that any modern compiler would find given a properly designed language.\nAnonymous — July 16, 2013 at 1:19 pm (permalink) Anonymous says:\npip, If you don’t like it, don’t use it. If you think it’s too unpredictable, don’t use it. But saying it’s universally inadequate for event driven UIs is just silly. Even on mobile devices, I don’t think it’s UNIVERSALLY true.\nThe first event-driven UI I ever used was something called Smalltalk/V, which ran on top of MSDOS much faster than Windows and provided a development environment, VM and room for applications in 64K. It’s successor, V/286 was used to build event-driven, networked applications for factory applications in the late 80s and early 90s, in less than 16MB of memory. You’ve ridden in the output of those factories, above 30,000 feet.\nIn that environment, almost any c code I encountered could be written faster in a bytecode interpreted language with a good class library, without a JIT and with garbage collection. Not because the c couldn’t have been faster, but because the amount of code that needed to be written, the deadline, the c developers skill level and the tools and effort available to kill memory leaks.\nThat situation still exists today, all over the world, in the corporate sector. And it even may apply in the mobile space, when building apps for less than some number of users. 100, say or 1000.\nAnonymous — July 16, 2013 at 1:39 pm (permalink) Anonymous says:\ndurkin, I agree with you. I wasn’t saying it couldn’t be done, both are very successful languages. My point was only that Java and C# have not lived up to the hype that was presented about them before any application base existed.\nLucas, most non-tech companies BUY C/C++ applications, but can’t afford or aren’t willing to pay for custom development in those languages. Java, yes, C# yes, Objective-C probably not unless the company is very large and in a media related business. In June, 2013 total non-Windows OS use on the desktop was about 9%. COBOL is barely visible in the media, but lots of big companies still run on it.\nLucas, most non-tech companies BUY C/C++ applications, but can’t afford or aren’t willing to pay for custom development in those languages. Java, yes, Objective-C probably not unless the company is very large and in a media related business. In June, 2013 total non-Windows OS use on the desktop was about 9%.\nAnonymous — July 16, 2013 at 3:29 pm (permalink) Anonymous says:\nWe all know that android has better hardware than iphone because is needed to run the crappy java at reasonable speed. So whatever you’ve tried to explain here is available only in theory if you don’t take everything into account, java is not native and will never run faster than objc.\nAnonymous — July 16, 2013 at 3:36 pm (permalink) Anonymous says:\nAndroid is Dalvik not Java, the VM is completely different. OTOH pick any Asha device and play with it. Its no iPhone in terms of feel (no GPU) but its CPU also sucks and it has 3-4mb of RAM.\nAnonymous — July 16, 2013 at 5:51 pm (permalink) Anonymous says:\n@Cristi, I’m not sure that Obj-C’s message passing is faster than Dalvik’s method invocation, after run through the Android JIT compiler. Obj-C is sort of its own animal, and you can’t compare it to other languages under the assumption that it’s exactly equivalent to C/C++. Performance sensitive Obj-C apps regularly drop into C or C++, just like performance sensitive Android Dalvik/\u0026ldquo;Java\u0026rdquo; apps do. It’s a bit easier to do that from Obj-C, but at that point it wouldn’t typically be referred to as Obj-C anymore. (Question of semantics, I suppose.)\nAnonymous — July 16, 2013 at 10:58 pm (permalink) Anonymous says:\nI take issue with the supposition that it’s impossible to microoptimize when targeting the JVM. Take a look at the implementation of Bagwell’s hash tries used in Clojure — their design actually takes into account CPU cache line widths, and they’re crazy fast as a result.\nAnonymous — July 17, 2013 at 1:06 am (permalink) Anonymous says:\nApple says that method calls are cached as they are used, after a while it becomes almost as a function call. You can also find the IMP and call it directly.\n\u0026ldquo;To speed the messaging process, the runtime system caches the selectors and addresses of methods as they are used. There’s a separate cache for each class, and it can contain selectors for inherited methods as well as for methods defined in the class. Before searching the dispatch tables, the messaging routine first checks the cache of the receiving object’s class (on the theory that a method that was used once may likely be used again). If the method selector is in the cache, messaging is only slightly slower than a function call. Once a program has been running long enough to \u0026ldquo;warm up\u0026rdquo; its caches, almost all the messages it sends find a cached method. Caches grow dynamically to accommodate new messages as the program runs.\u0026rdquo;\nAnonymous — July 17, 2013 at 1:24 am (permalink) Anonymous says:\nWith all that caching message passing in objective c approaches about 3 times slower than java method invocations. It isn’t hard to set up benchmarks to verify this yourself. I’ve done several tests myself for pure curiosity’s sake.\nAnonymous — July 17, 2013 at 2:19 am (permalink) Anonymous says:\nShai is right about Java performance, vs obj-c, c, etc. This is not a controversial fact among anyone who has actually measured the language performance on varying platforms. It is also true that iOS has very well designed frameworks that cover this difference, The reality is the whole industry would be better of if Apple had kept their Java wrappers of cocoa and then ported cocoa to actual java just as they ported WebObjects, WebObjects by the way was quite bit faster in its Java incarnation.\nAs for the silliness of commenters about allocation speed etc, well look any if us worth our weight know you are hinting to your runtime with your allocation patterns and it’s better to have your app come to steady state and then not allocate just to do normal work, like render a frame, etc.\nObjective c is like the bad hair on a beautiful woman (iOS). We put up with it, maybe even fondle it, out of love for what it connects us to.\nHaving done deep performance work for Apple, Sun, and many others in both the c layers and Java and objective c, I just say hey, it’s worth listening to our blogger here. If you would rather not, that’s ok. Just remember we tried to tell you 😉\nAnonymous — July 17, 2013 at 2:41 am (permalink) Anonymous says:\nI dug up this old simple benchmark of Towers of Hanoi and ran it again on my Macbook Air. It shows Java running over 5 times faster than Objective-C. You can verify this easily by copying/building/running the code on your local machine.\nhttps://gist.github.com/ano…\nAnonymous — July 17, 2013 at 5:20 am (permalink) Anonymous says:\nI will attribute your statement to inexperience 😉 Static optimization is optimal only with a closed world assumption. As soon as you load an additional class, all bets are off. For example, a JIT might know that a method which may be overridden is actually NOT overridden and just inline the call. A static compiler cannot know that. Btw: AOT (ahead of time compilation) has been a feature in IBM’s J9 VM since the dawn of time.\nAnonymous — July 17, 2013 at 5:29 am (permalink) Anonymous says:\nNot true: Blackberry 10 is based on QNX. It doesn’t come more real time than that.\nAnonymous — July 17, 2013 at 5:55 am (permalink) Anonymous says:\nFunny 🙂\nMost modern (managed) languages use a GC and everyone using those seem perfectly fine with how they work (including me). So I can conclude, from asking for a half baked solution, that you indeed lack that \u0026ldquo;developer skill\u0026rdquo; to work with it properly.\nAnonymous — July 17, 2013 at 2:51 pm (permalink) Anonymous says:\nActually, the music app developer I worked with did port some of his apps to the BB10. Everybody who has used it claims that the BB10 is by far the best implementation; because of the responsiveness. Animoog got ported to it as well; and people who use it also say that it has great responsiveness.\nUnfortunately though, making cheap apps for the BB10 doesn’t work business-wise because the user base is just too small. It might work if it were packaged/marketed as a dedicated music device though; but not as an actual Android/iOS competitor.\nMobile music apps’ killer hardware platform would have: a real-time OS (QNX?) and a pressure-sensitive screen. Every existing hardware choice already has enough throughput, and most have a fast enough touch screen.\nAnonymous — July 24, 2013 at 12:54 am (permalink) Anonymous says:\n\u0026ldquo;Note that the title of this post is not [written in] proper English.\u0026rdquo;\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/why-mobile-web-is-slow/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/why-mobile-web-is-slow/why-mobile-web-is-slow-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/why-mobile-web-is-slow-large-2.jpg\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/why-mobile-web-is-slow/why-mobile-web-is-slow-1.jpg\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e**\u003cbr\u003e\nClarification update:\u003cbr\u003e\n**\u003cbr\u003e\nFor some reason people read this as a rebuttal of\u003cbr\u003e\n\u003ca href=\"http://sealedabstract.com/rants/why-mobile-web-apps-are-slow/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nDrew Crawford\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\narticle,\u003cbr\u003e\n**\u003cbr\u003e\nit is not\u003cbr\u003e\n**\u003cbr\u003e\n. It is merely a response, I accept almost everything he said but have a slightly different interpretation on some of the points.\u003c/p\u003e\n\u003cp\u003eOver the weekend quite a few people wrote to me about a\u003cbr\u003e\n\u003ca href=\"http://sealedabstract.com/rants/why-mobile-web-apps-are-slow/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nwell researched article written by Drew Crawford\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nwhere he gives some insights about why the mobile web/JavaScript is slow and will not (for the foreseeable future) compete with native code. My opinion of the article is mixed, it is well written and very well researched, I also agree with a few of the points but I think that despite getting some of the conclusions wrong I think his reasoning is inaccurate.\u003c/p\u003e","title":"Why Mobile Web Is Slow?"},{"content":"\n**\nUpdated:\n**\nWe also added the option: ios.mopubTabletId which is required to build tablet compilant apps. It must point to a leaderboard ad unit.\nFor a long time we’ve been looking for a proper partner on banner ads and could only find mediocre networks or worse. Unfortunately it seems the field of proper advertising on device is still problematic and we just couldn’t find anyone with an offering that will work properly across the globe/devices.\nSo we picked the next best thing, we integrated\nMoPub\nsupport for Android/iOS only (for true cross platform our Inneractive support is still in place).\nMoPub isn’t an advertizing network, its an ad exchange. So effectively when you place a banner ad via MoPub you can get an ad from AdMob, iAd or any one of a relatively large list of partner networks.\nThe benefit here is in fill rates, you can improve ad fillrates and payments since if network X doesn’t have the right ad network Y could kick into place! You can mix and match many different networks including iAd which works really well on iOS but isn’t available elsewhere.\nTo work with MoPub you will need to signup to their service and create ad units, apps etc. using their interface. Make sure to create both banners and leaderboards since iOS will use banners for iPhone but leaderboards for iPad (otherwise iAd’s look awful). Then get the integration code from their unit (different codes for Android/iOS) and add the build arguments:\nios.mopubId=Your ad unit here\nios.mopubTabletId=Leaderboard ad unit for a tablet\nandroid.mopubId=Your ad unit here\nAnd you will get banners like the one in the picture.\nNotice that currently the ads take over the bottom portion of the screen so you might want to add padding or margin there\n. We are thinking whether this should be automated and if so in what way. This is an experimental feature at the moment so some things might change with it as we move along, but we felt that its a rather urgent feature which is why we are releasing it right now. Hopefully you will find it useful.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/mopub-ad-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/mopub-ad-support/mopub-ad-support-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/mopub-ad-support-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/mopub-ad-support/mopub-ad-support-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e**\u003cbr\u003e\nUpdated:\u003cbr\u003e\n**\u003cbr\u003e\nWe also added the option: ios.mopubTabletId which is required to build tablet compilant apps. It must point to a leaderboard ad unit.\u003c/p\u003e\n\u003cp\u003eFor a long time we’ve been looking for a proper partner on banner ads and could only find mediocre networks or worse. Unfortunately it seems the field of proper advertising on device is still problematic and we just couldn’t find anyone with an offering that will work properly across the globe/devices.\u003c/p\u003e","title":"MoPub Ad Support"},{"content":"\nHandling errors or exceptions in a deployed product is pretty difficult, most users would just throw away your app and some would give it a negative rating without providing you with the opportunity to actually fix the bug that might have happened.\nGoogle improved on this a bit by allowing users to submit stack traces for failures on Android devices but this requires the users approval for sending personal data which you might not need if you only want to receive the stack trace and maybe some basic application state (without violating user privacy).\nFor quite some time Codename One had a very powerful feature that allows you to both catch and report such errors, the error reporting feature uses the Codename One cloud which is exclusive for pro/enterprise users. Normally in Codename One we catch all exceptions on the EDT (which is where most exceptions occur) and just display an error to the user\nas you can see in the picture. Unfortunately this isn’t very helpful to us as developers who really want to see the stack, furthermore we might prefer the user doesn’t see an error message at all!\nCodename One allows us to grab all exceptions that occur on the EDT and handle them using the method\naddEdtErrorHandler in the Display class. Adding this to the Log’s ability to report errors directly to us and we can get a very powerful tool that will send us an email with information when a crash occurs!\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nChidiebere Okwudire — April 5, 2016 at 9:51 pm (permalink) Chidiebere Okwudire says:\nIs it possible to send log to another email address than the developer’s?\nShai Almog — April 6, 2016 at 2:41 am (permalink) Shai Almog says:\nNo. A lot of features are locked directly to that email account.\nIt’s a problem to accept an email dynamically for some services as they might be handled in complex ways e.g. sending an email from a production app. So it’s important to us that one valid email is used and that an email is used per developer to avoid abuse.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/handling-the-exception/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/handling-the-exception/handling-the-exception-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/handling-the-exception-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Exception\" loading=\"lazy\" src=\"/blog/handling-the-exception/handling-the-exception-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eHandling errors or exceptions in a deployed product is pretty difficult, most users would just throw away your app and some would give it a negative rating without providing you with the opportunity to actually fix the bug that might have happened.\u003c/p\u003e\n\u003cp\u003eGoogle improved on this a bit by allowing users to submit stack traces for failures on Android devices but this requires the users approval for sending personal data which you might not need if you only want to receive the stack trace and maybe some basic application state (without violating user privacy).\u003c/p\u003e","title":"Handling The Exception"},{"content":"\nWe started moving the usages of Vector and Hashtable to use Map/Collection/HashMap \u0026amp; ArrayList. This follows our release of the full source code for our modified version of retroweaver and the Java packages that go with it. Recap: we had to change retroweaver which was designed to allow Java 5 code to run on Java 2 in order to get it to work with CLDC which is missing MANY features.\nWe started by changing the most important and central features (there is a lot of code that uses old collections, changing it all will be challenging and sometimes not worth the hassle e.g. HTMLComponent). So we changed the TextArea, Component, Container, Display \u0026amp; DefaultListModel to use\nthe ArrayList class. We chose those since they are central and should yield the greatest performance benefit, we also chose them because they are well encapsulated and thus the change should be completely seamless API wise.\nWe also added\nMap/Collection support to the Util write object classes and Storage serialization code. So if you pass a vector or hashtable to the code it will act like before, however if you pass a different collection (e.g. ArrayList) or Map (e.g. HashMap) it will be stored properly as well. Right now when we unmarshal (read) the data for a Map or Collection we will always create as HashMap or ArrayList never creating the actual concrete class, the reason we can’t do that is that if we saved the class name and it was obfuscated this might break between revisions.\nSo this was the \u0026ldquo;low hanging fruit\u0026rdquo; now comes the tough part… Some developers have asked us in the past to generify some interfaces e.g. EventDispatcher, ListCellRenderer \u0026amp; DefaultListModel. To be honest I’m not so sure how well this will work but I understand the value of being able to do that. I have some concerns about binary compatibility for these cases but from my understanding it should be possible.\nHow important would this be to you guys?\nDo you want to see our common interfaces generified?\nAs a side note we also added an ability in our cloud server to send email messages directly from the app, which can be pretty useful since it doesn’t require a working email account or permissions other than networking. Its only available for pro accounts or higher, and allows you to use the Message API’s methods to send an HTML or plain text email directly through our build cloud server. Notice that due to spam issues all emails will arrive from a Codename One address (although you can customize the name of the sender) E.g. to send an email you can do something like this:\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — July 4, 2013 at 2:48 am (permalink) Anonymous says:\nI for one would appreciate Generifying the interface. The most important thing for me is (#1) Being able to write the same code for iPhone and Android apps. (#2) A nice API, (#3) Windows 8 Phone and Blackberry 10 support.\nAnonymous — July 6, 2013 at 8:52 am (permalink) Anonymous says:\nI am new to codename one, but based on your blog post, it seems that there are few things which are still used just to support CLDC profile, I would suggest that make framework separate for smart ;phone and CLDC so that you guys can make full use of Smart phones capabilities.\nAnonymous — July 6, 2013 at 9:04 am (permalink) Anonymous says:\nThe code is optimized for smartphones and provides access to the full smartphone capabilities including access to native code.\nThe post is about changing API’s not about CLDC compatibility.\nWe hide some Java language capabilities so our distribution size can be smaller and more efficient on iOS/Windows Phone.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/the-move-to-java-5-and-new-cloud-e-mail-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/the-move-to-java-5-and-new-cloud-e-mail-support/the-move-to-java-5-and-new-cloud-e-mail-support-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/the-move-to-java-5-and-new-cloud-e-mail-support/the-move-to-java-5-and-new-cloud-e-mail-support-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe started moving the usages of Vector and Hashtable to use Map/Collection/HashMap \u0026amp; ArrayList. This follows our release of the full source code for our modified version of retroweaver and the Java packages that go with it. Recap: we had to change retroweaver which was designed to allow Java 5 code to run on Java 2 in order to get it to work with CLDC which is missing MANY features.\u003c/p\u003e","title":"The Move To Java 5 And New Cloud E-Mail Support"},{"content":"\nWe’ve been so busy this past month that we just forgot mentioning many of the features that went into Codename One in June and\nthere are MANY small features that just didn’t get a blog post or even a mention!\nWe just open sourced a major piece of our backend code, the changes to retroweaver and library code that allow us to compile Java SE 5 code to J2ME/RIM. With this change in place we will start using Java 5 features throughout the code but mostly transition towards using ArrayList/HashMap and the base collection interfaces rather than Vector/Hashtable.\nOn the right you should see the multi column generic spinner used in the\nMaker\nGUI builder, its right columns are filled dynamically based on the layout type. This is pretty easy to accomplish even from the GUI builder. The Generic spinner’s methods now accept an offset for the column and change the values/model within the given column.\nPaul Harrison Williams contributed an\nXML\nwriter\nimplementation that allows you to serialize XML Elements to a stream.\nProbably the most interesting/important feature\nis two new scale modes in Style: Scale to fit and Scale to fill. When you set a bg image to a style (either via the designer or in code) you can set the image behavior. The default is scaled, which never really made much sense. You can also tile or align the image in many ways but up until now we were missing two very basic and important features:\nScale to fit scales the image so it will fit on the component while maintaining its aspect ratio. It will leave the background in the bgColor if transparency is defined as expected.\nScale to fill scales the image so it will fill the entire component while maintaining aspect ratio, in this case the image will usually \u0026ldquo;flow\u0026rdquo; out of the screen in one of its edges.\nThis is easier to explain with an example (in order scaled, scale to fit, scale to fill):\nAs part of this work we also added a flag to image download service allowing it to maintain the aspect ratio of downloaded images which is really useful when working with images off the internet from users photo albums etc.\nOther than that we\nadded a simple ability to create/delete contacts, this is rather basic but can help for many common use cases you can delete a contact using its \u0026ldquo;id\u0026rdquo; as: Display.getInstance().deleteContact(id);\nYou can also create a basic contact using:\nDisplay.getInstance().createContact(firstName, familyName, officePhone, homePhone, cellPhone, email);\nWe made some enhancements to our Facebook support as well but one\nof the more interesting ones is the ability to sign in to an App without a user visible OAuth process. This will grant you the ability to access public information on Facebook (e.g. pages, public posts/profiles etc.) but since no user will be logged in this won’t provide an \u0026ldquo;identity\u0026rdquo;. Note that you will still need to create a Facebook App to associate with the requests, then you can just login using:\nFacebookAccess.anonymousLogin(appid, clientSecret);\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/big-batch-of-features/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/big-batch-of-features/big-batch-of-features-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/big-batch-of-features-large-5.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Multi Column Generic Spinner\" loading=\"lazy\" src=\"/blog/big-batch-of-features/big-batch-of-features-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve been so busy this past month that we just forgot mentioning many of the features that went into Codename One in June and\u003c/p\u003e\n\u003cp\u003ethere are MANY small features that just didn’t get a blog post or even a mention!\u003c/p\u003e\n\u003cp\u003eWe just open sourced a major piece of our backend code, the changes to retroweaver and library code that allow us to compile Java SE 5 code to J2ME/RIM. With this change in place we will start using Java 5 features throughout the code but mostly transition towards using ArrayList/HashMap and the base collection interfaces rather than Vector/Hashtable.\u003c/p\u003e","title":"Big Batch Of Features"},{"content":"\nWe’ve had a long standing annoyance with Codename One’s RTL (Right To Left languages, e.g. Arabic/Hebrew etc.) where the back button was still pointing in the wrong direction on iOS.\nThis was REALLY annoying to such a great extent that up until recently we recommended that people don’t use RTL on iOS devices.\nWell we finally fixed it, what took us so long was the desire to \u0026ldquo;do it right\u0026rdquo; but we couldn’t figure out what the right thing was?\nBasically the iOS 6 back button is broken since it has a very specific direction and angle it can’t be cut as a 9-piece border and has to actually appear as a horizontal image border. My initial thoughts were to allow a component to define an RTL specific style attribute (in this case border), however doing something like this would be painful and just the thought of going back and editing all the themes seemed excessive.\nSo I added a method into the image class called mirror() which you can now invoke to get an exact mirror image of the given image. and into the border class we added the ability to get an RTL border, this is only implemented for horizontal image borders which is the source of this specific problem. This isn’t generic but it works rather well and seamlessly! The back button will \u0026ldquo;just reverse\u0026rdquo; on RTL regardless of the theme you use and will act as you would expect starting with the upcoming update.\nAs a side note, we will not be traveling to Java One this year as all our talks got rejected. This is after having packed rooms and rock star trophy from the previous Java One. Its a shame that Oracle is such a monocolture where you can’t talk about alternative approaches within their conference. I can’t say I’m too disappointed about not going, since leaving Moscone Java One hasn’t been the same.\nI am very excited about attending JavaZone which looks like a REALLY cool conference by some very cool guys, can’t wait to go there.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/longstanding-issue-of-back-button-in-bidirtl/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/longstanding-issue-of-back-button-in-bidirtl/longstanding-issue-of-back-button-in-bidirtl-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/longstanding-issue-of-back-button-in-bidirtl-large-3.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/longstanding-issue-of-back-button-in-bidirtl/longstanding-issue-of-back-button-in-bidirtl-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve had a long standing annoyance with Codename One’s RTL (Right To Left languages, e.g. Arabic/Hebrew etc.) where the back button was still pointing in the wrong direction on iOS.\u003c/p\u003e\n\u003cp\u003eThis was REALLY annoying to such a great extent that up until recently we recommended that people don’t use RTL on iOS devices.\u003c/p\u003e\n\u003cp\u003eWell we finally fixed it, what took us so long was the desire to \u0026ldquo;do it right\u0026rdquo; but we couldn’t figure out what the right thing was?\u003c/p\u003e","title":"Longstanding Issue Of Back Button In BiDi/RTL"},{"content":"\nNote: skip to the bottom for some instructions on working with the BB Z10.\nLately we’ve been asked by one of our pro customers to fix some issues which occurred only on the z10 device. I thought this would be an easy task: just grab the tools from the blackberry site and then use them to debug the issue. I was quite wrong… Apparently the emulator can only run in a virtualization environment.\nOK that shouldn’t stop me, I grabbed the VMPlayer installed it then installed the BB emulator and had myself a running emulator… Or at least I should have been so lucky! My machine couldn’t run it because the display driver wasn’t supported, took me a while to figure this one out. I tried on another PC instead and was luckier, it worked I had a emulator running.\nBlackberry 10 is in many regards more like Android than older blackberries. So it doesn’t support our existing BB apps, however it does support running Android apps if they are packaged specifically for it.\nSo I started working on\ninstalling the android build of the app, should be an easy task, right?\nWrong again. Spent a couple of hours understanding the process of converting the .apk to a .bar file and then the signing process. Finally I, got a valid .bar file and installing it wasn’t hard. The app was finally running in the emulator and I got a tingling happy feeling all over.\nThen the app crashed which was pretty much what our customer complained about, so lets take a look at the log or console. Should be somewhere, right?\nWrong, you need an ssh client to connect to the VM and then look for the file somewhere… That’s inconvenient but doable, I really wanted to know what the hell happened.\nLaunching Putty and connecting to get the log then finding the path, trying to get in and it seems that I don’t have permissions to enter the directory for the log. Well that broke me, how do they expect anyone to develop apps for this?\nSome more googling and I came to the conclusion that the only way to debug this is with a device.\nWell a few days past and I got myself a limited edition z10 device (thanks to\nShai Ifrach\n), seems like it became a hit device because it’s a limited edition. It even sold for $1799 –\nhttp://www.ebay.com/itm/Developer-BlackBerry-Z10-Limited-Edition-Red-/321094687957\nChecking the problem on the device should be easier, it seemed that the OS version on the device was out of date and since they push the OS updates through the carrier this posed a problem.\nOr am I? After\nsome more googling I found a manual hacking process to manually update the OS. Got the approval from the owner (I didn’t think I could hack a $1799 loaner device without that) and I was able to update the z10 OS, now lets see what’s going on.\nAfter some more research it seems like the easiest way would be to use the eclipse plugin with the device, grabbed the plugin some more setups and got it working and I’m getting the output in the ddms, now finally I managed to debug the issue and to figure out what was the problem.\nIn\nconclusion – Blackberry… Please… show some love for developers, if it’s not practical to develop properly with the emulator don’t ship it and I thought your JDE was awful.\nThe device itself is surprisingly decent, it feels like they have a slim chance to maintain some market with this hardware.\nFor those of you who want to build apps for Blackberry OS 10, you need to start with your Android APK (send an Android build in Codename One) then converting the apk to a bar file which can be done in a few ways:\nOnline tool – Blackberry provides an applet on their site where you provide the apk and the signing certs and it allows you to convert and sign your apk file. Command line tools – a few script files that will allow you to preform the conversion in command line Eclipse plugin – through the plugin you can do the conversion. See also –\nhttp://developer.blackberry.com/android/tools/\nWe would like to simplify this process for our developers but we are running into some issues with the Blackberry command line tools and their signing process. It seems signatures aren’t stored in any standard way.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — June 25, 2013 at 4:57 pm (permalink) Anonymous says:\ni hope that RIM can help you more that some time in the future codename one will support B10 devices by default.\nAnonymous — July 2, 2013 at 7:32 am (permalink) Anonymous says:\nI wonder what they were thinking, making development so difficult for their OS, knowing fully well it’s not the best OS or even Hardware in the market.\nAnonymous — July 4, 2013 at 5:19 pm (permalink) Anonymous says:\nTheir dev tools were never a pleasant experience, the JDE was also painful but workable.\nThe current simulator is a tool for hackers only, but can you blame them? they don’t have much time and the pressure on them is huge, I hope they will improve over time.\nAnonymous — January 31, 2014 at 3:47 am (permalink) Anonymous says:\nwhere is the online converter can you give me a link?\nAnonymous — January 31, 2014 at 4:39 am (permalink) Anonymous says:\nThey change the URL’s all the time in the RIM site. Did you try googling?\nAnonymous — January 31, 2014 at 5:40 am (permalink) Anonymous says:\nyeh i think they removed it…\nAnonymous — May 1, 2014 at 4:24 am (permalink) Anonymous says:\nEnergy, thank you that we find a simple and powerfull solution to build for BB10 and thanks that rim makes it pleasant for developers to build for their OS, appreciate it. amen.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/hands-on-with-the-blackberry-tools-on-the-z10/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/hands-on-with-the-blackberry-tools-on-the-z10/hands-on-with-the-blackberry-tools-on-the-z10-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/hands-on-with-the-blackberry-tools-on-the-z10-large-2.jpg\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/hands-on-with-the-blackberry-tools-on-the-z10/hands-on-with-the-blackberry-tools-on-the-z10-1.jpg\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eNote: skip to the bottom for some instructions on working with the BB Z10.\u003c/p\u003e\n\u003cp\u003eLately we’ve been asked by one of our pro customers to fix some issues which occurred only on the z10 device. I thought this would be an easy task: just grab the tools from the blackberry site and then use them to debug the issue. I was quite wrong… Apparently the emulator can only run in a virtualization environment.\u003c/p\u003e","title":"Hands-on With The Blackberry Tools On The Z10"},{"content":"\nWe constantly try to improve the performance, speed and build speed of the various ports most importantly the iOS port.\nSteve\nfound out a while back during his investigations that the synchronized keyword is especially slow in our iOS port, this is something that isn’t trivial to fix in the port itself. I made some work the past couple of days of mitigating the problem by adding usages of a StringBuilder like class and removing synchronization (which never worked anyway) from TextArea. This provided very dramatic and noticeable performance improvements on iOS.\nThe next thing to do would be to remove the usage of Vector/Hashtable for MUCH faster performance by moving to ArrayList/HashMap both of which are unsynchronized and should boost performance on all devices.\nWhy didn’t we just \u0026ldquo;do it\u0026rdquo;?\nThe main issue is compilability,\nour open source code is compileable on all the platforms we support. But for J2ME/Blackberry this is a bit difficult since our server does quite a bit of heavy lifting. So our goal is to try and place the code that allows translating J2ME/Blackberry code to Java5 into the open source and then start moving forward with proper Java 5 support in the core project.\nI hope we can start doing this soon.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/improving-the-ios-port-moving-to-full-java-5-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/improving-the-ios-port-moving-to-full-java-5-support/improving-the-ios-port-moving-to-full-java-5-support-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Duke\" loading=\"lazy\" src=\"/blog/improving-the-ios-port-moving-to-full-java-5-support/improving-the-ios-port-moving-to-full-java-5-support-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe constantly try to improve the performance, speed and build speed of the various ports most importantly the iOS port.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://sjhannah.com/blog/?p=229\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nSteve\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nfound out a while back during his investigations that the synchronized keyword is especially slow in our iOS port, this is something that isn’t trivial to fix in the port itself. I made some work the past couple of days of mitigating the problem by adding usages of a StringBuilder like class and removing synchronization (which never worked anyway) from TextArea. This provided very dramatic and noticeable performance improvements on iOS.\u003c/p\u003e","title":"Improving The iOS Port – Moving To Full Java 5 Support"},{"content":"\nWe now have new support for GZipInputStream and GZipOutputStream thanks to the great work done by the guys in the\nJZLib\nproject, we ported their work into the project class hierarchy and added a GZConnectionRequest which will automatically unzip an HTTP response if it is indeed gzipped.\nBy default this class doesn’t request gzipped data but its pretty easy to do so just add the HTTP header\nAccept-Encoding: gzip e.g.: GZConnectionRequest con = new GZConnectionRequest(); then con.addRequestHeader(\u0026quot;Accept-Encoding\u0026quot;, \u0026quot;gzip\u0026quot;);\nDo the rest as usual and you should have smaller responses by potential.\nWe thought about adding this capability to the global ConnectionRequest but eventually decided not to do so since it will increase the size of the distribution to everyone. If you do not need the gzip functionality the obfuscator will just strip it out during the compile process.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — June 17, 2013 at 8:31 am (permalink) Anonymous says:\nThis is great news ! I will update my blog post about compression with this, keep up the good work !\nAnonymous — February 6, 2014 at 5:47 am (permalink) Anonymous says:\nIs it also supported on the WebBrowser component when fetching HTML?\nAnonymous — February 7, 2014 at 3:13 am (permalink) Anonymous says:\nSince the web browser uses native connections and doesn’t go thru connection request gzip should \u0026ldquo;just work\u0026rdquo; for that case.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/gzip-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/gzip-support/gzip-support-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Zip\" loading=\"lazy\" src=\"/blog/gzip-support/gzip-support-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe now have new support for GZipInputStream and GZipOutputStream thanks to the great work done by the guys in the\u003cbr\u003e\n\u003ca href=\"https://github.com/ymnk/jzlib\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nJZLib\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nproject, we ported their work into the project class hierarchy and added a GZConnectionRequest which will automatically unzip an HTTP response if it is indeed gzipped.\u003c/p\u003e\n\u003cp\u003eBy default this class doesn’t request gzipped data but its pretty easy to do so just add the HTTP header\u003c/p\u003e","title":"GZip Support"},{"content":"\nApple just announced iOS 7 support the other day and it includes quite a few UI changes. We are already working full speed at incorporating support for iOS 7 before the general availability of the OS and have already released an initial skin through the OTA download feature (it will only work properly with the next plugin update).\nThe trend towards simpler flat design is great since we can now create applications that look good/consistent on all platforms much more easily than we could in the past and we will probably update our themes to incorporate more of the flat design concepts as we move forward.\nKeep in mind when going over the theme that this is work in progress and that at the moment this isn’t applied to the actual device builds, however when the time comes all you will need to do in order to support the feel of iOS 7 would be to send a build to the build server.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — January 2, 2014 at 7:42 pm (permalink) Anonymous says:\nHi CN1,\nthat sounds great! Is there any ETA on the iOS7 skin?\nThanks,\nEmil\nAnonymous — January 3, 2014 at 3:23 am (permalink) Anonymous says:\nIts been there for a while. Just click the More… option in the skins menu.\nAnonymous — January 3, 2014 at 4:02 am (permalink) Anonymous says:\nI am aware that the skin is available in the simulator. I was referring to the device still using the old skin; sorry for being unclear 🙂\nAnonymous — January 4, 2014 at 6:09 am (permalink) Anonymous says:\nYou need to define the build argument ios.themeMode to modern or just wait a couple of weeks till we flip the switch to make iOS 7 the default.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/ios-7-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/ios-7-support/ios-7-support-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/ios-7-support-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/ios-7-support/ios-7-support-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eApple just announced iOS 7 support the other day and it includes quite a few UI changes. We are already working full speed at incorporating support for iOS 7 before the general availability of the OS and have already released an initial skin through the OTA download feature (it will only work properly with the next plugin update).\u003c/p\u003e\n\u003cp\u003eThe trend towards simpler flat design is great since we can now create applications that look good/consistent on all platforms much more easily than we could in the past and we will probably update our themes to incorporate more of the flat design concepts as we move forward.\u003c/p\u003e","title":"iOS 7 Support"},{"content":"\nCodename One Maker is a pretty elaborate app, there is only so far we can go with simplifying the app itself.\nSo we added a tutorial mode which is common in mobile/web apps\n, to walk the user through the process of creating a simple application and using the GUI builder (we also added a\nUdemy course\nbut I digress). This feature is probably useful for almost every app out there, so here is how you can achieve that with Codename One…\nThere are generally two approaches for laying an overlay:\nGlass pane – this is how we used to do things in the old days, its powerful but has many limitations. You essentially need to draw everything using graphics.\nA glass pane is just a \u0026ldquo;layer\u0026rdquo; on top of all components that you can draw on. It might seem that you can \u0026ldquo;emulate\u0026rdquo; the glass pane by overriding the paint method in Form and that would indeed work for simple use cases however the glass pane is \u0026ldquo;clever\u0026rdquo; and knows how to repaint itself when a component is updated (e.g. if a ticker is running the whole form won’t repaint so glass pane will work but overriding Form paint would not!).\nLayered layout – this is a more \u0026ldquo;modern\u0026rdquo; approach we take where we essentially place two containers in a LayeredLayout and the last one added remains on top.\nGenerally the glass pane is not interactive (it just draws) where the layered layout can actually grab input etc. we made use of the layered layout in a previous post (\nwhen a dialog is no a dialog\n). In this case though, I chose to use a glass pane mostly because I was too lazy to go back to every form and add a layered layout to the hierarchy\nYou will notice several interesting things about the tutorial mode. We added an option to \u0026ldquo;swipe\u0026rdquo; out of the tutorial mode at any time (this is the bottom portion starting at line 47).\nWe draw everything manually in the glass pane (that’s how it works).\nYou will notice that some sections accept null as the highlight component, this can happen when we use the title as the highlight component on Android 4.x.\nNewer Android devices use the native action bar for the title and so will return null when we query for the title area.\nWe hope this is useful for you when building your apps.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — July 23, 2014 at 8:21 am (permalink) Anonymous says:\nI used this code snippet with a highlightComponent = null, and the glasspane with the text appears as it should – it’s a very coll feature. I can’t swipe out though. I’m not sure I understand the swipe logic. Can you explain how it works ?\nAnonymous — July 23, 2014 at 12:25 pm (permalink) Anonymous says:\nWe add a pointer dragged listener to the parent form as you see at the bottom of the source. If a user swipes a 5th of the screen from left to right the tutorial should end.\nAre you getting the pointer events? Should be pretty easy to debug if this is causing issues in the simulator.\nAnonymous — July 23, 2014 at 6:14 pm (permalink) Anonymous says:\nI’ve got a side menu on the form and swiping left to right exposes the side menu form, so I guess it’s the order in which pointer dragged events are consumed.\nAnonymous — July 24, 2014 at 3:29 am (permalink) Anonymous says:\nYes, this predated the sidemenu by a while. You can just edit that logic to work with a different gesture or a tap on a specific screen location.\nAnonymous — July 24, 2014 at 3:53 am (permalink) Anonymous says:\nOK – I changed the logic to swipe right to left and works well. Where would you normally call showTutorialOverlay() ? I have a call in postShow for the form but wonder if that’s what you had in mind as a use case.\nAnonymous — July 24, 2014 at 2:12 pm (permalink) Anonymous says:\nPost show should work out nicely.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/walk-thru-tutorial/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/walk-thru-tutorial/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eCodename One Maker is a pretty elaborate app, there is only so far we can go with simplifying the app itself.\u003c/p\u003e\n\u003cp\u003eSo we added a tutorial mode which is common in mobile/web apps\u003c/p\u003e\n\u003cp\u003e, to walk the user through the process of creating a simple application and using the GUI builder (we also added a\u003cbr\u003e\n\u003ca href=\"https://www.udemy.com/cn1maker\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nUdemy course\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nbut I digress). This feature is probably useful for almost every app out there, so here is how you can achieve that with Codename One…\u003c/p\u003e","title":"Walk-thru Tutorial"},{"content":"\nWe’ve got many requests in the past year for a cryptography API, initially we thought about adding something like this to the core but it seems somewhat niche so we decided to wrap up this great open source project and re-package it as a CodenameOne lib.The project is supported on all CodenameOne platforms right out of the box without any changes.\nYou can download the full source code as well as a compiled binary from a Google code project here:\nhttps://code.google.com/p/bouncy-castle-codenameone-lib/\nand you can download the compiled binary from here:\nBouncyCastleCN1Lib.cn1lib\n(since Google removed the download section for new projects).\nYou can learn more about bouncy castle and how to use it through the\nmany resources on available here:\nhttp://www.bouncycastle.org/\nHappy coding!\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — June 27, 2013 at 5:43 pm (permalink) Anonymous says:\nthis is a very valuable addition !\nAnonymous — January 15, 2014 at 9:54 pm (permalink) Anonymous says:\ncan you please tell me, how i can get sha1 or md5 hashing of a string using this lib?\nAnonymous — January 16, 2014 at 4:12 am (permalink) Anonymous says:\nDid you try this:\nhttps://www.google.com/sear…\nAnonymous — October 26, 2014 at 6:27 am (permalink) Anonymous says:\nI tried to search for AES string encription, but all examples forces me to use java.security.* (and I already have a working class for android written purely with java.security/javax.crypto)), I need one for Your platform to cover the iPhone), which in return results with an error during compiling (error: package java.security does not exist). BouncyCastle is installed. Any example written PURELY with BouncyCastle?\nAnonymous — October 26, 2014 at 9:44 am (permalink) Anonymous says:\nDid you try searching our discussion forum for aes?\nhttps://groups.google.com/f…\nAnonymous — October 26, 2014 at 3:52 pm (permalink) Anonymous says:\nActually, I did not. Thanks.\nKaya TC — March 7, 2016 at 11:21 am (permalink) Kaya TC says:\nIm having difficulties to Hash a passwordfield, i searched google for a while now, but the examples are not for cn1.\nI could not find some classes which are in the examples so im stuck now.\nI just want to have a SHA hash =)\nShai Almog — March 8, 2016 at 3:31 am (permalink) Shai Almog says:\nI think this contains some examples which might be helpful:\nhttp://www.programcreek.com…\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/bouncy-castle-crypto-api/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/bouncy-castle-crypto-api/bouncy-castle-crypto-api-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/bouncy-castle-crypto-api/bouncy-castle-crypto-api-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve got many requests in the past year for a cryptography API, initially we thought about adding something like this to the core but it seems somewhat niche so we decided to wrap up this great open source project and re-package it as a CodenameOne lib.The project is supported on all CodenameOne platforms right out of the box without any changes.\u003c/p\u003e\n\u003cp\u003eYou can download the full source code as well as a compiled binary from a Google code project here:\u003cbr\u003e\n\u003ca href=\"https://code.google.com/p/bouncy-castle-codenameone-lib/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nhttps://code.google.com/p/bouncy-castle-codenameone-lib/\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nand you can download the compiled binary from here:\u003cbr\u003e\n\u003ca href=\"/files/BouncyCastleCN1Lib.cn1lib\"\u003eBouncyCastleCN1Lib.cn1lib\u003c/a\u003e\u003cbr\u003e\n(since Google removed the download section for new projects).\u003c/p\u003e","title":"Bouncy Castle Crypto API"},{"content":"\nOne of the things we’ve been working on with Maker is getting the new GUI builder to support hierarchies/layouts which should be landing tomorrow or so. When we initially built the GUI builder within the Codename One designer we made many mistakes but one of the big ones was with layouts, it takes too long to see how a layout affects something (you need to physically accept a dialog/rinse repeat) so people just don’t experiment enough with the options.\nIn Maker we intend to fix that, by providing\nthe UI you see in the video and the image. Essentially when you spin the spinner the layout changes automatically and animates the components into place giving a clear indication of the change between positions (if they \u0026ldquo;jump\u0026rdquo; its harder to notice differences in some cases).\nThe problem is that a \u0026ldquo;normal\u0026rdquo; dialog doesn’t allow for this UI, it doesn’t allow an \u0026ldquo;always on top\u0026rdquo; window and it doesn’t really allow the underlying form to \u0026ldquo;animate\u0026rdquo;. If you will study the code the reasoning for that will become crystal clear: a dialog is really a Form that takes up the entire screen and just \u0026ldquo;draws\u0026rdquo; the previous form behind. Since the previous form is \u0026ldquo;deinitialize\u0026rdquo; it just won’t run most of the animations (to preserve CPU). This was done ages ago with a very specific set of use cases in mind and its generally very efficient but we just can’t implement something like this using this approach.\nSo how did we implement this feature?\nWe used LayeredLayout.\nThe LayeredLayout allows placing components one on top of the other. So we created a LayeredLayout and when time came to show the fake dialog we just did something similar to this:\nAs you can see the \u0026ldquo;Dialog\u0026rdquo; is just a container with the right UIID and some additional components faking the title and content pane.\nWe place it in the correct location by using a layout\nmanager and we can animate it into place (and out) by using layout animations or replace (for disposing the dialog).\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — June 8, 2013 at 11:17 am (permalink) Anonymous says:\nGreat job. have been waiting for something like this.\nThanks.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/when-a-dialog-isnt-a-dialog/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/when-a-dialog-isnt-a-dialog/when-a-dialog-isnt-a-dialog-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/when-a-dialog-isnt-a-dialog-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Fake dialog with spinner\" loading=\"lazy\" src=\"/blog/when-a-dialog-isnt-a-dialog/when-a-dialog-isnt-a-dialog-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eOne of the things we’ve been working on with Maker is getting the new GUI builder to support hierarchies/layouts which should be landing tomorrow or so. When we initially built the GUI builder within the Codename One designer we made many mistakes but one of the big ones was with layouts, it takes too long to see how a layout affects something (you need to physically accept a dialog/rinse repeat) so people just don’t experiment enough with the options.\u003c/p\u003e","title":"When A Dialog Isn't A Dialog"},{"content":"\nThe PC isn’t going away tomorrow but I think we took a major step in reducing the need for it when building some applications in the upcoming version of Maker. We just launched a very preliminary preview of our new Drag \u0026amp; Drop form designer for Maker. This is pretty rough early on, but having built quite a few GUI builders I can tell you that its 90% there!\nYou can drag elements into place, yes they are all in a vertical layout (BoxLayout Y) and there is no container hierarchy (yet) but the infrastructure is there and its already looking better than our current GUI builder looked at that stage!\nStay tuned and as usual we really appreciate your feedback.\nArguably the more interesting story is the plugin suppor\nt. As Codename One developers you can now build plugins for Maker using Codename One \u0026amp; NetBeans!\nThis effectively turns Maker into a tool that is limited only by your imagination and not by some arbitrary constraints we put forth.\nOne thing to keep in mind before proceeding:\nA plugin can’t be previewed within Maker. The user will be able to pass arguments (settings) to the plugin and see it within the app but he won’t be able to launch it (we can’t dynamically download code according to store EULA’s and also some technical limitations).\nSo how does this work?\nA Codename One Maker\nplugin is really just 2 files an XML file and a CN1Lib file.\nThe XML file describes\nthe requirements of the plugin from the user and gives us basic details about the plugin, only the XML file is ever downloaded to the device.\nWhen the user sends the build, the details are sent to the server. The server downloads and incorporates the CN1Lib file which can include native code or any other capabilities. Its compiled like any Codename One library in that regard. When the built application on the device the user can see the plugin\nin action.\nSo how do we build a hello world plugin?\nI created a simple Twitter feed plugin just to show the basic principals (see the full project at the bottom of this post). To start off we need to create a new Library Project in NetBeans (sorry currently Eclipse doesn’t support Library projects although its theoretically possible to work with it to build these projects).\nWe can remove the hello world code and create a new package with our company and name of the plugin, then we need to implement the plugin. The plugin is a class that derives from MakerPlugin here is the simple Twitter plugin from the code below.\nNotice the overriden methods above are a part of the plugin interface, once we are in the plugin itself we can just write any Codename One code that we want although keep in mind that I try not to block the execution thread… Otherwise I might create an unpleasant experience when building a tabs based application.\nAlso notice that I enable scrollability since the parent form won’t be accessible we disabled scrolling there (to avoid nested scrolling issues), if you need scrolling you need to explicitly declare it.\nIts probably obvious but bares stating that the plugin class must be public, have a no argument constructor (or no constructor which is the same thing) and mustn’t be abstract.\nYou will also need one more file which is the xml descriptor file, in my case its twitter.mplugin (in the root of the downloaded file) which you can see right here:\nNotice several things:\nWe declare the maker version, this is crucial since if someone hasn’t updated Maker on the device and your plugin expects a specific version… It should fail to install.\nThe package name and the class name must match exactly your class since that is how we generate the plugin calls on the server!\nThe cn1lib entry MUST point at an absolute URL where the plugin can be downloaded from, the download only happens on the build server so the build will fail if the file isn’t accessible.\nYou can define as many arguments as you want but currently all of them must be strings, we are working on adding more options in the future.\nI hope this has been educational for you and I hope we all start building Codename One plugins soon!\n__Download\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — June 3, 2013 at 4:19 am (permalink) Anonymous says:\nHi, this looks really exciting! Is there also support for these plugins in the desktop Designer tool?\nAnonymous — June 3, 2013 at 1:26 pm (permalink) Anonymous says:\nThanks!\nWe have some plans to support custom components via the libraries support. There is already some code within the designer to allow that. However, playing around with Maker has made me realize how outdated the designer is and we are starting to seriously consider a total rewrite. Its not ideal but it will allow us to consolidate a lot of code and increase the stability (through dogfooding).\nIt would also allow us to run on the actual devices directly which is a huge bonus. Best of all, we can connect to the PC/Mac and transfer files directly to the device since we already have the plugin installed.\nThe only issue is rewriting all the logic but that’s not too bad since the current UI is horrible.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/maker-on-device-drag-drop-gui-builder-external-3rd-party-plugins/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/maker-on-device-drag-drop-gui-builder-external-3rd-party-plugins/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe PC isn’t going away tomorrow but I think we took a major step in reducing the need for it when building some applications in the upcoming version of Maker. We just launched a very preliminary preview of our new Drag \u0026amp; Drop form designer for Maker. This is pretty rough early on, but having built quite a few GUI builders I can tell you that its 90% there!\u003c/p\u003e","title":"Maker: On Device Drag \u0026 Drop GUI Builder + External 3rd Party Plugins!"},{"content":"\nWe just released an initial preview of\nCodename One Maker into Google Play\nto start soliciting feedback on what we got wrong and what we need to improve. Let us know what you think and how we can improve it in the future.\nWe already intend to produce some of the following:\nDrag and drop form builder – this won’t be a full fledged GUI builder (which requires real coding) but rather a simple way to create custom forms\nPlugins – will allow Codename One developers to create libraries that can be integrated into the built applications!\nDownloadable themes\nOn device theme customization/creation\nWizards to create more fleshed out applications from websites, blogs and social networks\nWhat do you think is most important, what do you think is missing?\nAs a side note we submitted the app to Apple and got rejected because we aren’t allowed to mention any other platforms on iOS (no blackberry or android mention). So the iOS users would only be able to build iOS apps (assuming we get approved)… Thanks Apple.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-maker-is-now-live-on-google-play/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-maker-is-now-live-on-google-play/codename-one-maker-is-now-live-on-google-play-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://play.google.com/store/apps/details?id=com.codenameone.apps.maker\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/codename-one-maker-is-now-live-on-google-play/codename-one-maker-is-now-live-on-google-play-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eWe just released an initial preview of\u003cbr\u003e\n\u003ca href=\"https://play.google.com/store/apps/details?id=com.codenameone.apps.maker\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nCodename One Maker into Google Play\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nto start soliciting feedback on what we got wrong and what we need to improve. Let us know what you think and how we can improve it in the future.\u003c/p\u003e\n\u003cp\u003eWe already intend to produce some of the following:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eDrag and drop form builder – this won’t be a full fledged GUI builder (which requires real coding) but rather a simple way to create custom forms\u003c/p\u003e","title":"Codename One Maker Is Now Live On Google Play"},{"content":"\nWe are about to release a brand new product:\nMaker\n. Codename One Maker is an App that allows non-developers to build native applications directly from their mobile phone or tablet by using the Codename One backend.\nThe tool is relatively simple and produces \u0026ldquo;cookie cutter\u0026rdquo; applications, however we think that you would be able to build amazing plugins to make the tool truly powerful\n. We intend to introduce a plugin architecture based on our Codename One libraries that will allow you to build extensions to Maker using our standard Java API and native code.\nFor now Maker contains an option to get the Codename One source code upon build completion which will allow novices to prototype the applications they want then give a developer the source code in order to get the professional features into place. Let us know what you think in the comments below.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — May 23, 2013 at 5:20 am (permalink) Anonymous says:\nThis is great news, I know so many people will have a good opportunity to air their opinions via ‘mobile development’ good work team Codename One…\nAnonymous — May 23, 2013 at 1:01 pm (permalink) Anonymous says:\nGreat, I travel a lot and I’ll be able to prototype from my tablet, then code on eclipse. Also my business partner who dont program will be able to prototype =)\nAnonymous — May 24, 2013 at 3:32 am (permalink) Anonymous says:\nthats so cool…. i think this is a huge step… the revolution to mobile and more so android programming\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/introducing-codename-one-maker/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/introducing-codename-one-maker/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe are about to release a brand new product:\u003cbr\u003e\n\u003ca href=\"/maker.html\"\u003e\u003cbr\u003e\nMaker\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n. Codename One Maker is an App that allows non-developers to build native applications directly from their mobile phone or tablet by using the Codename One backend.\u003c/p\u003e\n\u003cp\u003eThe tool is relatively simple and produces \u0026ldquo;cookie cutter\u0026rdquo; applications, however we think that you would be able to build amazing plugins to make the tool truly powerful\u003c/p\u003e\n\u003cp\u003e. We intend to introduce a plugin architecture based on our Codename One libraries that will allow you to build extensions to Maker using our standard Java API and native code.\u003c/p\u003e","title":"Introducing Codename One Maker"},{"content":"\nMobile development platform Codename One is announcing the release of its 1.1 version on Monday, May 20th. Less than 4 months after releasing its 1.0 version, Codename One doubled its user base becoming the 5th most downloaded NetBeans plugin of all time and more than doubling builds on its cloud servers month over month.\nCodename One is a one of a kind solution that allows Java developers to build native applications that work on all mobile devices seamlessly, it combines an open source client architecture that integrates with industry standards Eclipse/NetBeans with a one of a kind cloud build system. This unique architecture enables Java developers to build iPhone applications without owning a Mac or Windows Phone applications without a Windows 8 machine.\nVersion 1.1 solidifies Codename One as the technological market leader in Write Once Run Everywhere (WORA) on mobile devices with key features such as: Windows Phone 8 support, 3rd party Library Support, many UI improvements and tools to assist development.\nThe platform to date has been used to build over 2,000 native mobile applications and has received widespread, viral acclaim in technology and business media including InfoWorld, Slashdot, Hacker News, VentureBeat, Business Insider, The Next Web, Dr. Dobbs and Forbes, which named the company one of the 10 greatest industry disrupting startups of 2012.\n_\n\u0026ldquo;It is amazing that within 4 months since our 1.0 doubled or more on every single KPI, we have some amazing plans for the future and expect to exceed that many times over.\u0026rdquo;\n_\nsaid co-founder and CEO Shai Almog.\nAlmog, along with co-founder Chen Fishbein, decided to launch the venture after noticing a growing inefficiency within mobile application development. By enabling developers to significantly cut time and costs in developing native applications for iOS, Android, Blackberry, Windows Phone and other devices, Almog and Fishbein hope to make mobile application development increasingly feasible.\nThe Java-based platform is open-source and utilizes lightweight technology, allowing it to produce unique native interfaces highly differentiated from competitive cross-platform mobile development toolkits, which typically use HTML5 or heavyweight technology.\nBy drawing all components from scratch rather than utilizing native widgets, Codename One enables developers to avoid fragmentation – a major hindrance found in the majority of competitors – and additionally allows accurate desktop simulation of mobile apps.\nThe startup’s founders are recognized for engineering Sun Microsystems’s famous Lightweight User Interface Toolkit, a mobile platform used by leading mobile carriers and industry leaders to this date.\nCodename One is available for download free of charge.\n**\nAbout Codename One\n**\nCodename One, named by Forbes as \u0026ldquo;one of the 10 greatest industry disrupting startups of 2012,\u0026rdquo; is an Israel-based technology company that has created a powerful cross-platform software development kit for mobile applications. The technology enables developers to create native applications across multiple operating systems using a single code base. Codename One was founded by renowned software engineers Shai Almog and Chen Fishbein in 2012.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/with-200000-sdk-downloads-mobile-development-platform-codename-one-announces-version-11/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/with-200000-sdk-downloads-mobile-development-platform-codename-one-announces-version-11/codename-one-charts-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eMobile development platform Codename One is announcing the release of its 1.1 version on Monday, May 20th. Less than 4 months after releasing its 1.0 version, Codename One doubled its user base becoming the 5th most downloaded NetBeans plugin of all time and more than doubling builds on its cloud servers month over month.\u003c/p\u003e\n\u003cp\u003eCodename One is a one of a kind solution that allows Java developers to build native applications that work on all mobile devices seamlessly, it combines an open source client architecture that integrates with industry standards Eclipse/NetBeans with a one of a kind cloud build system. This unique architecture enables Java developers to build iPhone applications without owning a Mac or Windows Phone applications without a Windows 8 machine.\u003c/p\u003e","title":"With 200,000 SDK Downloads, Mobile Development Platform Codename One Announces Version 1.1"},{"content":"\nWe are working on something exciting, more on that next week (hopefully). One of the things we needed was a way to access files on a device, e.g. images, etc. however this is a painful and fragmented subject.\nMost of my files are still on my laptop and not on my tablet or phone and moving them back and forth isn’t\nconvenient… Luckily we have\nDropbox\n, this neat tool has really helped us collaborate as a startup and has made many painful things remarkably easy.\nSo Chen came up with an amazing plugin that allows us to treat drop box as yet another file system we can use to extract files from!\n(He made use of some excellent work contributed to the community by\nEric Coolman\nfor Oauth 1.x support!).\nThis is absolutely spectacular and hugely convenient!\nYou can download his source code\nhere\nits a Codename One Library project so you just compile it in NetBeans then add it to the lib directory of either Eclipse or NetBeans. Then right click the project\nand press refresh libs and it should \u0026ldquo;just work\u0026rdquo;.\nThis is a brand new project and Chen would love some contributions and collaborations there so feel free to contribute.\nSo how do you use it?\nFirst you need to create a Dropbox core application\nhere\n, this will give you the two keys you need below. Keep in mind that in order to use it for more than one account you will need to select an option during the process and in order to use it in production you will need specific approval.\n**\nNotice:\n**\nfor this code to work properly you will need a \u0026ldquo;proper\u0026rdquo; browser component, so you will need Java 7 to be configured properly with FX so the browser component will work as expected on the simulator.\nFirst you just need to login:\nThe code above logs in to Dropbox then invokes the Dropbox file picker code which I’ll show you below using our tree component.\nThe code below completes the picture by creating a file picker tree allowing\nus to download a file from dropbox and do whatever we please with it!\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — May 16, 2013 at 9:20 pm (permalink) Anonymous says:\nThis is all great. Also I want to know when are you going to support the new Asha software platform? Or are you going to support it at all?\nAnonymous — May 17, 2013 at 6:19 pm (permalink) Anonymous says:\nJ2ME platform is supported, what feature are you missing?\nAnonymous — October 31, 2013 at 11:43 am (permalink) Anonymous says:\nDear Chen,\nI would like to discuss with you in detail features of your plugin and its possible use in the application we are developing. Please contact me ASAP.\nBest regards,\nIbrokhim\nAnonymous — January 24, 2014 at 11:44 am (permalink) Anonymous says:\nIs it possible to upload a file as well?\nAnonymous — January 24, 2014 at 3:40 pm (permalink) Anonymous says:\nNot at the moment although it should be doable in theory.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/drop-it-introducing-dropbox-integration/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/drop-it-introducing-dropbox-integration/drop-it-introducing-dropbox-integration-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://code.google.com/p/dropbox-codenameone-sdk/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Dropbox\" loading=\"lazy\" src=\"/blog/drop-it-introducing-dropbox-integration/drop-it-introducing-dropbox-integration-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eWe are working on something exciting, more on that next week (hopefully). One of the things we needed was a way to access files on a device, e.g. images, etc. however this is a painful and fragmented subject.\u003c/p\u003e\n\u003cp\u003eMost of my files are still on my laptop and not on my tablet or phone and moving them back and forth isn’t\u003c/p\u003e\n\u003cp\u003econvenient… Luckily we have\u003cbr\u003e\n\u003ca href=\"https://code.google.com/p/dropbox-codenameone-sdk/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nDropbox\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, this neat tool has really helped us collaborate as a startup and has made many painful things remarkably easy.\u003c/p\u003e","title":"Drop It – Introducing Dropbox Integration"},{"content":"\nAs part of our preparation for the 1.1 version of Codename One we are accelerating our typical release cycle so we can test against regressions as soon as possible. We plan to make a release within this month for versions 1.1.\nThe final feature set for 1.1 should include the following highlights:\n3rd party Library support\n[\nWindows Phone 8 support\n](http://www.codenameone.com/3/post/2013/04/windows-phone-8-and-the-state-of-7.html)\nSide menu functionality\nPull to refresh\nOTA Device Skin downloads\nS40 Improvements\nCloud object viewer tool\nComponent inspector tool\nOn/Off Switch\nPingjam integration\n(And maybe a couple of additional surprises!)\nSo if you run into an issue in the next couple of weeks please\n**\ncontact us immediately\n**\nso we can squash it before the release. Thanks!\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/getting-ready-for-11/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/getting-ready-for-11/codename-one-charts-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eAs part of our preparation for the 1.1 version of Codename One we are accelerating our typical release cycle so we can test against regressions as soon as possible. We plan to make a release within this month for versions 1.1.\u003c/p\u003e\n\u003cp\u003eThe final feature set for 1.1 should include the following highlights:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"http://www.codenameone.com/3/post/2013/02/new-preliminary-library-support.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\n3rd party Library support\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e[\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eWindows Phone 8 support\u003c/p\u003e\n\u003cp\u003e](\u003ca href=\"http://www.codenameone.com/3/post/2013/04/windows-phone-8-and-the-state-of-7.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttp://www.codenameone.com/3/post/2013/04/windows-phone-8-and-the-state-of-7.html\u003c/a\u003e)\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"http://www.codenameone.com/3/post/2013/02/hamburger-sidemenu.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nSide menu functionality\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e","title":"Getting Ready For 1.1"},{"content":"\nWorking with the\nCloud Object API\ncan sometimes be difficult. The data isn’t tabular and understanding the concepts such as indexes and scopes for such objects is pretty hard.\nTo help alleviate this difficulty Chen built a tool right into the Codename One simulator that allows you to query the cloud storage for the current application and helps you review some of the complexities involved.\nYou can query various application scopes, if you don’t enter an object type you will receive all objects but only for the private/application scopes (otherwise you would just get too much information). Notice that when you sort based on an index if the index is missing an entry just won’t appear so keep that in mind.\nWe have great plans for this API, including features for map-reduce like functionality to allow you to build complex data manipulation logic without having to setup any server infrastructure.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/cloud-object-viewer/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/cloud-object-viewer/cloud-object-viewer-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/cloud-object-viewer-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/cloud-object-viewer/cloud-object-viewer-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eWorking with the\u003cbr\u003e\n\u003ca href=\"/javadoc/com/codename1/cloud/package-summary.html\"\u003e\u003cbr\u003e\nCloud Object API\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\ncan sometimes be difficult. The data isn’t tabular and understanding the concepts such as indexes and scopes for such objects is pretty hard.\u003c/p\u003e\n\u003cp\u003eTo help alleviate this difficulty Chen built a tool right into the Codename One simulator that allows you to query the cloud storage for the current application and helps you review some of the complexities involved.\u003c/p\u003e\n\u003cp\u003eYou can query various application scopes, if you don’t enter an object type you will receive all objects but only for the private/application scopes (otherwise you would just get too much information). Notice that when you sort based on an index if the index is missing an entry just won’t appear so keep that in mind.\u003c/p\u003e","title":"Cloud Object Viewer"},{"content":"\nWe have many interesting ways for you to make money using Codename One and\npingjam\nis one of the most innovative ways we ran into.\nPingjam\nads are placed within the dialer window based on the number you are dialing to, e.g. you dial to purchase a pizza you might get an ad offering a discount for purchasing over the web!\nThis means\na great CTR rate since users receive ads that are very relevant just when they are about to make a purchase!\n**\nYou get paid for the number of active installs\n**\nPingjam\n‘s innovation\ndoesn’t stop there. Unlike other ad networks it doesn’t pay out per click but rather per install similarly to the\nstartapp\nmodel which allows you to rely on a monthly payment of a predictable sum without being concerned about ad visibility. Pingjam pays $5/month for every 1000 active app installs in the USA and Canada (or $1 elsewhere). Note that your revenue is based on how many active installs you have, and not whether your users see or click on any of the ads. You get paid regardless of whether your app was used during the month. In essence, Pingjam pays you for distributing their service.\nOne of the nicest things about\nour current monetization methods is that they all can be used together and do not conflict with one another so you can have multiple concurrent revenue streams!\nNotice that once the application is removed pingjam is uninstalled cleanly and does not leave a mark on the phone/dialer.\nPingjam\nis currently only available on Android for obvious reasons, to set it up all you need to do is sign up in their website and then go to the right click settings section in the monetization dialog (NetBeans only at the moment) and set your advertiser key in that section (the update containing that feature will be released April 30th).\nAccording to Pingjam, the addition of the caller ID service does not impact install rates at all:\nWe have proven this by running extensive tests on hundreds of thousands of installs and dozens of apps. The results were conclusive – install rates are unchanged and uninstall rates aren’t affected.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — April 29, 2013 at 8:53 pm (permalink) Anonymous says:\nSounds good to be true 🙂\nBut how about this statement: \u0026ldquo;Only one app will get the credit per device; if multiple apps have pingjam enabled, the credit will go to the first app that was installed.\u0026rdquo;\nThe source is here: http://support.andromo.com/…\nAnonymous — April 30, 2013 at 12:52 am (permalink) Anonymous says:\nIts similar to startapp in that sense, they pay \u0026ldquo;rent\u0026rdquo; for the ad space and the app that \u0026ldquo;owns\u0026rdquo; that space is the first one where the user accepted the terms (probably first one installed).\nHowever, if the first app was removed then your app will start receiving the payments for that device.\nAnother benefit is that this is a relatively young network so your chances of reaching a \u0026ldquo;virgin\u0026rdquo; device are very high.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/pingjam-a-new-way-to-make-money-on-ads/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/pingjam-a-new-way-to-make-money-on-ads/pingjam-a-new-way-to-make-money-on-ads-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/pingjam-a-new-way-to-make-money-on-ads-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/pingjam-a-new-way-to-make-money-on-ads/pingjam-a-new-way-to-make-money-on-ads-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eWe have many interesting ways for you to make money using Codename One and\u003cbr\u003e\n\u003ca href=\"http://get.pingjam.com/codenameone\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\npingjam\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nis one of the most innovative ways we ran into.\u003cbr\u003e\n\u003ca href=\"http://get.pingjam.com/codenameone\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nPingjam\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nads are placed within the dialer window based on the number you are dialing to, e.g. you dial to purchase a pizza you might get an ad offering a discount for purchasing over the web!\u003c/p\u003e\n\u003cp\u003eThis means\u003c/p\u003e","title":"Pingjam: A New Way To Make Money On Ads"},{"content":"\nIs J2ME dead or dying?\nHow many times have we heard this for the past 3 years or so? Sadly the answer is: Yes!\nUnfortunately there is no active owner for the J2ME standard and thus no new innovation around J2ME for quite some time (MIDP 2.0 came out in 2004, 3.0 never really materialized). Android is/was the biggest innovation since and became the unofficial successor to J2ME.\nWell, if J2ME is dead what about Feature Phones? Should we care about them?\nThe answer is: Yes! very much so!\nFeatures Phones are still selling in millions and still beats Android sales in the developing world.Recently Nokia shipped the Asha series devices which are quite powerful and capable pieces of hardware, they are very impressive. Nokia’s revenue is driven mainly by the Feature Phone market.\nThere is a real battle in the developing countries between Feature Phones and Android devices, Feature Phones are still cheaper and more efficient where Android has more/better content (apps \u0026amp; games).\nHow long will it take Android to catch up? we will see…\nIn the meantime there is money on the table and a real opportunity for developers to make some money (and gain loyal users who will migrate to Android or other platform at some point)\nTo win over the competition or at least to maintain its dominate player position Nokia must bring new quality content to the devices, it’s not enough to ship cool new feature phones, the new phone needs to connect to facebook, twitter, gmail, whatsapp and have all the new cool games/apps Android has and more.\nSo how should you write your apps for the cool new Nokia Feature Phone if J2ME is dead? Luckily there is an option Codename One ;-).\nIn Codename One You have 1 Java API which is the same for J2ME, Android, iOS, Blackberry and Win8.\nBelow are some of the J2ME highlights:\nFacebook Connect – did you noticed there aren’t many social apps on OVI? There is a reason Facebook uses oauth2 which is a huge pain without a browser API, this is solved and working in Codename One. 2. Java 5 features – You can use generics and other Java 5 features in your app and it will work on your J2ME/Blackberry devices. You don’t have to limit yourself to CLDC. 3. Rich UI – If you know or knew LWUIT (Swing like API), well Codename One UI is effectively LWUIT 2.0. 4. Built in Asha skins and themes\nThe most important thing is the fact that your skills are not wasted on an old/dying J2ME API, by joining our growing community and writing the next amazing app your skills can target the emerging platforms of the present/future.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — April 24, 2013 at 5:09 am (permalink) Anonymous says:\nThat is a good possibility to develop j2me functionalities/apps through codename one, but also i don’t think that j2me is really dying…\nHave a look:\nhttp://www.oracle.com/techn…\nhttp://www.netmarketshare.c…\nAnonymous — April 24, 2013 at 6:51 am (permalink) Anonymous says:\nj2me is already dead, you would get laughed at by any serious developer if you told them you still programmed in it.\nAnonymous — April 24, 2013 at 7:31 am (permalink) Anonymous says:\nbut i would not tell them 🙂\nAnonymous — April 24, 2013 at 7:39 am (permalink) Anonymous says:\nWe actually agree with that, we try not to list it anywhere on our site because of that (even though we still support it).\nI recently had the pleasure to meet one of the guys working on the feature phone platform for Facebook (based on their Snaptu acquisition) and he surprised me by saying that they still see growth in the feature phone version… This is pretty amazing, I would have expected decline but this is apparently still to come.\nTo be clear, I would never target J2ME as my main platform but if we can get there for almost free that could be interesting.\nAnonymous — April 24, 2013 at 7:39 am (permalink) Anonymous says:\nJust show the numbers and they will stop laughing, also, it is way easier to get a better spot for your app at Nokia OVI store than the others\nAnonymous — April 24, 2013 at 9:37 am (permalink) Anonymous says:\nHey everyone,\nShai really cool read by the way. It’s funny how the situation changes from country to country, Where I live in, you still see lots and lots of people with Nokia s40 phones even though Android, iOS and Windows Phones are getting a whole lot more common. I think it’s great you guys support the J2ME through Codename One even if not to the level of the other platforms because it gives us as developers the possibility to reach an even bigger market without the effort of having to learn it or the obligation of targeting as a main platform.\nI think you guys are doing a marvelous job with Codename One and I really hope to see it grow and support a whole lot of different stuff there’s still left to explore. Keep up the great work!\nAnonymous — April 24, 2013 at 10:24 am (permalink) Anonymous says:\nIsn’t it a simple case of demand? Just because a technology is good, doesn’t mean it will last forever. If the majority of the market is no longer supporting or working with J2ME, then developers will disappear and products will disappear. Of course, as the article says, there is still a market for J2ME software, the market is just a fraction of what it used to be.\nAnonymous — April 24, 2013 at 12:34 pm (permalink) Anonymous says:\nSamsung is now prepared to compete with Nokia Asha in the feature phone market with the recent release of 4 new full touch devices, the Rex 60, 70, 80, and 90.\nAnonymous — May 1, 2013 at 6:54 am (permalink) Anonymous says:\nIn this part of the world, Nigeria, j2me is still alive but whether it will remain or not is the question.\nNokia and Tecno are making huge sales quarterly in Africa, with over 10 million sales in one quarter.\nMy app got over 2000 downloads in few weeks of release to the Nokia Store, without any publicity.\nIf Codenameone really wanna support Asha devices, I think they should implement some of the Asha specific APIs.\nI had to create a native app for my Nearest Locator mobile app in other to fully maximize the Asha LPS feature.\nAnonymous — May 16, 2013 at 9:22 pm (permalink) Anonymous says:\nDoes Codename One support the new Asha platform in Asha 501?\nAnonymous — May 17, 2013 at 1:45 am (permalink) Anonymous says:\nYes, it supports all asha series\nAnonymous — September 26, 2013 at 6:58 am (permalink) Anonymous says:\nits sad to know that j2me may soon go into oblivion. i love the m3g based 3d games which i think are simpler to make compared to open gl es which is quite popular now. I was hoping to release a good number of 3d apps based on m3g on j2me platform in Nigeria but i guess i’have to port to android os or IOS and i am not happy about that. I love m3g on j2me,i wish it was available on android or Ios instead of open gl es.\nAnonymous — October 9, 2013 at 11:32 am (permalink) Anonymous says:\nI wouldn’t say that with full confidence. Javascript wasn’t considered a serious language to develop except to make a website more interactive. Look at it now, it’s part of a serious platform tool to develop mobile apps that will allow a single source base to run on the two most popular devices, iOS and Android.\nWhy is that? because it allows a single source base to run on multiple platforms. For any business int he industry, this is economical. Codename One offers the same leverage using J2ME SDK. So for those with the skills set already, this is a viable option to use when one is consulting or providing a mobile solution to a client.\nHowever, the risk is, how is J2ME being kept up to date. Who is maintaining the SDK to keep up with the moving technology.\nAnonymous — October 9, 2013 at 3:09 pm (permalink) Anonymous says:\nWe don’t use the J2ME SDK.\nWe use Java 5 (J2ME ends with JDK 1.4 subset) and we add a lot of features that don’t exist in J2ME (while still maintaining compatibility). I would not target J2ME alone but Codename One allows some developers to have their cake and eat it.\nAnonymous — May 29, 2014 at 6:41 am (permalink) Anonymous says:\ni want to be a developer and i think j2me sdk is the best app to start with i have on my tecno device(tecno t531) but i need to learn how to use it pls help me i know you are advanced programmers\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/j2me-feature-phones-nokia-devices/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/j2me-feature-phones-nokia-devices/j2me-feature-phones-nokia-devices-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/j2me-feature-phones-nokia-devices-large-3.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/j2me-feature-phones-nokia-devices/j2me-feature-phones-nokia-devices-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eIs J2ME dead or dying?\u003c/p\u003e\n\u003cp\u003eHow many times have we heard this for the past 3 years or so? Sadly the answer is: Yes!\u003c/p\u003e\n\u003cp\u003eUnfortunately there is no active owner for the J2ME standard and thus no new innovation around J2ME for quite some time (MIDP 2.0 came out in 2004, 3.0 never really materialized). Android is/was the biggest innovation since and became the unofficial successor to J2ME.\u003c/p\u003e","title":"J2ME, Feature Phones \u0026 Nokia Devices"},{"content":"\nWe just added a new On/Off switch to Codename One that should allow you to use this component which is very popular on iOS (and gaining some popularity on Android), this is a rather elaborate component because of its very unique design on iOS but we were able to accommodate most of the small behaviors of the component into our version and it seamlessly adapts between the Android style and the iOS style.\nThis component will be a part of the next library update (couple of weeks) and will be available in the GUI builder as well as using code (as usual) it will carry the name OnOffSwitch.\nInitially I wanted the component to be a \u0026ldquo;drop in replacement\u0026rdquo; for checkbox by deriving from that class in order to implement this feature. However, the animation abilities of animated layout (which do lots of the effects you see on the Android version) drew me to using a Container. So you won’t be able to use the exact same code as a CheckBox.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/turn-it-on-or-off/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/turn-it-on-or-off/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eWe just added a new On/Off switch to Codename One that should allow you to use this component which is very popular on iOS (and gaining some popularity on Android), this is a rather elaborate component because of its very unique design on iOS but we were able to accommodate most of the small behaviors of the component into our version and it seamlessly adapts between the Android style and the iOS style.\u003c/p\u003e","title":"Turn It On (Or Off)"},{"content":"\nChen has recently added support for a new OTA (Over The Air) skin download feature which allows us to give you more device skins while maintaining a relatively small distribution size, in fact we might shrink the distribution by removing some of the builtin skins into the new OTA download option. Most of the work on the Skins themselves was contributed by\nEric Coolman\nwho did a lot of work on cutting these up and assembling them properly.\nThe feature is remarkably simple as you can see in the video, just pick the device you are targeting and you should get a pretty good approximation of it on which you can debug your app just like with our existing device options or the device options downloaded from Eric’s site. If you would like to contribute/build skins for the OTA work feel free to open issues in our\nissue tracker\nwith\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — August 10, 2013 at 11:36 am (permalink) Anonymous says:\nCool feature..very usefull\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/ota-device-skin-downloads/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/ota-device-skin-downloads/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eChen has recently added support for a new OTA (Over The Air) skin download feature which allows us to give you more device skins while maintaining a relatively small distribution size, in fact we might shrink the distribution by removing some of the builtin skins into the new OTA download option. Most of the work on the Skins themselves was contributed by\u003cbr\u003e\n\u003ca href=\"http://gadgets.coolman.ca/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nEric Coolman\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nwho did a lot of work on cutting these up and assembling them properly.\u003c/p\u003e","title":"OTA Device Skin Downloads"},{"content":"\nFrom the many emails and discussions we have with developers it seems that there is a great deal of confusion regarding the differences between the 4 levels of subscription that Codename One is offering. I would like to explain the difference more succinctly by covering some of the cases and benefits we reached with various level of subscribers.\nThere are generally 4 levels of subscription: Free, Basic, Pro \u0026amp; Enterprise. (note: there is also a corporate tailored license which is something completely different).\nThe free and the basic subscriptions are basically identical, the only difference is that the basic subscription has the no monthly build quotas. Free and basic subscribers get basic support in our discussion group, which is great for indie developers.\nPro subscribers get a lot more, but find the biggest advantage to be in the support arena. Besides getting priority in response time, pro subscribers often email us their project source code to get help in debugging nasty issues that they run into. The ability to share proprietary sources with us via email is hugely beneficial, for us its really great because we often find issues in the source that weren’t the reason for contacting us. E.g. a pro subscriber had an issue with background images and while dealing with that issue I noticed he set his back button behavior incorrectly. I wouldn’t have seen this without some access to his sources.\nWith Enterprise subscribers we have scheduled \u0026ldquo;office hours\u0026rdquo; this essentially means we spend time with them on Skype (or other VoIP solutions) and go over the issues in person. The great benefit here is that we can actually go over a bug or a feature and give proper hands-on assistance in resolving such issues. E.g. on a recent session with a customer I used a feature within the simulator that allows us to\nedit and continue\ndebugging, the surprised and glee expressed by that customer over that ability prompted me to do the\nedit and continue blog post\n. Some of our enterprise customers only schedule office hours when they have an issue/bug which is a shame, the biggest value of office hours is in the help we can give in design review, tips etc. when going over your code.\nBesides all of the above, having a pro/enterprise account gives you access to a growing list of features (cloud storage, push etc.) and\nto our online course\nwhich is far more detailed than the\nHow Do I?\nvideos.\nNotice that the Codename One 101 course has been deprecated by now. We shifted our online courses to the Codename One Academy.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/which-subscription-level-should-i-choose/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/which-subscription-level-should-i-choose/codename-one-charts-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eFrom the many emails and discussions we have with developers it seems that there is a great deal of confusion regarding the differences between the 4 levels of subscription that Codename One is offering. I would like to explain the difference more succinctly by covering some of the cases and benefits we reached with various level of subscribers.\u003c/p\u003e\n\u003cp\u003eThere are generally 4 levels of subscription: Free, Basic, Pro \u0026amp; Enterprise. (note: there is also a corporate tailored license which is something completely different).\u003c/p\u003e","title":"Which Subscription Level Should I Choose?"},{"content":"\nThis post is inspired by a great post written by\nTope\n, covering the slicing of a PSD image to produce small PNG images which you can later on use as image borders, backgrounds, icons etc. Tope’s technique is pretty simple and works rather well but I’d like to offer another technique as well as a better way to detect the proper layer you with to cut.\nThis post assumes you have a recent version of Photoshop installed and assumes you don’t know anything about Photoshop. So we start by opening the PSD file in Photoshop, this file is composed of layers. A single \u0026ldquo;component\u0026rdquo; is usually composed of multiple layers which you can show/hide by pressing the \u0026ldquo;eye\u0026rdquo; button in the layer view.\nYou can see the layer view by selecting Windows-\u0026gt;Layers from the photoshop menu, on the right you can see the layers of a simple iPhone design that I have here. You will notice that every entry is collapsible.\nA common paradigm designers use is to create multiple screens/forms in a singled PSD\nand thus represent a \u0026ldquo;screen\u0026rdquo; (Form) of its own within the design.\nSo in order to see the other forms for those cases you can just hide/show each layer, in order to show individual components you can\nuse the eye icon to get a specific component.\nNow our goal is to find a specific set of layers relevant to us and \u0026ldquo;hide\u0026rdquo; everything else so we can get the particular component we need in isolation.\nThis is pretty easy when the design is small, but just locating the right layer becomes a HUGE hassle as the design gets complicated and deeply nested.\nTo find the layer matching a specific component we select the \u0026ldquo;Move Tool\u0026rdquo; from the toolbar and check the auto select option in the toolbar above, we then pick the \u0026ldquo;Layer\u0026rdquo; entry instead of group.\nNow when we click an area on the screen the layer corresponding to this specific entry will be selected in the layer view and we could manipulate it. Notice that a component is often composed of multiple layers… We usually would want to hide things such as the text layers etc. for cases such as buttons where we would want to get the button alone so we can cut it into a 9-piece border, but we would want other layers.\nNow say I want to extract an image that is comprised of the following 3 layers, I can select all 3 layers then right click on them (important! Notice that you need to click on the area where the text appears NOT on the icon of the layer, you will get a different context menu otherwise!). You will get an option to convert the layers to a smart object.\nAfter converting to a smart object double click the layer icon (you will get a dialog with a message that is relevant only if you are interested in really changing the file), the standalone image will open in a separate tab and you will be able to use the Save As option and select PNG as the format.\nI hope this tutorial together with the very detailed tutorial from Tope will help you cut images from PSD’s more effectively and help you create better looking apps.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — September 30, 2013 at 3:28 am (permalink) Anonymous says:\nthere is a nice alternative solution to do this process automatically,\nfree little extension called Breeezy it adds to Photoshop the ability to export multiple layers in one click\nyou can take a look\nbreeezyplugin.com\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/cutting-psd-files/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/cutting-psd-files/cutting-psd-files-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThis post is inspired by a great post written by\u003cbr\u003e\n\u003ca href=\"http://www.appdesignvault.com/photoshop-crop\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nTope\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, covering the slicing of a PSD image to produce small PNG images which you can later on use as image borders, backgrounds, icons etc. Tope’s technique is pretty simple and works rather well but I’d like to offer another technique as well as a better way to detect the proper layer you with to cut.\u003c/p\u003e","title":"Cutting PSD Files"},{"content":"\nA preliminary Windows Phone 8 build has been available on our servers for the past couple of days. We differentiate between a Windows Phone 7 and 8 version by a build argument that indicates the version (win.ver=8) this will be exposed by the GUI in the next update of the plugin. But now I would like to discuss the architecture and logic behind this port which will help you understand how to optimize the port and maybe even help us with the actual port.\nThe Windows Phone 7 and 8 ports are both based on the XMLVM translation to C# code, we picked this approach because all other automated approaches proved to be duds. iKVM which seems like the most promising option, isn’t supported on mobile so that only left the XMLVM option.\nThe Windows Phone 7 port was based on XNA (3d C# based API) which has its share of problems but was more appropriate to our needs in Codename One. Unfortunately Microsoft chose to kill off XNA for Windows Phone 8 which put us in a bit of a bind when trying to build the Windows Phone 8 port.\nWhile externally Windows Phone 8\nand 7 look very similar, their underlying architecture is completely different and very incompatible. You cannot compile a universal binary that will work on all of Microsoft’s platforms, so just to make order within this mess:\nWindows Phone 7 – based on the old Windows CE kernel. Allows only managed runtimes (e.g. C# not C++), graphics can be done using XAML or XNA (more on that later.\nWindows Phone 8 – based on an ARM port of Windows 8 kernel. Allows unmanaged apps (C# or C++) graphics can be done in XAML or Direct3D when using C++ (but not silverlight).\nWindows RT/Desktop – the full windows 8 kernel either for ARM or for PC. They are partially compatible to one another so I’m putting them together. This is actually pretty similar to the Windows Phone 8 port, but incompatible so a different build is needed and slightly different API usage. As you understand we can’t use XNA since it isn’t supported by the new platforms, we toyed a bit with the idea of using Direct3D but integrating it with text input, fonts etc. seemed like a nightmare. Furthermore, doing another C++ port would mean a HUGE amount of work!\nSo Codename One is based on the XAML API.\nMost people would think of XAML as an XML based API, but you can use it from C# and just ignore most of the XML aspects of it which is what we need since our UI is constructed dynamically. However, this is more complicated than it seems.\nTo understand the complexity you need to understand the idea of a Scene Graph. If you used Codename One you are using a more immediate mode graphics API, where the paint method is invoked and just paints the component whenever its needed. This is the simplest most portable way of doing graphics and is pretty common, its used natively by Android, OpenGL, Direct3D etc. and is very familiar to developers.\nIn recent years many Scene Graph API’s sprung up, XAML is one of them and so is JavaFX, Flash, SVG and many others. In a Scene Graph world you construct a graphics hierarchy and then let it be rendered, the whole paint() sequence is hidden from the developer. The best way to explain it is that our components in Codename One are really a scene graph, only at a higher abstraction level. Windows/Flash placed the scene graph on the graphics as well, so to draw a rectangle you would just add it to the tree (and remove it when you no longer need it).\nThis is actually pretty powerful, you can do animations just by changing component values in trees and performance can be pretty spectacular since the paint loop can be GPU optimized.\nHowever, the reality of this is that most developers find these API’s harder to work with (since they need to keep track of a rather complex unintuitive tree), the API’s aren’t portable at all since the hierarchies are so different. Performance is also very hard to tune since so much is hidden by the underlying hidden paint logic.\nFor Codename One this is a huge problem, we need our API to act as if its painting in immediate mode while constructing/updating a scene! When we initially built this the performance was indeed as bad as you might imagine. While we are not in the clear yet, the performance is much improved…\nHow did we solve this?\nThere are several different issues involved, the first is the number of elements on the screen. We noticed that if we have more than 200 elements on the screen performance quickly degraded. This was a HUGE problem since we have thousands of paint operations happening just in the process of transitioning into a new form. To solve this we associate every graphics component with a component and when the component is repainted we remove all operations related to it, we also try to reuse graphics resources such as images from the previous paint operation.\nWhen painting a component in Codename One we normally traverse up the component tree and paint the first opaque component forward (known as painters algorithm) however, since the scene already has the parent component painting it again would result in many copies of the image being within the scene graph. E.g. I have a background image on a form, when painting a translucent label I have to paint the background image within a clipping region matching the label…. In the Windows Phone port we have a special hook that just disables this functionality, this hook alone pushed us over the top to reasonable graphics performance!\nWe are working on getting additional performance oriented features into place and fixing some issues related to this approach, its not a simple task since the API wasn’t designed with this in mind but it is doable. We would appreciate you taking the time to review the port\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/windows-phone-8-and-the-state-of-7/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/windows-phone-8-and-the-state-of-7/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eA preliminary Windows Phone 8 build has been available on our servers for the past couple of days. We differentiate between a Windows Phone 7 and 8 version by a build argument that indicates the version (win.ver=8) this will be exposed by the GUI in the next update of the plugin. But now I would like to discuss the architecture and logic behind this port which will help you understand how to optimize the port and maybe even help us with the actual port.\u003c/p\u003e","title":"Windows Phone 8 And The State Of 7"},{"content":"\nThis is a guest post by Bertrand Cirot, based on an original blog post that appeared\nhere\n. Bertrand works as an SFDC, Flex and Java/J2EE developer in Switzerland. Closely interested in mobile device solutions, he writes on\nTuto-CodenameOne.ch\nwhich proposes tutorials for the French-speaking community.\nWhile investigating the possibilities within Codename One, I made a discovery that I would like to share with you via this short article. But first lets discuss SalesForce, it is a CRM platform. Which has an advantage of an open Web Service API enabling it for use with Codename One.\n**\nThis is an ideal combination that provides simple and effective customer management on all mobile devices.\n**\nSalesForce, a complete platform SalesForce is a CRM (Customer Relationship Management) platform that is fully hosted in the cloud, as indicated by it’s logo. SalesForce (SFDC) is a leader in sales management tools, it provides a complete and evolutionary system. Many tools are available and configurable in a simple and efficient way to manage all the essential information about the sales activity. In addition, the platform is fully integrated with communication tools, social networking and instant messaging.\nOnce You connect the SalesForce interface, you can easily add standard data: Users, Accounts, Products, Contacts, etc. Everything is added via forms based interface, If you wish, you can also add new fields to the Available Objects or create new ones from scratch.\nSalesForce can therefore easily form a set of custom data hosted in the Cloud. More importantly for mobile development, the SFDC platform offers several communication API’s allowing third party applications access to its data (SOAP, Bulk or REST).\nPersonally recommend the REST architecture mainly for bandwidth reasons, even though it is more restrictive in terms of implementation and use.\nSalesForce One and Codename: a winning combination In order to make ​​a Codename One application communicate with SalesForce, I performed some tests.\nMy starting point was the official documentation of the REST API: I soon managed to authenticate and execute a query to retrieve a list of distant objects.\nWhat’s next? Still, I could not stop there so I decided to use the opportunity to try the new library support that was recently introduced to Codename One and create a SalesForce library. There is still a lot of work to be done, there are bugs and only a small part of the API is exposed in the library. I will try to tackle these issues one at a time and I will keep you informed of my progress. If you are interested, the code is available on Google Code under the name:\nCodenameOne-SFDC-Lib\n.\n**\nIf you want to help me in pushing forward the development of the library faster, do not hesitate to contact me, I’d love to have some help\n**\n.\nBertrand CIROT\nwriter on\nTuto-CodenameOne\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/combining-salesforce-and-codename-one/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/combining-salesforce-and-codename-one/combining-salesforce-and-codename-one-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is a guest post by Bertrand Cirot, based on an original blog post that appeared\u003cbr\u003e\n\u003ca href=\"http://www.tuto-codenameone.ch/salesforce-et-codename-one/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nhere\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n. Bertrand works as an SFDC, Flex and Java/J2EE developer in Switzerland. Closely interested in mobile device solutions, he writes on\u003cbr\u003e\n\u003ca href=\"http://www.tuto-codenameone.ch/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nTuto-CodenameOne.ch\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nwhich proposes tutorials for the French-speaking community.\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eWhile investigating the possibilities within Codename One, I made a discovery that I would like to share with you via this short article. But first lets discuss SalesForce, it is a CRM platform. Which has an advantage of an open Web Service API enabling it for use with Codename One.\u003c/p\u003e","title":"Combining SalesForce and Codename One"},{"content":"\nThis is a guest post by Yaniv Nizan who is the CEO and Co-Founder of\nThe SOOMLA Project\n, the platform for Creating In-App Purchase Stores for Mobile Games. Yaniv also writes in 4 different blogs including\nblog.soom.la\n, speaks in different industry events about gamification and game design and tweets\n@y_nizan\n.\nGamification is the practice of using game mechanics in a different context with a goal to engage users\nMobile apps are in fierce competition these days. There are over one million apps available in the different marketplaces and while a user may install a large number of apps on his device. Recent research by Flurry shows that users don’t use many apps for very long and in fact only 25% of the apps survive after 3 months.\nThis is one of the main reasons why app developers need to invest a lot of resources in engaging the users and increasing the average length of activity for the users. One interesting way of doing that is through the user of gamification. Games are very popular in smartphones and most users are already accustomed to playing games on their mobile devices so the fit seems very natural here.\nDigging a bit deeper into gamification, there are a few basic game mechanics that are suited for gamifying most mobile apps: Goals or Achievements, Problem Solving and Awards. I’m deliberately leaving social out since it is not a purely game related. It is present in some games and in some apps. On top of the game mechanics gamification is also about making elements more responsive and providing instant gratification. These are easier to do on touch devices but not all apps are utilizing the power of this approach.\nSo now that we know what Gamification is, let’s define the goal in the context of a mobile app. The idea here is to get the user in the engagement loop. The engagement loop is achieved when the user invests time in order to improve his value from the application and then he is willing to invest more time which will increase the value and so forth. The more iterations of this loop, the better the\napp engagement\nwill be.\nHere is how we can combine all of these together:\nTip 1 – Creating Engagement Opportunities for the User This is a key component in creating the engagement loop. You app needs to have elements that allow users to invest time and get more out of the app. One easy example for this is profile building. In apps that provide social interaction, investing time in your profile is not a required step but the more a user invests time in it, the better his experience will be. Same goes for apps that allow you to import your friends from other social networks. The more time you invest, the more engaging the app is likely to be for you.\nTip 2 – Encouraging Your Users to Invest the Time through Achievements While the user does get value from investing his time, he doesn’t get it right away. This is part of the reason why it’s important to provide a more instant gratification even for an action that is good for the user. NOTE – it’s important not to provide short term rewards for actions that will end up hurting the user – this can backfire and produce a negative result. Easy elements that can be added to encourage users are progress bar for completing his user profile or awards for connecting and inviting friends.\nTip 3 – Guide Users about the Value They Can Receive Once your app users invested time and unlocked more value. You can add responsive UX that guides them about opportunities to get more value as they appear. This could be anything from friend recommendations to relaying on the app for day to day tasks. If we take one example, a task management app can encourage users to connect the app with the calendar app through achievements and awards. Once the calendar app is connected, the task management app can recommend the user to add tasks after a meeting.\nTip 4 – Getting Rid of Clutter via Smart Unlocking While great apps allow users to get tremendous value, they also need to be very simple. The conflict here is that the more functionality you add to the app the more it is becoming more complicated. Luckily, gamification does provide a solution. Provided that you are already maintaining some score about the user, you can gradually unlock features based on his score or level. This approach allows you to keep the first experience simple and gradually add more value later on.\nTip 5 – Reward your Key Users Every successful app has users that evangelize the app and explain others how to get value from it. While you can design a great UX with guidance and tutorials, nothing beats a friend explaining the user how to use the app and showing him the end result. This is not about getting buzz by soliciting likes on Facebook. This is about finding the few that are really excited about the app and gamifying their evangelism activity. You could have awards such as the Educator, the Trainer and you could reward users for repeatedly mentioning your app.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — March 24, 2013 at 2:56 pm (permalink) Anonymous says:\nGreat post guys!\nKeep up the good work!\nAnonymous — March 24, 2013 at 4:20 pm (permalink) Anonymous says:\nVery cool. Thanks for the post!\nAnonymous — November 13, 2013 at 10:25 am (permalink) Anonymous says:\nThanks for this post. Do you have any examples of utility apps that do this well? Eg, Telecoms, banking, power etc\nBalbir singh — February 7, 2018 at 10:16 am (permalink) Balbir singh says:\nthanks for sharing this informative post about mobile app.\nhttp://www.nanoarchsoftware…\n.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/5-tips-for-gamifying-your-mobile-app/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/5-tips-for-gamifying-your-mobile-app/5-tips-for-gamifying-your-mobile-app-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is a guest post by Yaniv Nizan who is the CEO and Co-Founder of\u003cbr\u003e\n\u003ca href=\"http://soom.la/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nThe SOOMLA Project\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, the platform for Creating In-App Purchase Stores for Mobile Games. Yaniv also writes in 4 different blogs including\u003cbr\u003e\n\u003ca href=\"http://blog.soom.la/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nblog.soom.la\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n, speaks in different industry events about gamification and game design and tweets\u003cbr\u003e\n\u003ca href=\"http://twitter.com/y_nizan\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\n@y_nizan\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n.\u003c/p\u003e\n\u003chr\u003e\n\u003cblockquote\u003e\n\u003cp\u003eGamification is the practice of using game mechanics in a different context with a goal to engage users\u003c/p\u003e","title":"5 Tips for Gamifying Your Mobile App"},{"content":"\nThe other day one of our pro users sent us an app he is working on (which looks great and will hopefully be submitted to the gallery), he was experiencing major performance degradation on iOS compared to Android. Initially I couldn’t find anything wrong with the app so I started debugging and benchmarking the hell out of it.\nTurns out that we had a bug with table cells in which we made the cell transparent regardless of theme settings, this had to do with the old way in which we drew the table cell border which is no longer relevant. Anyway, this triggered a problem when he tried to set the cell background. His solution was to use a gradient and set the source/destination color to the same value!\nNaturally this slowed down performance considerably… However, even when that was fixed there was still some sluggishness that was obvious and specific to iOS.\nI spent some time with the device native profiler and found a major performance bug in scaled image drawing that occurred when\ndrawing the same image in more than one resolution on the same page. Fixing that improved the performance noticeably. I then profiled again and found an issue with the speed of draw string, we cache textures of Strings in the native code and it seems that this cache was filling up too fast on my ipad. I increased the cache size and tripled it for the iPad which has a large size and can fit more strings on the screen.\nDoing all of the above has made the applications noticeably faster in every way and might improve the performance of your apps just by sending a new build.\nOther than that we are now starting to deploy SSD based Mac build servers. This roughly halves the time it takes to build a native iPhone app in CN1! I hope to convert all our servers to these beasts, I was able to build the Facebook demo in under 3 minutes!\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — March 19, 2013 at 8:08 pm (permalink) Anonymous says:\nGreat work! Things just keep getting better and better. You guys are so amazing.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/performance-improvements-on-ios-some-other-news/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/performance-improvements-on-ios-some-other-news/codename-one-charts-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe other day one of our pro users sent us an app he is working on (which looks great and will hopefully be submitted to the gallery), he was experiencing major performance degradation on iOS compared to Android. Initially I couldn’t find anything wrong with the app so I started debugging and benchmarking the hell out of it.\u003c/p\u003e\n\u003cp\u003eTurns out that we had a bug with table cells in which we made the cell transparent regardless of theme settings, this had to do with the old way in which we drew the table cell border which is no longer relevant. Anyway, this triggered a problem when he tried to set the cell background. His solution was to use a gradient and set the source/destination color to the same value!\u003c/p\u003e","title":"Performance Improvements On iOS \u0026 Some Other News"},{"content":"\nChen has been busy adding one of the more addictive features yet to Codename One: pull to refresh. If you are unfamiliar with the Twitter app, this feature essentially means that you pull the UI downwards from the top and an arrow appears indicating that the UI will refresh once you lift your finger. This is now baked into Codename One allowing you instantly add this sort of UI pattern!\nCool and painfully addictive.\nI also added quite a few How Do I? tutorials over the past couple of months and 3 new ones today covering this, the hamburger sidemenu and override in platform. Check this out in the\nHow Do I?\nsection.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/pull-to-refresh-several-new-how-do-i-videos/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/pull-to-refresh-several-new-how-do-i-videos/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eChen has been busy adding one of the more addictive features yet to Codename One: pull to refresh. If you are unfamiliar with the Twitter app, this feature essentially means that you pull the UI downwards from the top and an arrow appears indicating that the UI will refresh once you lift your finger. This is now baked into Codename One allowing you instantly add this sort of UI pattern!\u003c/p\u003e","title":"Pull To Refresh \u0026 Several New How Do I videos"},{"content":"\nThe title of this post might be a bit misleading… Hamburger?\nThe Hambuger sidemenu is the menu style popularized by the Facebook app, its called a Hamburger because of the 3 line icon on the top left resembling a hamburger patty between two buns (get it: its a side menu…)!\nUp until now these things were a pain to implement smoothly in Codename One, but Chen wouldn’t let this rest and just committed support for this feature. Working with a Hamburger menu couldn’t be simpler! Just set the command behavior to side menu (in the Display class) and it just works. You can also set it by setting the commandBehavior theme constant in the\nCodename One designer to \u0026ldquo;Side\u0026rdquo;.\nThen just add commands and watch them make their way into the side menu allowing you to build any sort of navigation you desire.\nChen updated the Facebook demo to show this off, its still only available via SVN and requires the latest SVN version of Codename One for all the bells and whistles to function properly but it already looks pretty sweet!\nNow all we need is a cheeseburger sidemenu with fries.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — February 28, 2013 at 7:21 pm (permalink) Anonymous says:\nThanks Chen, was hoping that would land for 1.1 – looks great!\nAnonymous — March 1, 2013 at 6:37 am (permalink) Anonymous says:\nGreat job Chen!!\nAnonymous — August 17, 2013 at 4:36 pm (permalink) Anonymous says:\nThis looks great, but I have no idea how to use it. Unfortunately, as a total beginner, \u0026quot; Just set the command behavior to side menu (in the Display class)\u0026quot; does not mean anything to me yet, and i dont know how to setup the menus on the left to start with. There is a \u0026ldquo;Commands\u0026rdquo; Properties in the editor, but when you hit Add, and enter \u0026ldquo;side menu\u0026rdquo; as the \u0026ldquo;name\u0026rdquo; attribute, it doesnt seen to do anything.\nHas anyone got a link to a demo handy?\nAnonymous — August 18, 2013 at 1:34 am (permalink) Anonymous says:\nThanks, its sometimes hard to see where we are being obtuse. The facebook demo shows the side menu.\nTo activate command behavior either:\nOpen the designer, select the theme. Go to the constants tab, click \u0026ldquo;Add\u0026rdquo; and select commandBehavior from the combo box, type in Side for the value.\nOr use:\nDisplay.getInstance().setCommandBehavior(Display.COMMAND_BEHAVIOR_SIDE_NAVIGATION);\nCommands are either added by clicking the Command section in the form in the GUI designer and adding commands or by invoking the method on form called addCommand.\nAnonymous — August 18, 2013 at 7:20 am (permalink) Anonymous says:\nMagic – works! Added in the designer. Worked with latest eclipse plugin, no SVN pull required. CN1 is amazing.\nGeorge Njoroge — September 4, 2015 at 9:29 am (permalink) George Njoroge says:\nCan I get a link project source code\nShai Almog — September 5, 2015 at 3:58 am (permalink) Shai Almog says:\nIts in our demos repository http://github.com/codenameo…\nBertrand Gauvreau — October 16, 2015 at 3:52 pm (permalink) Bertrand Gauvreau says:\nI Shai ! First, Thank you for offering us CodenameOne ! It’s a fantastic tool !\nI have an issue with the hamburger menu. When I run my app on my Android device and click on the hamburger menu icon, the menu opens but it slides up with the whole window and makes the Action Bar disappear. The action bar reappears only when I restart the app.\nDo you have any idea ?\nThank You\nShai Almog — October 17, 2015 at 4:33 am (permalink) Shai Almog says:\nGreat to hear!\nDid you update the theme constant to side?\nI would suggest you migrate to the new Toolbar API which is more powerful than the side menu on its own and encapsulates all its functionality.\nBertrand Gauvreau — October 17, 2015 at 12:46 pm (permalink) Bertrand Gauvreau says:\nThank you Shai\nMahmoud — March 26, 2016 at 8:43 pm (permalink) Mahmoud says:\nDear Shai,\ni have menu and my background is white but i have gradient line at the first of menu\nhow i can remove it\nShai Almog — March 27, 2016 at 4:26 am (permalink) Shai Almog says:\nThat’s the shadow for the sidemenu set the theme constant sideMenuShadowBool=false\nMahmoud — March 27, 2016 at 5:43 am (permalink) Mahmoud says:\nThanks Shai 🙂\nAkinniranye James — September 14, 2016 at 1:39 pm (permalink) Akinniranye James says:\nIs it possible to achieve a side menu as rich as this? Since we cant even set different uiids for commands. Am considering using layered pane layout\nShai Almog — September 15, 2016 at 3:47 am (permalink) Shai Almog says:\nThis is the side menu in the up to date kitchen sink. You can customize the Commands heavily but it’s far more intuitive to use the Toolbar API…\nhttps://uploads.disquscdn.c…\nAkinniranye James — September 15, 2016 at 8:01 pm (permalink) Akinniranye James says:\nWow, I barely recognize this Kitchen Sink, wow. Good job.\nAkinniranye James — September 15, 2016 at 8:26 pm (permalink) Akinniranye James says:\nMy bad. I never knew there is toolbar..addComponentToSideMenu, I have only been using toolbar.addCommandToSideMenu\ntracey-de santa — July 26, 2017 at 6:21 am (permalink) tracey-de santa says:\ncool,\nAkinniranye James — July 26, 2017 at 3:59 pm (permalink) Akinniranye James says:\ncheck out our app https://play.google.com/sto….\nusing codenameone\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/hamburger-sidemenu/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/hamburger-sidemenu/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eThe title of this post might be a bit misleading… Hamburger?\u003c/p\u003e\n\u003cp\u003eThe Hambuger sidemenu is the menu style popularized by the Facebook app, its called a Hamburger because of the 3 line icon on the top left resembling a hamburger patty between two buns (get it: its a side menu…)!\u003c/p\u003e\n\u003cp\u003eUp until now these things were a pain to implement smoothly in Codename One, but Chen wouldn’t let this rest and just committed support for this feature. Working with a Hamburger menu couldn’t be simpler! Just set the command behavior to side menu (in the Display class) and it just works. You can also set it by setting the commandBehavior theme constant in the\u003c/p\u003e","title":"Hamburger Sidemenu"},{"content":"\nFirst, let me start with an apology for not blogging as frequently. Its been hectic these past few weeks and I could barely find the time to write this! That’s generally a \u0026ldquo;good thing(tm)\u0026rdquo;.\nOne of my favorite things about working with Codename One is the GUI builder, it solves a lot of the headaches of handcoding/positioning elements into place especially when coupled with the Codename One LIVE! application. However, not all of us use the GUI builder and even when we do we sometimes end up writing code manually.\nIn those cases it is sometimes pretty difficult to visualize the UI and how to properly style it in the designer tool e.g. when you run into\ninexplicable spacing that is clearly not your intention.\nFor this purpose we now have the component inspector in the simulator tool. It allows us to inspect the component hierarchy in a running simulator, see the classes and UIID’s involved etc.\nYou can reach the component inspector via the simulator menu after which you can just expand the UI to see the elements within and understand more about the way Codename\nOne lays out everything.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — February 24, 2013 at 6:51 pm (permalink) Anonymous says:\nThis feature sounds like exactly what I need. Where do I find it? I have the plugin version 1.0.33 and no updates available but I can’t find this tool\nAnonymous — February 25, 2013 at 4:53 am (permalink) Anonymous says:\nI was sure it was there already… Updated the version to 34 right now so it has to be there now.\nAnonymous — February 27, 2013 at 8:35 am (permalink) Anonymous says:\nVery neat. Refresh doesn’t seem to work. I need to close the inspector dialog and re-open when I change forms to get an updated component tree.\nAnonymous — February 27, 2013 at 9:12 am (permalink) Anonymous says:\nOops. Wrote the code but forgot to wire it. Will be fixed for the next update.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/inspecting-components/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/inspecting-components/inspecting-components-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/inspecting-components-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/inspecting-components/inspecting-components-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eFirst, let me start with an apology for not blogging as frequently. Its been hectic these past few weeks and I could barely find the time to write this! That’s generally a \u0026ldquo;good thing(tm)\u0026rdquo;.\u003c/p\u003e\n\u003cp\u003eOne of my favorite things about working with Codename One is the GUI builder, it solves a lot of the headaches of handcoding/positioning elements into place especially when coupled with the Codename One LIVE! application. However, not all of us use the GUI builder and even when we do we sometimes end up writing code manually.\u003c/p\u003e","title":"Inspecting Components"},{"content":"\nWe’ve just launched a new library project type for Codename One, this is very preliminary but we think this is pretty much the final direction we will take with the Codename One library support.\nTo get started just create a new project and select the Codename One library project as your option.\nThis will generate a cn1lib file when you build the project which you can just place in a lib dir of any new Codename One project in order to distribute binary libraries. You will need to use the Refresh\nLibs right click option when adding a new library to a project.\nThe obvious question we get quite frequently is: Why not just use\nJars?\nThere are several different answers here:\nWe only support a subset of Java 5 hence something might not be supported and we will fail.\nWe expect code to be compiled in a specific way (target 1.5 etc.) we just don’t test other configurations and they are likely to fail.\nWe would like to enable native device code, e.g. including an Android specific JAR or iOS specific .a library, this is possible with our file format but impossible with JAR’s.\nWe want\nintellisense\ncode completion to work properly (include the javadoc when you use the library) while this is possible with jar’s its not automatic.\nWe want everything to integrate with the Codename One designer tool (this is work in progress, more on that later).\nSo now that we have the basic requirements in place what is actually happening and what’s a cn1lib file?\nThe cn1lib file is a zip containing between 2 – 7 zips within it.\nThe two required zips are one containing the compiled classes of the library and the\nother one contains stub sources for the library. We run a doclet on your sources and generate sources that only contain the signatures and javadocs, this allows code completion to work correctly in the various IDE’s without you having to do anything about it and still allows for proprietary libs.\nOther than that we package into zips all the content of the native directories for every one of the platforms, so if you used Codename One’s ability to generate native interfaces then this will all be packaged in source form into the library. To keep proprietary data there you would need to use a library such as a jar (for Android, Blackberry \u0026amp; J2ME) or an ‘a’ file for iOS. That gets into the territory of native OS programming which is a bit out of the scope of this mini introduction so I won’t get into that.\nI hope you guys start banging on the tires of this tool and let us know how it works out for you.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — February 12, 2013 at 6:41 am (permalink) Anonymous says:\nGreat news ! The ability to embed native code reminds me of the Native Extensions for Adobe AIR, it offers many opportunities for developers.\nCan’t wait to do some testing.\nAnonymous — February 15, 2013 at 2:10 pm (permalink) Anonymous says:\nIt cannot be overstated how important a step this is for CN1. Just as vibrant App market is critical to the success of a device, a flourishing ecosystem of 3rd party libraries is a compelling reason to choose one platform over another.\nLooking forward to digging in and creating some libraries.\nAnonymous — June 18, 2013 at 10:07 pm (permalink) Anonymous says:\nMay I make a suggestion. Modify SWIG to generate wrappers to common C libs for codename one and your on a winner. The approach will need to be different between the platforms , BUT, a lot of C libs have IOS and android ports (ultimately the only platforms that really matter imho) but expose common APIs. Doing this gives you a huge range of potential libraries whilst preserving at least some degree of cross platform support.\nAnonymous — June 19, 2013 at 4:26 am (permalink) Anonymous says:\nThanks. I think the SWIG interface requirement might be problematic. There are several tools out there that map Objective-C code to Java and since Android is Java this should theoretically work.\nThe problem with these sort of approaches (e.g. taken on C# with Mono) is that when you have a failure you will only find help for Objective-C code and you would only be able to properly debug on xcode so you end up back in square one.\nNative wrappers essentially mean we expect people to go into native code and we feel the opposite. If you need to write native code that means our platform is missing something.\nAnonymous — October 23, 2014 at 11:25 pm (permalink) Anonymous says:\nIt seems we can not import to Cn1 library project another Cn1 lib.( got compile error)\nExample: We make a chart Cn1 lib project but can not import font or graphic Cn1 lib( can’t see refresh libs option)\nAnonymous — October 24, 2014 at 9:59 am (permalink) Anonymous says:\nWe currently don’t support nesting libraries into one another. Most developers who needed that ended up just adding the other library to the classpath in compilation then requiring that both cn1libs be in the lib directory. This isn’t ideal but can be worked with for most cases. You can also just hack the ant scripts to achieve more elaborate build options.\nDavid Hinckley — December 25, 2015 at 10:23 am (permalink) David Hinckley says:\nI do not see the CodenameOne Library project option. I have CodenameOneFeature1.0.0.201511241324 on Eclipse 4.4.2. What am I missing?\nShai Almog — December 26, 2015 at 5:00 am (permalink) Shai Almog says:\nWe just didn’t implement this on Eclipse. Back when we did this there wasn’t much demand and most of the hardcore hackers used NetBeans since it made it easier to work with our sources: https://www.codenameone.com…\nWe’ll add this in a future update, however you can just open any existing library project and just change it to suite your needs since they are just ant projects that don’t need much IDE integration.\nOrlando D\u0026rsquo;Free — March 31, 2016 at 8:36 am (permalink) Orlando D\u0026rsquo;Free says:\nWhen I create a Codename One Library project, I find a file called private.properties that has this line in it:\napplication.args=com.codename1.hello.FirstCodenameOneLibrary\nThis is referring to the one class that was placed in my library code. But I’m not using it, so my first instinct is to delete it. Does this property need to point to an existing class? Is there anything about that class that I need to know?\nShai Almog — April 1, 2016 at 3:20 am (permalink) Shai Almog says:\nThis is part of the NetBeans project structure. You don’t need it and it won’t have any affect to remove it or leave it there.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-preliminary-library-support/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-preliminary-library-support/new-preliminary-library-support-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/new-preliminary-library-support-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/new-preliminary-library-support/new-preliminary-library-support-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eWe’ve just launched a new library project type for Codename One, this is very preliminary but we think this is pretty much the final direction we will take with the Codename One library support.\u003c/p\u003e\n\u003cp\u003eTo get started just create a new project and select the Codename One library project as your option.\u003c/p\u003e\n\u003cp\u003eThis will generate a cn1lib file when you build the project which you can just place in a lib dir of any new Codename One project in order to distribute binary libraries. You will need to use the Refresh\u003c/p\u003e","title":"New Preliminary Library Support"},{"content":"\n_\nTel Aviv, Israel\n_\n– Mobile development platform Codename One is announcing the launch of its 1.0 version on Tuesday, January 29. After releasing in beta last June, Codename One – the first software development kit that allows Java developers to create true high performance native mobile applications across multiple mobile operating systems using a single code base – has garnered over 100,000 downloads and emerged as one of the fastest toolkits of its kind, on par with native OS toolkits.\nThe platform to date has been used to build over 1,000 native mobile applications and has been touted by mobile developers and enthusiasts as the best write-once-run-everywhere solution for building native mobile apps.\n\u0026ldquo;I have been developing with Codename One for a couple of months now. When you line up all of the other options for development, whether native SDKs, Appcelerator, ADF or others, Codename One wins on almost every front,\u0026rdquo; said software developer Steve Hannah.\nCodename One has received widespread, viral acclaim in technology and business media including InfoWorld, Slashdot, Hacker News, VentureBeat, Business Insider, The Next Web, Dr. Dobbs and Forbes, which named the company one of the 10 greatest industry disrupting startups of 2012.\n\u0026ldquo;We have been thrilled with the success of our beta launch and are very excited to release the much-awaited 1.0 version,\u0026rdquo; said co-founder and CEO Shai Almog.\nAlmog, along with co-founder Chen Fishbein, decided to launch the venture after noticing a growing inefficiency within mobile application development. By enabling developers to significantly cut time and costs in developing native applications for iOS, Android, Blackberry, Windows 7 Phone and other devices, Almog and Fishbein hope to make mobile application development increasingly feasible.\nThe Java-based platform is open-source and utilizes lightweight technology, allowing it to produce unique native interfaces highly differentiated from competitive cross-platform mobile development toolkits, which typically use HTML5 or heavyweight technology.\nBy drawing all components from scratch rather than utilizing native widgets, Codename One enables developers to avoid fragmentation – a major hindrance found in the majority of competitors – and additionally allows accurate desktop simulation of mobile apps.\nThe startup’s founders are recognized for engineering Sun Microsystems’s famous Lightweight User Interface Toolkit, a mobile platform used by leading mobile carriers and industry leaders to this date.\nCodename One is available for download free of charge.\nAbout Codename One Codename One, named by Forbes as \u0026ldquo;one of the 10 greatest industry disrupting startups of 2012,\u0026rdquo; is an Israel-based technology company that has created a powerful cross-platform software development kit for mobile applications. The technology enables developers to create native applications across multiple operating systems using a single code base. Codename One was founded by renowned software engineers Shai Almog and Chen Fishbein in 2012.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — March 13, 2015 at 7:12 am (permalink) Anonymous says:\nIn the menu above just click the download link.\nAnonymous — March 13, 2015 at 7:12 am (permalink) Anonymous says:\nIts a good news for us! and i wanna download it.\nIt would be appreciable if you provide an official link to download it.\nAnonymous — March 13, 2015 at 7:12 am (permalink) Anonymous says:\nthumps up for the great ideas.\nAnonymous — March 13, 2015 at 7:12 am (permalink) Anonymous says:\ngood night\nHow will simulate Windows phone emulator in Netbeans Codename One?\nAnonymous — March 13, 2015 at 7:12 am (permalink) Anonymous says:\nThere is a lumia skin with the Codename One distribution.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/with-100000-sdk-downloads-mobile-development-platform-codename-one-comes-out-of-beta-with-10-launch/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/with-100000-sdk-downloads-mobile-development-platform-codename-one-comes-out-of-beta-with-10-launch/codename-one-charts-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e_\u003cbr\u003e\nTel Aviv, Israel\u003cbr\u003e\n_\u003cbr\u003e\n– Mobile development platform Codename One is announcing the launch of its 1.0 version on Tuesday, January 29. After releasing in beta last June, Codename One – the first software development kit that allows Java developers to create true high performance native mobile applications across multiple mobile operating systems using a single code base – has garnered over 100,000 downloads and emerged as one of the fastest toolkits of its kind, on par with native OS toolkits.\u003c/p\u003e","title":"With 100,000 SDK Downloads, Mobile Development Platform Codename One Comes Out of Beta With 1.0 Launch"},{"content":"\nDue to technical reasons in our website we had to dump blogger which served us well until now. We aren’t deleting the blog but we will try to move it to this domain.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/new-blog-infrastructure/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/new-blog-infrastructure/codename-one-charts-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eDue to technical reasons in our website we had to dump blogger which served us well until now. We aren’t deleting the blog but we will try to move it to this domain.\u003c/p\u003e\n\u003cp\u003eNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\u003c/p\u003e","title":"New Blog Infrastructure"},{"content":"\nThey say that today all companies are software companies. In less than 5 years all companies will be mobile companies. So why isn’t Oracle \u0026ldquo;getting it\u0026rdquo;, why aren’t they on the iPhone, on Android and even Windows Phone?\nThis\nOTN thread\nhas been going on for some time now with people constantly chiming in with various uninformed opinions regarding their desire for an official Java for all platforms from Oracle.\nThis won’t happen in the next two years or so, don’t delude yourselves.\nNo we don’t have a vested interest here, if Oracle issues Java FX for iOS it will be great for us. We will be able to use their implementation (if it were any good, more on that below) and still provide value.\nRead below for more detailed explanation from a former insider as to why this just won’t happen.\nChen used to be a Sun employee and I was a Sun contractor for quite a few years, we were there for the Oracle takeover as well. I can’t talk too much about what I know from within, its not so much a contractual issue as a personal moral issue (respect the privacy of the guys paying your bills). However, there is one thing that I think no one will mind me disclosing that explains perfectly well why Oracle removed all sessions about the iPhone from Java One (except for our session which wasn’t an Oracle sponsored section).\nOne of the early feelings we got before the merger completed was the basic difference between Sun and Oracle and it boiled down to this:\nWith Sun we used to go to customers/trade shows and show the cool stuff we had that wasn’t yet a product. E.g. showing off cool new JavaFX tools that didn’t have an ETA yet. This was ingrained in the hacker mentality and core to Sun, why show people the stuff that’s available to download?\nDon’t they know already?\nOracle is the exact opposite, they NEVER show something that isn’t a product or won’t be a product very soon. This is actually quite clever, people aren’t aware of lots of the stuff that’s available and if you talk about your pipe dream (which is cool) there is no \u0026ldquo;action item\u0026rdquo; to download a try it. You need people’s attention focused on what they can buy (obvious why Oracle was profiting while Sun was losing).\nSo Oracle’s removing of the JavaFX on iOS talks from Java One is simply a matter of them not having a concrete product in the pipeline (update: just to clarify, this is an educated guess not a statement of fact).\nNow you may ask: Why not?\nThat’s actually a much easier answer and as usual it divides into several different answers:\nThere is no business there – Oracle released a Java based solution for iOS backend for the ADF team. This is a tool that’s only useful if you buy a server license (minimum 20k USD), so there is a clear business here. Java is generally an odd duck in Oracle’s tools, they just don’t build stuff that doesn’t make business sense (like Java itself). 2. This is a consumer product – Oracle is an enterprise company. Yes they are trying to break some of that mold but old habits die hard, they don’t really understand the business and they don’t really know how to build consumer products.\nSun also sucked with user facing projects so really this isn’t very different (and keep in mind, that Sun never made a Java for iPhone release either despite Apple removing the restrictions WELL before the acquisition). 3. It will suck – the problem here is Apple. Apple disallows JIT’s in its license (self modifying code), mostly for security reasons but probably also to block things like this. That is why you can’t ship a custom built webkit with your application (no V8 JavaScript engine for Chrome on iOS which is why it sucks on iOS).\nWe get around it by translating the Java bytecode to C and compiling it, this gives us native (or better) performance.\nI don’t know about Oracle here, but this sort of architecture would never fly at Sun. Java is a virtual machine with a JIT, that is a religion within Sun and I assume the same is true for the Sun engineers who stayed at Oracle. 4. It will suck worse – not only will it be slow because of the VM, it will be slow because of JavaFX (here we can actually help if Oracle chooses to do option 3 well).\nAdobe with its amazing skills in vector graphics programming is finding it remarkably hard to build a high performance vector graphics rendering engine in iOS. They complain that Apple doesn’t expose the internal GPU behavior.\nFrankly, I understand Apple here. Documenting the GPU on the level Adobe needs is REALLY hard. Supporting this against potential driver issues and attacks isn’t simple, that’s why they have Core Animation.\nJava FX can’t use Core Animation (just like Adobe can’t) and will run into the exact same problems Adobe hit. I have a great deal of respect for the engineers on the Java FX team, they are pretty clever. But that’s not good enough.\nWe don’t run into those pitfalls since we are pretty used to device limitations, we pre-render everything important as raster images (which is what most mobile developers do anyway). This might not have the same \u0026ldquo;cool\u0026rdquo; graphics geek sheik, but it actually provides amazing looks because prerendering often looks better. Sure there are compromises about what you can do, but you will find pre-rendered graphics in most of the leading iOS apps despite the availability of vector graphics. Its easier, faster and flexible enough.\nSo if you are looking for JavaFX on iOS, Android or Windows Phone then sorry. Just won’t happen.\nWe are trying to help, but Java FX is a dead end technology as illustrated by the famous graph at the top of this article. Everyone will be on mobile which will exceed everything WinTel ever was and FX isn’t well suited for today’s mobile devices. It probably can’t be fixed either since it relies on a Scene-Graph approach which just isn’t very portable to device specific Scene-Graphs. It would be possible to implement it over OpenGL ES but that has many issues.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — January 27, 2013 at 7:36 am (permalink) Anonymous says:\nI’ve always liked Swing, but JavaFX seemed to me an answer to a question nobody asked – I don’t think the world really needed another graphics scripting language. Sun didn’t do themselves any favours either by appearing to favour JavaFX over Swing for a while.\nAs you say, now it’s pretty much moot.\nAnonymous — February 11, 2013 at 8:17 pm (permalink) Anonymous says:\nI guess you were proven wrong in less that one month: http://fxexperience.com/201…\nAnonymous — February 12, 2013 at 2:04 am (permalink) Anonymous says:\nCool. I don’t mind being wrong.\nThis isn’t a binary solution/product which is the main thing covered by this article. To be frank I didn’t think Oracle would ever do even something such as an Open Source code dump so that is surprising.\nAnonymous — May 14, 2014 at 3:50 am (permalink) Anonymous says:\nNow every one knows why. They were waiting to sue Android. Either they will get a continuous revenue or a one time big fine.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/why-oracle-wont-issue-java-for-ios-anytime-soon/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/why-oracle-wont-issue-java-for-ios-anytime-soon/why-oracle-wont-issue-java-for-ios-anytime-soon-1.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/why-oracle-wont-issue-java-for-ios-anytime-soon-large-2.jpg\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/why-oracle-wont-issue-java-for-ios-anytime-soon/why-oracle-wont-issue-java-for-ios-anytime-soon-1.jpg\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eThey say that today all companies are software companies. In less than 5 years all companies will be mobile companies. So why isn’t Oracle \u0026ldquo;getting it\u0026rdquo;, why aren’t they on the iPhone, on Android and even Windows Phone?\u003c/p\u003e\n\u003cp\u003eThis\u003cbr\u003e\n\u003ca href=\"https://forums.oracle.com/forums/thread.jspa?threadID=2448461\u0026amp;\u0026amp;t\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nOTN thread\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nhas been going on for some time now with people constantly chiming in with various uninformed opinions regarding their desire for an official Java for all platforms from Oracle.\u003c/p\u003e","title":"Why Oracle won't issue Java for iOS anytime soon"},{"content":"\nAnswering common question is what a FAQ is usually for, but usually that’s just not enough. A common presentation tip is: \u0026ldquo;Show, don’t tell\u0026rdquo;.\nWhich is why we launched the\n\u0026ldquo;How Do I?\u0026rdquo;\nsection in the Codename One website, this section contains short video tutorials demonstrating how to do small things in Codename One from creating your first Codename One application to monetizing and debugging it (upcoming).\nWe hope to flesh out this section with more videos as time goes on, feel free to ask for future videos right here.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/how-do-i/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/how-do-i/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eAnswering common question is what a FAQ is usually for, but usually that’s just not enough. A common presentation tip is: \u0026ldquo;Show, don’t tell\u0026rdquo;.\u003c/p\u003e\n\u003cp\u003eWhich is why we launched the\u003cbr\u003e\n\u003ca href=\"http://www.codenameone.com/how-do-i.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\n\u0026ldquo;How Do I?\u0026rdquo;\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nsection in the Codename One website, this section contains short video tutorials demonstrating how to do small things in Codename One from creating your first Codename One application to monetizing and debugging it (upcoming).\u003c/p\u003e","title":"How Do I???"},{"content":"\nThanks for answering our questions about what you want in Codename One 1.1, your answers were very interesting and your comments are always helpful. Before getting to the actual results I’d like to cover some of the comments made in some of the responses which I think broadcast that we need to communicate what we have better:\nA frequent request is for more ad network integration\n_\n\u0026ldquo;AdMob, iAd support and more\u0026rdquo;\n_\nwe are working on those but getting the agreements through and adapting them is difficult. These two specific networks are specifically difficult, Google is very rigid on AdMob and Apple is worse. We are constantly talking with networks about adding support for them (e.g. Zooz and Startapp which were recently integrated), but this is a time consuming slow process.\nA comment asked for:\n_\n\u0026ldquo;Lists that require less code to implement.\u0026rdquo;\n_\n. Did you checkout MultiList? Check out the up to date developer guide which covers them, they are pretty lean and also very easy to work with in the GUI builder.\nOne poster answered\n_\n\u0026ldquo;Fast rendering on iOS (Slow performance on iPad 1 / iOS 5.5.1)\u0026rdquo;\n_\nto which I would like to answer that rendering is pretty fast already. If you feel performance is slow a survey isn’t the place to say that, use the discussion forum and read the developer guide tips.\nMutable images are inherently slow on iOS and drawing most graphics primitives isn’t as fast, however image drawing etc. should be pretty fast.\nOne poster asked for\n_\n\u0026ldquo;Debugging on real device directly from Eclipse/Netbeans\u0026rdquo;\n_\nwhich we plan to do in the future and actually have all the pieces in place for this. It would just require quite a major effort from us to actually accomplish this so this isn’t planned for 1.1.\nWe got one request for\n_\n\u0026ldquo;Proximity Sensor Support\u0026rdquo;\n_\n, I’m guessing that we would have to implement bluetooth, NFC, sockets, motion sensor and only then proximity if at all. There is just too much ground to cover in these things.\nAnother commenter asked for\n_\n\u0026ldquo;Annotations Support to make compilation metaprogramming\u0026rdquo;\n_\n. We already support static annotations, dynamic annotations won’t be possible on older platforms (which might be fine) but would require some reflection capabilities. Since a mobile application is statically linked runtime annotations might be completely redundant since we know of all classes during compile time, that won’t change since we translate bytecode to native.\nMost of the functionality used by annotations is useful with dynamic loading, I would be interested to hear use cases though so feel free to submit issues with specific cases you would want to enable.\nLets look at the results and then I’ll try to interpret them. Feel free to give your own spin in the comments below.\nThe first chart represents the primary feature, listed by rank below.\n[\n](http://1.bp.blogspot.com/-gE-Ly54c7q4/UOhJ5GIyIOI/AAAAAAAAZyM/oZv0N4L-cbA/s1600/chart_2.png)\nWindows Phone 8 support 32.56% Library support 20.93% New layout managers 9.30% Continuous integration 6.98% Improved 2D vector graphics 6.98% Facebook/Google+ side menu 6.98% Infinite scroll/pull to refresh 4.65% bluetooth 4.65% Easy web service wizard 2.33% Theme customizer/colorization tool 2.33% Charts API (graphs) 2.33% Everything below this got 0 percent.\nThe second chart shows the options when picking one of 3 options:\nWindows Phone 8 support 17.22% Library support 16.56% Charts API (graphs) 9.27% Improved 2D vector graphics 7.28% Infinite scroll/pull to refresh 6.62% New layout managers 6.62% Facebook/Google+ side menu 5.96% Continuous integration 5.30% Theme customizer/colorization tool 5.30% Automatic device testing 4.64% Matisse like layout in the GUI builder 3.97% Easy web service wizard 3.31% Support Amazon purchase \u0026amp; push API’s 2.65% IntelliJ Idea support 2.65% Auto complete wizard 1.99% bluetooth 0.66% My interpretation of the data is this:\nPeople want Windows Phone 8 support. We are working on getting it into 1.1. Library support, again a major requested feature although I’m not sure people understand what it means. This doesn’t mean you could take any arbitrary JAR off the internet. We already announced this feature for 1.1 so we are good here. New layout manager made a surprise showing at the top… I think this generally says people find layout managers difficult and hope we would have a better option. But its very likely a new layout manager will suffer from different set of problems from the current ones. I’d be happy if people who voted for this can post examples of what they would want in the comments. It surprised me that no one voted for the Matisse like layout manager in the GUI builder. I’m guessing people didn’t understand that this meant placing components in arbitrary locations and having it \u0026ldquo;just work\u0026rdquo; (sort of). Continuous integration made a great showing, I really want it as part of 1.1. I’m guessing most people who voted for improved vector graphics assume this is about performance or maybe SVG support. If I’m wrong about this feel free to correct me in the comments below. I’d like to start some of the work for this and would especially love to add features such as perspective transform. It surprised me how low bluetooth scored, we will probably not have it for 1.1 either unless we get a code contribution there. Charts have a really high secondary option position and a really low 1st priority position. I think its an important feature but I’m still undecided since its a VERY complex feature to properly integrate. Notice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — January 28, 2013 at 5:09 pm (permalink) Anonymous says:\nThe work I’ve done on the issue indicates a chart is simply another GUI component which is hooked up in a structured way to some non-trivial data source. This doesn’t seem to be complex, other than the Java2D programming required for good rendering on multiple platforms. Have you considered licensing iReports? It’s Java and open source so a port to mobiles adding GUI events to the charts to make them into interactive components might be the most efficient option.\nAnonymous — January 29, 2013 at 3:36 am (permalink) Anonymous says:\nThere are many charting frameworks we can port such as JGraph or JChart etc. The main issue though is getting the underlying graphics capability to support these framework, e.g. a more elaborate affine implementation with a shapes/stroke API. That would require some serious work.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/survey-results-with-some-commentsthoughts/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/survey-results-with-some-commentsthoughts/survey-results-with-some-commentsthoughts-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThanks for answering our questions about what you want in Codename One 1.1, your answers were very interesting and your comments are always helpful. Before getting to the actual results I’d like to cover some of the comments made in some of the responses which I think broadcast that we need to communicate what we have better:\u003c/p\u003e\n\u003cp\u003eA frequent request is for more ad network integration\u003cbr\u003e\n_\u003cbr\u003e\n\u0026ldquo;AdMob, iAd support and more\u0026rdquo;\u003cbr\u003e\n_\u003cbr\u003e\nwe are working on those but getting the agreements through and adapting them is difficult. These two specific networks are specifically difficult, Google is very rigid on AdMob and Apple is worse. We are constantly talking with networks about adding support for them (e.g. Zooz and Startapp which were recently integrated), but this is a time consuming slow process.\u003c/p\u003e","title":"Survey Results With Some Comments/Thoughts"},{"content":"\n**\nUpdate:\n**\nThe survey was completed and its results are published. Thanks for taking the time to answer.\nWe are already gearing to close 1.0 and are looking at the features we would like to get into 1.1 currently slated for May 2013. In that spirit we would love if you would take a few minutes to answer this quick survey.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — March 6, 2013 at 4:25 am (permalink) Anonymous says:\ni thing adding third party library support is more convenient.\nI am using signaturein in my android app so i add these thing easily as\na library or jar AND USE IT\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/what-features-would-you-like-to-see-in-11/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/what-features-would-you-like-to-see-in-11/codename-one-charts-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e**\u003cbr\u003e\nUpdate:\u003cbr\u003e\n**\u003cbr\u003e\nThe survey was completed and its results are published. Thanks for taking the time to answer.\u003c/p\u003e\n\u003cp\u003eWe are already gearing to close 1.0 and are looking at the features we would like to get into 1.1 currently slated for May 2013. In that spirit we would love if you would take a few minutes to answer this quick survey.\u003c/p\u003e\n\u003ch2 id=\"notice-this-post-was-automatically-converted-using-a-script-from-an-older-blogging-system-some-elements-might-not-have-come-out-as-intended-if-that-is-the-case-please-let-us-know-via-the-comments-section-below\"\u003eNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\u003c/h2\u003e\n\u003ch2 id=\"archived-comments\"\u003eArchived Comments\u003c/h2\u003e\n\u003cp\u003e\u003cem\u003eThis post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\u003c/em\u003e\u003c/p\u003e","title":"What Features Would You Like To See In 1.1"},{"content":"\nOne of the common questions we get for Codename One is regarding testability. Cross platform frameworks are notoriously hard to auto-test and so fail when you try to build more complex applications.\nWe see this as one of the most important areas in which we can innovate and leapfrog native OS environments by offering testing that is just as cross platform as Codename One is. We aren’t just announcing our own unit testing API, we are announcing a fully integrated test recorder to auto-generate GUI tests for your applications and run them on the simulator.\nWe will also integrate this exact same testing framework into our build server to seamlessly test device support for you in the future.\nIn the video above you can see me going through the process of recording a test for the kitchen sink and then running it in the simulator.\nI’m sure I’m going to get this question so I’ll hit it right now before it comes up. No the tests are not JUnit compatible and we haven’t used another well known testing framework. The main logic behind this is that tools such as JUnit rely on reflection to work since they use annotations or method invocation without an interface. This doesn’t mesh well with Codename One’s device targets so we chose to implement something of our own.\nYou would have to write most of the test cases for Codename One anyway since the API/functionality would be pretty different.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nMurali Kumar — June 4, 2016 at 1:54 pm (permalink) Murali Kumar says:\nNo audio in the above video\nShai Almog — June 5, 2016 at 4:14 am (permalink) Shai Almog says:\nThe video was recorded without audio just to demo the process. We’ll probably do a more thorough tutorial on building automated tests in the future.\nHristo Vrigazov — September 4, 2016 at 8:17 am (permalink) Hristo Vrigazov says:\nHow can we test classes (without the test recorder)?\nShai Almog — September 5, 2016 at 4:25 am (permalink) Shai Almog says:\nTests are just classes that derive abstract test. You can use the test recorder to create a template and then create as many of those as you want purely from code. The test process auto-detects them and runs them.\nTakii Marskii — October 19, 2016 at 9:03 pm (permalink) Takii Marskii says:\nIs it possible to just run one Script out of the whole Test Scripts? If so how would I do that?\nShai Almog — October 20, 2016 at 2:12 am (permalink) Shai Almog says:\nWe don’t provide that option currently.\nKumuda Garlapati — May 1, 2024 at 6:14 pm (permalink) Kumuda Garlapati says:\nI’m new to codename one and trying to find out how we can record and play back help us testing desktop application, how we can install simulator and record and run the tests. any help is really appreciated.\nShai Almog — May 2, 2024 at 1:27 am (permalink) Shai Almog says:\nThe simulator is a part of the Codename One project. When you run the getting started project it’s there and so is the test recorder. Recorded tests are just source code. You need to add the source to the test package and then you have unit tests.\nKumuda Garlapati — May 2, 2024 at 12:31 pm (permalink) Kumuda Garlapati says:\nok thanks for the info.\nKumuda Garlapati — May 8, 2024 at 4:03 pm (permalink) Kumuda Garlapati says:\nI was able to record the tests but not able to run them as seeing some errors \u0026ldquo;java.lang.ClassCastException: class com.codename1.components.InfiniteProgress cannot be cast to class com.codename1.ui.Container (com.codename1.components.InfiniteProgress and com.codename1.ui.Container are in unnamed module of loader com.codename1.impl.javase.ClassPathLoader @6f539caf)\u0026rdquo;\nJust a question do I need to use specific version of net beans to run tests? I’m not sure what I’m missing here. Thanks\nShai Almog — May 9, 2024 at 10:34 am (permalink) Shai Almog says:\nYou need to edit the tests after recording. The recording process is imperfect by definition and generates code that might fail and might be too fragile (e.g. fail on a different simulator/device).\nIn this case it seems that the failure is triggered by code that shows a progress indicator for a long running task. When recording this wasn’t caught since we skip delays. Otherwise your code would be littered with \u0026ldquo;sleep\u0026rdquo; commands. The code is running too quickly and is then running into the InfiniteProgress component which has taken over the form. You need to wait within the test code for the InfiniteProgress to complete.\nKumuda Garlapati — May 8, 2024 at 5:16 pm (permalink) Kumuda Garlapati says:\nHi Shai Almong, this is the test class that was recorded\npointerPress(0.5816994f, 0.7446808f, new int[]{0, 1, 0, 0, 0, 1, 0, 1});\nwaitFor(149);\npointerRelease(0.5816994f, 0.7446808f, new int[]{0, 1, 0, 0, 0, 1, 0, 1});\npointerPress(0.43809524f, 0.425f, new int[]{0, 1, 0, 2, 1, 2, 0, 0});\nwaitFor(202);\npointerRelease(0.43809524f, 0.425f, new int[]{0, 1, 0, 2, 1, 2, 0, 0});\nreturn true;\nWhenever I try to run encountered error\u0026quot;java.lang.ClassCastException: class com.codename1.components.InfiniteProgress cannot be cast to class com.codename1.ui.Container (com.codename1.components.InfiniteProgress and com.codename1.ui.Container are in unnamed module of loader com.codename1.impl.javase.ClassPathLoader @6f539caf)\u0026quot;\nKumuda Garlapati — May 9, 2024 at 12:17 pm (permalink) Kumuda Garlapati says:\nThank you Shai Almong for the reply, I always worked with selenium, this is a new thing for me, where do i get documentation on how to code?\nKumuda Garlapati — May 10, 2024 at 4:43 pm (permalink) Kumuda Garlapati says:\nI’m able to record and run test cases, I really appreciate your help on this. thanks\nKumuda Garlapati — September 5, 2024 at 2:11 pm (permalink) Kumuda Garlapati says:\nHi Shai Almong, I have a question as we are using test recorder and question is once I record all the tests and when running is it able to handle different screen resolutions?\nShai Almog — September 6, 2024 at 3:02 am (permalink) Shai Almog says:\nNot seamlessly. We try to generate \u0026ldquo;logical code\u0026rdquo; but can’t always detect that correctly.\nKumuda Garlapati — September 6, 2024 at 3:05 pm (permalink) Kumuda Garlapati says:\nGot it. thank you.\nKumuda Garlapati — October 17, 2024 at 2:44 pm (permalink) Kumuda Garlapati says:\nHi Shai Almog, Sorry for bothering you, have a question on whether the .apk file provided to us by developers can be integrated with appium framework are there any limitations or is it compatible? as we have selenium framework for ui and want to have this application embedded into it for better management. Really appreciate your help on this.\nShai Almog — October 19, 2024 at 5:23 am (permalink) Shai Almog says:\nHi,\nWe don’t have any support for Appium. It might be possible to build something like that or adapt existing APIs into a cn1lib but there was no effort in that direction.\nKumuda Garlapati — October 21, 2024 at 12:58 pm (permalink) Kumuda Garlapati says:\nThank you for the reply, I will have conversation with developers.\nKumuda Garlapati — January 7, 2025 at 4:50 pm (permalink) Kumuda Garlapati says:\nHi Shai Almong, We are looking for enabling accessibility id’s to work with android apk automation, Can you tell us how we can enable those in properties file? is there any documentation that we can refer. Thanks for your help.\nShai Almog — January 8, 2025 at 2:50 am (permalink) Shai Almog says:\nI’m afraid not. Accessibility on Android/iOS is one of our big open issues: https://github.com/codenameone/CodenameOne/issues/426\nGaurav P — January 8, 2025 at 1:36 pm (permalink) Gaurav P says:\nHi Shai, is there any ETA we have at the moment for enabling accessibility on Android or iOS. as this is stopping us to perform UI testing on different platforms like iOS, Android, Windows or Mac. Kindly advise\nGaurav P — January 8, 2025 at 1:38 pm (permalink) Gaurav P says:\nHi Shai, is there any ETA we have at the moment for enabling accessibility on Android or iOS. as this is stopping us to perform UI testing on different platforms like iOS, Android, Windows or Mac. Kindly advise\nShai Almog — January 9, 2025 at 2:56 am (permalink) Shai Almog says:\nUnfortunately no. It’s been an open issue for 9 years, I doubt that this will change unless there’s a major drive behind it. It’s a lot of deep effort so community attempts at fixing this even for one platform have failed.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/test-it/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/test-it/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eOne of the common questions we get for Codename One is regarding testability. Cross platform frameworks are notoriously hard to auto-test and so fail when you try to build more complex applications.\u003c/p\u003e\n\u003cp\u003eWe see this as one of the most important areas in which we can innovate and leapfrog native OS environments by offering testing that is just as cross platform as Codename One is. We aren’t just announcing our own unit testing API, we are announcing a fully integrated test recorder to auto-generate GUI tests for your applications and run them on the simulator.\u003c/p\u003e","title":"Test It"},{"content":"\nSteve Hannah\nwho ported Codename One to Avian has just completed a set of benchmarks on Codename One’s iOS performance putting Codename One’s at 33% slower performance than native C and faster performance than Objective-C!\nI won’t spoil his research results so please read his full post\nhere\n.\nA small disclaimer is that the Objective-C benchmark is a bit heavy on the method/message calls which biases the benchmark in our favor. Method invocations in Codename One are naturally much faster than the equivalent Objective-C code due to the semantics of that language.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/codename-one-benchmarked-with-amazing-results/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/codename-one-benchmarked-with-amazing-results/codename-one-benchmarked-with-amazing-results-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/codename-one-benchmarked-with-amazing-results-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/codename-one-benchmarked-with-amazing-results/codename-one-benchmarked-with-amazing-results-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://sjhannah.com/blog/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nSteve Hannah\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\nwho ported Codename One to Avian has just completed a set of benchmarks on Codename One’s iOS performance putting Codename One’s at 33% slower performance than native C and faster performance than Objective-C!\u003c/p\u003e\n\u003cp\u003eI won’t spoil his research results so please read his full post\u003cbr\u003e\n\u003ca href=\"http://sjhannah.com/blog/?p=226\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cbr\u003e\nhere\u003cbr\u003e\n\u003c/a\u003e\u003cbr\u003e\n.\u003c/p\u003e\n\u003cp\u003eA small disclaimer is that the Objective-C benchmark is a bit heavy on the method/message calls which biases the benchmark in our favor. Method invocations in Codename One are naturally much faster than the equivalent Objective-C code due to the semantics of that language.\u003c/p\u003e","title":"Codename One Benchmarked With Amazing Results"},{"content":"\nFonts are were a painful subject in Codename One, historically devices supported a very limited set of fonts and we were bound by said limitations. However, devices moved forward and finally we too can move forward to more reasonable font support.\nThe new font API is limited to Android \u0026amp; iOS, we were considering Blackberry support too but it seems that the font support on Blackberry is too limited for our needs (feel free to correct me if I’m wrong here), on the other platforms a standard system font will be used where fonts aren’t supported.\nIn order to use a font just add the ttf file into the src directory, notice that the file must have the \u0026ldquo;.ttf\u0026rdquo; extension otherwise the build server won’t be able to recognize the file as a font and set it up accordingly (devices need fonts to be defined in very specific ways). Once you do that you can use the font from code or from the theme.\nIn the theme section of the Codename One designer you now have the option to define the font like this:\nThe system font will be used where True Type fonts aren’t supported, the size of the font can be one of 5 options.\nSmall, medium \u0026amp; large correspond to the 3 system font sizes and occupy the exact same sizes of the system fonts.\nMillimeters \u0026amp; pixels will size the fonts appropriately using the numeric field.\nTo use fonts from code just use:\nif (Font.isTrueTypeFileSupported()) { Font myFont = Font.createTrueTypeFont(fontName, fontFileName); myFont = myFont.derive(sizeInPixels, Font.STYLE_PLAIN); // do something with the font } Notice that in code only pixel sizes are supported so its up to you to decide how to convert that. You also need to derive the font with the proper size unless you want a 0 sized font which probably isn’t very useful.\nThe font name is the difficult bit, iOS requires the name of the font which doesn’t always correlate to the file name in order to load the font, its sometimes viewable within a font viewer but isn’t always intuitive so be sure to test that on the device to make sure you got it right.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/fonts-revisited/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/fonts-revisited/fonts-revisited-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/fonts-revisited-large-3.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/fonts-revisited/fonts-revisited-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eFonts are were a painful subject in Codename One, historically devices supported a very limited set of fonts and we were bound by said limitations. However, devices moved forward and finally we too can move forward to more reasonable font support.\u003c/p\u003e\n\u003cp\u003eThe new font API is limited to Android \u0026amp; iOS, we were considering Blackberry support too but it seems that the font support on Blackberry is too limited for our needs (feel free to correct me if I’m wrong here), on the other platforms a standard system font will be used where fonts aren’t supported.\u003c/p\u003e","title":"Fonts Revisited"},{"content":"\nWe just made a major update including a pile of fixes and features. One of the biggest things we are launching right now is an early preview of our new Cloud Storage and Cloud Bind ™ solutions.\nCloud Storage allows you to effectively use our cloud as a big object database, similar to other big data solutions as a sort of key/value pair lookup engine that allows you to share/sync between devices.\nThe Cloud Bind ™ solution allows you to seamlessly bind components such as lists, text components etc. to the cloud where changes automatically persist to the Cloud Storage and data is automatically fetched from there.\nThese are currently limited only to pro users mostly because we haven’t yet figured out the free quotas we want to allocate for free/basic users. We will publish more tutorials and information when we have this fleshed out.\nWe also added an iPhone 5 simulator skin allowing you to generate iPhone 5 resolution screenshots.\nAnd we finally added a bar code/qr code reader API. However, this wasn’t as easy as one would suspect. The problem is that ZXing our API of choice for the QR code in the demo, doesn’t do barcodes on iOS… So we had to use a different implementation on iOS which might not be as good as ZXing with QR codes. So the old native approach will still work if you want it too, but you don’t have to because we have a much simpler API.\nThere is allot more coming in the next couple of months… Stay tuned.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/cloud-storage-cloud-bindtm-iphone-5-simulator-barcodes-and-much-more/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/cloud-storage-cloud-bindtm-iphone-5-simulator-barcodes-and-much-more/codename-one-charts-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe just made a major update including a pile of fixes and features. One of the biggest things we are launching right now is an early preview of our new Cloud Storage and Cloud Bind ™ solutions.\u003c/p\u003e\n\u003cp\u003eCloud Storage allows you to effectively use our cloud as a big object database, similar to other big data solutions as a sort of key/value pair lookup engine that allows you to share/sync between devices.\u003c/p\u003e","title":"Cloud Storage, Cloud Bind(tm), iPhone 5 simulator, barcodes and much more"},{"content":"\nOne of the hardest ideas for developers to grasp in Codename One (or GUI programming in general) is the idea of a single event dispatch thread (EDT). The rules of using it and releasing it are sometimes complex and mistakes are very easy to make e.g.:\nWriting complex/slow code that blocks the EDT thus slowing the entire application Accessing Codename One widgets from a thread that isn’t the EDT. The problem is that both of these issues are notoriously hard to catch on the simulator but often crop up on the device where race conditions can happen more easily and slow EDT performance is more noticeable.\nTo ease the process of detecting these violations we added a flag to the simulator allowing you to receive information about such cases. When using light debugging you will see printouts to the console when accessing the EDT from a separate thread or taking too long to perform the task on the EDT. When setting it to full you will also see the stack trace where the violation was detected.\nThese tools aren’t perfect and they sometimes printout warnings that are unwarranted while entirely missing a real violation. However they can be a valuable tool in improving your application’s portability and responsiveness on multiple devices when used consciously.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/detect-edt-violations/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/detect-edt-violations/detect-edt-violations-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/img/blog/old_posts/detect-edt-violations-large-2.png\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Picture\" loading=\"lazy\" src=\"/blog/detect-edt-violations/detect-edt-violations-1.png\"\u003e\u003cbr\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eOne of the hardest ideas for developers to grasp in Codename One (or GUI programming in general) is the idea of a single event dispatch thread (EDT). The rules of using it and releasing it are sometimes complex and mistakes are very easy to make e.g.:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eWriting complex/slow code that blocks the EDT thus slowing the entire application\u003c/li\u003e\n\u003cli\u003eAccessing Codename One widgets from a thread that isn’t the EDT.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe problem is that both of these issues are notoriously hard to catch on the simulator but often crop up on the device where race conditions can happen more easily and slow EDT performance is more noticeable.\u003c/p\u003e","title":"Detect EDT Violations"},{"content":"\nFor those of you unable to attend JavaOne this year, you can check out the full video of our session here. You don’t actually see me but you can hear me talk and see the slides/demos since the feed from the projector was recorded.\nApple wiped my iPad the day before with a stupid iOS 6 beta bug and my version of the demo had some bugs in it, but other than that I’m pretty happy with the presentation.\nCheck it out.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/screen-capture-of-our-java-one-session/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/screen-capture-of-our-java-one-session/hqdefault.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003eFor those of you unable to attend JavaOne this year, you can check out the full video of our session here. You don’t actually see me but you can hear me talk and see the slides/demos since the feed from the projector was recorded.\u003c/p\u003e\n\u003cp\u003eApple wiped my iPad the day before with a stupid iOS 6 beta bug and my version of the demo had some bugs in it, but other than that I’m pretty happy with the presentation.\u003c/p\u003e","title":"Screen Capture of Our Java One Session"},{"content":"\nWe recently added Windows Phone support to Codename One, this allows you to build your applications as a Windows XAP application for installation on a Windows Phone device. Unfortunately of all the platforms we support (including J2ME and iOS) MS is the only company that chose not to allow standard OTA distribution so you will literally need a PC in order to install the application with a cable.\nMS has a sort of beta distribution option which might alleviate the problem but we didn’t get a chance to try it out.\nSending a build for Windows Phone is similar to sending it to any other platform, with the latest distribution just right click and send a build for Windows Phone, its just that simple.\nUnlike most other platforms MS didn’t burden us with the silly need to sign the distribution (they can sign it themselves when we upload to the store, makes MUCH more sense!).\nInstalling said build requires that you enable your device for development for which you need to pay Microsoft. The instructions for doing all of this are all\nhere\n.\nNotice: This post was automatically converted using a script from an older blogging system. Some elements might not have come out as intended…. If that is the case please let us know via the comments section below. Archived Comments This post was automatically migrated from the legacy Codename One blog. The original comments are preserved below for historical context. New discussion happens in the Discussion section.\nAnonymous — January 22, 2015 at 4:42 pm (permalink) Anonymous says:\nWhen you’re testing your app on the emulator, leave the emulator open between debugging sessions so you can run your app again quickly.\nDiscussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/blog/installing-on-a-windows-phone-device/","summary":"\u003cp\u003e\u003cimg alt=\"Header Image\" loading=\"lazy\" src=\"/blog/installing-on-a-windows-phone-device/codename-one-charts-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eWe recently added Windows Phone support to Codename One, this allows you to build your applications as a Windows XAP application for installation on a Windows Phone device. Unfortunately of all the platforms we support (including J2ME and iOS) MS is the only company that chose not to allow standard OTA distribution so you will literally need a PC in order to install the application with a cable.\u003c/p\u003e","title":"Installing On A Windows Phone Device"},{"content":" Native interfaces are how you call platform-specific code from a Codename One application without giving up the portability of the rest of the project. When Codename One says \u0026ldquo;native\u0026rdquo; in this context, it does not mean Java\u0026rsquo;s ordinary native keyword. It means \u0026ldquo;use the platform\u0026rsquo;s own language and APIs\u0026rdquo; when you need something that the portable Codename One layer does not expose directly.\nThat means the implementation changes by platform. On Android, a native interface implementation can use the Android SDK and third-party Android libraries. On iOS, the implementation uses the native iOS language and APIs. On JavaScript builds, you can call into JavaScript. On the desktop port, you can use ordinary JavaSE APIs. The Java code in your main app remains the same; the native interface is the bridge that dispatches to the right implementation on each platform.\nThe core idea is simple: define an interface that extends NativeInterface, then provide platform-specific implementations of that interface. The interface becomes the contract between your portable Java code and the native side. isSupported() is especially important because not every platform will necessarily have an implementation. Your Java code should check whether the native feature is available before relying on it.\nThis is useful both inside an application and inside a cn1lib. In fact, cn1libs are one of the best uses of native interfaces because they let you wrap messy platform-specific integration behind a clean Java API. The caller sees a normal library. The native details stay hidden inside the implementation.\nThe most important habit here is to keep the native surface area small. Expose the narrowest interface that solves the problem. It is tempting to mirror a large native API directly, but that usually leads to code that is harder to maintain, harder to test, and harder to port. A small interface with a few focused methods is much easier to reason about and much easier to support across platforms.\nNative interfaces also restrict the kinds of types you can pass. That is intentional. Simple values such as primitives, strings, byte arrays, and peers are much easier to move between languages and runtimes. Once you try to pass complex Java objects directly into Objective-C, JavaScript, or other native code, translation becomes far more complicated and performance becomes harder to predict.\nPeerComponent is one of the most important special cases. It allows native code to return a native visual component that can be placed into a Codename One layout like an ordinary component. The classic example is a native map view. That pattern is powerful because it gives you real native UI where it matters while still letting the surrounding screen remain portable.\nThe hard part of native interfaces is often not the code itself but the configuration around it. Native libraries frequently come with Gradle dependencies on Android, CocoaPods or frameworks on iOS, manifest changes, plist changes, and packaging rules for extra files. In Codename One these are usually handled through build hints and native source packaging. If a native library\u0026rsquo;s installation instructions start with \u0026ldquo;add this dependency\u0026rdquo;, \u0026ldquo;edit the manifest\u0026rdquo;, or \u0026ldquo;add this plist entry\u0026rdquo;, you should read that as configuration work that must be expressed through the Codename One build system.\nThe video shows the older \u0026ldquo;generate native stubs from the IDE\u0026rdquo; workflow. The idea behind it is still valid, but the everyday project structure around Codename One is more Maven-centric now. The principle has not changed: define the interface cleanly, implement it per platform, and keep the real fix or integration logic in the project that will survive regeneration and rebuilds.\nFor deeper debugging, the include-sources workflow is still useful. When native code needs to be debugged in the native IDE, generate or inspect the native project, verify the behavior there, and then bring the stable implementation back into the Codename One project. The generated artifacts are useful for diagnosis, but the durable source of truth should remain your actual project and library structure.\nFurther Reading Developer Guide Build Hints Build Server Introduction for Android Developers How Do I Use The Include Sources Feature To Debug The Native Code On iOS/Android Etc. Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-access-native-device-functionality-invoke-native-interfaces/","summary":"\u003cp\u003e\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/2xKvvv7XoVQ?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\nNative interfaces are how you call platform-specific code from a Codename One application without giving up the portability of the rest of the project. When Codename One says \u0026ldquo;native\u0026rdquo; in this context, it does not mean Java\u0026rsquo;s ordinary \u003ccode\u003enative\u003c/code\u003e keyword. It means \u0026ldquo;use the platform\u0026rsquo;s own language and APIs\u0026rdquo; when you need something that the portable Codename One layer does not expose directly.\u003c/p\u003e","title":"ACCESS NATIVE DEVICE FUNCTIONALITY? INVOKE NATIVE INTERFACES?"},{"content":" Client/server work in Codename One usually starts with a simple question: do you want a portable client talking to a server over standard HTTP APIs, or do you want generated RPC-style plumbing that hides some of that protocol detail? The old webservice wizard was designed for the second case. It generated client-side proxies and matching server-side scaffolding so you could define methods and call them almost as if they were local functions.\nThat approach is still useful to understand conceptually, but it is no longer the default direction most modern projects should start with. Today, most teams are better served by ordinary REST-style HTTP APIs, ConnectionRequest, and the higher-level REST helpers described in the developer guide. Those approaches fit better with current backend tooling, current deployment habits, and Maven-era Codename One projects.\nWhat the video still teaches well is the separation of concerns. The client side should know how to invoke a remote capability. The server side should contain the real business logic. Generated proxies can reduce boilerplate, but they do not remove the need to think carefully about API evolution, error handling, and backward compatibility.\nOne lesson from the older wizard flow is still especially important: remote APIs are contracts. Once an app is in production, you cannot casually change method signatures or response shapes and expect every installed client to keep working. If a service needs to evolve incompatibly, version it or add new endpoints instead of silently mutating the old ones.\nThe sync-versus-async distinction also matters regardless of whether you use the old wizard or a modern REST API. A synchronous call is simpler to read, but it blocks the current flow and demands careful error handling. An asynchronous call is usually the healthier default in mobile UI work because it keeps the application responsive and makes network latency explicit in the code.\nFor a current Codename One project, the practical advice is to design a normal server API first, then call it from the client using the networking tools that best match the service. If the service is HTTP-based, prefer the modern REST-oriented client approach. If you are maintaining an older project that already uses the wizard-generated proxies, treat them as an existing contract layer and evolve them carefully rather than rewriting method signatures casually.\nFurther Reading Developer Guide How Do I Use HTTP, Sockets, Webservices And Websockets Terse REST API REST API Design Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-access-remote-webservices-perform-operations-on-the-server/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/sUhpCwd0YJg?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eClient/server work in Codename One usually starts with a simple question: do you want a portable client talking to a server over standard HTTP APIs, or do you want generated RPC-style plumbing that hides some of that protocol detail? The old webservice wizard was designed for the second case. It generated client-side proxies and matching server-side scaffolding so you could define methods and call them almost as if they were local functions.\u003c/p\u003e","title":"ACCESS REMOTE WEBSERVICES? PERFORM OPERATIONS ON THE SERVER?"},{"content":"Trivial usage of the camera to capture a photo\nScreenshots CAMERA DEMO Trivial usage of the camera to capture a photo\nHome CAMERA DEMO Trivial demo showing off usage of the camera via the Capture API.\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\nBlog Post: link\nSource: link\nJS Port: link\nAndroid App: link\nios: link\n","permalink":"https://www.codenameone.com/camera-demo/","summary":"\u003cp\u003eTrivial usage of the camera to capture a photo\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"CAMERA DEMO\" loading=\"lazy\" src=\"/demos/camera-demo-screenshot-1.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"camera-demo\"\u003eCAMERA DEMO\u003c/h2\u003e\n\u003cp\u003eTrivial usage of the camera to capture a photo\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eCAMERA DEMO\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/camera-demo-screenshot-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eTrivial demo showing off usage of the camera via the \u003ca href=\"/manual/misc-features/#_capture_photos_video_audio\"\u003eCapture API\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\u003cbr\u003e\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\u003c/p\u003e","title":"CAMERA DEMO"},{"content":"Shows off the various chart types that can be created with the Codename One charts API\nScreenshots CHARTS DEMO Shows off the various chart types that can be created with the Codename One charts API\nHome CHARTS DEMO The charts demo is derived from an old aChartEngine demo and shows off the various types of charts supported by Codename One. Its highlights include different UI’s for phone/tablet, pinch to zoom/pan and many other capabilities.\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\nBlog Post: link\nSource: link\nJS Port: link\nAndroid App: link\nios: link\n","permalink":"https://www.codenameone.com/charts-demo/","summary":"\u003cp\u003eShows off the various chart types that can be created with the Codename One charts API\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"CHARTS DEMO\" loading=\"lazy\" src=\"/demos/charts-demo-slide-1-7.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"CHARTS DEMO\" loading=\"lazy\" src=\"/demos/charts-demo-slide-4-5.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"CHARTS DEMO\" loading=\"lazy\" src=\"/demos/charts-demo-slide-2-7.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"CHARTS DEMO\" loading=\"lazy\" src=\"/demos/charts-demo-slide-3-7.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"charts-demo\"\u003eCHARTS DEMO\u003c/h2\u003e\n\u003cp\u003eShows off the various chart types that can be created with the Codename One charts API\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eCHARTS DEMO\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/charts-demo-slide-1-7.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/charts-demo-slide-4-5.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/charts-demo-slide-2-7.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/charts-demo-slide-3-7.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe charts demo is derived from an old aChartEngine demo and shows off the various types of charts supported by Codename One. Its highlights include different UI’s for phone/tablet, pinch to zoom/pan and many other capabilities.\u003c/p\u003e","title":"CHARTS DEMO"},{"content":"Full-featured chat app UI component.\nScreenshots Chat App Full-featured chat app UI component.\nHome Chat App Chat App UI Kit RADChatApp is a full-featured chat room app UI component for Codename One. It helps building an elaborate cross-platform chat app UI much faster. Easily customizable to clone UI of social chat apps like WhatsApp, Twitter or Messenger etc.\nFeatures – Provides nice Chat room view out of the box. – User avatar support – Use provided view models or bind to your own view models. – Add your own custom actions. – Nice UI animations when messages are added or removed, or to indicate other users are typing – Add badges (e.g. Like, or Thumbs up) to chat messages Tutorial: link\nSource: link\nJS Port: link\nAndroid App: link\n","permalink":"https://www.codenameone.com/chat-app/","summary":"\u003cp\u003eFull-featured chat app UI component.\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"Chat App\" loading=\"lazy\" src=\"/demos/chat-app-demos-chatapp.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"chat-app\"\u003eChat App\u003c/h2\u003e\n\u003cp\u003eFull-featured chat app UI component.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eChat App\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/chat-app-demos-chatapp.png\"\u003e\u003c/p\u003e\n\u003ch4 id=\"chat-app-ui-kit\"\u003eChat App UI Kit\u003c/h4\u003e\n\u003cp\u003eRADChatApp is a full-featured chat room app UI component for Codename One. It helps building an elaborate cross-platform chat app UI much faster. Easily customizable to clone UI of social chat apps like WhatsApp, Twitter or Messenger etc.\u003c/p\u003e\n\u003ch4 id=\"features\"\u003eFeatures\u003c/h4\u003e\n\u003cul\u003e\n\u003cli\u003e– Provides nice Chat room view out of the box.\u003c/li\u003e\n\u003cli\u003e– User avatar support\u003c/li\u003e\n\u003cli\u003e– Use provided view models or bind to your own view models.\u003c/li\u003e\n\u003cli\u003e– Add your own custom actions.\u003c/li\u003e\n\u003cli\u003e– Nice UI animations when messages are added or removed, or to indicate other users are typing\u003c/li\u003e\n\u003cli\u003e– Add badges (e.g. Like, or Thumbs up) to chat messages\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eTutorial: \u003ca href=\"https://shannah.github.io/RADChatApp/getting-started-tutorial.html\" target=\"_blank\" rel=\"noopener noreferrer\"\u003elink\u003c/a\u003e\u003c/p\u003e","title":"Chat App"},{"content":"Calculator and calendar within a tab UI\nScreenshots CHROME Calculator and calendar within a tab UI\nHome CHROME Chrome was one of the early Codename One demos during the era of iOS 4.x. Back then it featured a chrome like brushed metal interface that looked modern. However, it didn’t age well. It is based on a native iOS demo licensed from app design vault.\nWe tried to modernize the look of Chrome but it is not the best looking or most functional demo there is. We still think it features a unique look and the calculator portion of the demo alone is remarkably valuable!\nThe original demo was written using the old Codename One GUI builder, whereas this one was converted to Java 8 syntax and uses the new GUI builder. We also replaced builtin icons where possible with material design font icons and flattened as much of the UI as possible.\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\nSource: link\nJS Port: link\nAndroid App: link\nios: link\n","permalink":"https://www.codenameone.com/chrome/","summary":"\u003cp\u003eCalculator and calendar within a tab UI\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"CHROME\" loading=\"lazy\" src=\"/demos/chrome-slide-1-1-1.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"chrome\"\u003eCHROME\u003c/h2\u003e\n\u003cp\u003eCalculator and calendar within a tab UI\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eCHROME\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/chrome-slide-1-1-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eChrome was one of the early Codename One demos during the era of iOS 4.x. Back then it featured a chrome like brushed metal interface that looked modern. However, it didn’t age well. It is based on a native iOS demo licensed from \u003ca href=\"http://www.appdesignvault.com/shop/chrome/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eapp design vault\u003c/a\u003e.\u003cbr\u003e\nWe tried to modernize the look of Chrome but it is not the best looking or most functional demo there is. We still think it features a unique look and the calculator portion of the demo alone is remarkably valuable!\u003cbr\u003e\nThe original demo was written using the old Codename One GUI builder, whereas this one was converted to Java 8 syntax and uses the new GUI builder. We also replaced builtin icons where possible with material design font icons and flattened as much of the UI as possible.\u003c/p\u003e","title":"CHROME"},{"content":"Gorgeous design as the designer intended\nScreenshots CLEAN MODERN – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP Gorgeous design as the designer intended\nHome CLEAN MODERN – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP This demo ports a set of PSD designs to a fully functional cross platform Codename One app, it also takes those designs for a high resolution Android device and makes them useable in any resolution device.\nSince this isn’t a \u0026ldquo;real application\u0026rdquo; with functionality it can’t be distributed thru the stores so we can’t provide an iOS version or even upload it to Google Play. We provide the ability to download the APK for Android and full source code. Notice that the images are all actual device screenshots from an Android One Plus One device.\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nBlog Post: link\nSource: link\nJS Port: link\nAndroid App: link\n","permalink":"https://www.codenameone.com/clean-modern-port-of-psd-design-to-cross-platform-native-mobile-app/","summary":"\u003cp\u003eGorgeous design as the designer intended\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"CLEAN MODERN – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP\" loading=\"lazy\" src=\"/demos/clean-modern-port-of-psd-design-to-cross-platform-native-mobile-app-slide-1-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"CLEAN MODERN – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP\" loading=\"lazy\" src=\"/demos/clean-modern-port-of-psd-design-to-cross-platform-native-mobile-app-slide-2-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"CLEAN MODERN – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP\" loading=\"lazy\" src=\"/demos/clean-modern-port-of-psd-design-to-cross-platform-native-mobile-app-slide-3-4.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"CLEAN MODERN – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP\" loading=\"lazy\" src=\"/demos/clean-modern-port-of-psd-design-to-cross-platform-native-mobile-app-slide-4-4.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"CLEAN MODERN – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP\" loading=\"lazy\" src=\"/demos/clean-modern-port-of-psd-design-to-cross-platform-native-mobile-app-slide-5-3.png\"\u003e\u003c/p\u003e","title":"CLEAN MODERN – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP"},{"content":"Simple demo demonstrating an analog clock with the shape API\nScreenshots CLOCK DEMO Simple demo demonstrating an analog clock with the shape API\nHome CLOCK DEMO The Clock Demo shows an analog clock that animates while showing the time. It uses the shape API to draw the hands of the clock.\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\nBlog Post: link\nSource: link\nJS Port: link\nAndroid App: link\nios: link\n","permalink":"https://www.codenameone.com/clock-demo/","summary":"\u003cp\u003eSimple demo demonstrating an analog clock with the shape API\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"CLOCK DEMO\" loading=\"lazy\" src=\"/demos/clock-demo-slide-1-4.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"clock-demo\"\u003eCLOCK DEMO\u003c/h2\u003e\n\u003cp\u003eSimple demo demonstrating an analog clock with the shape API\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eCLOCK DEMO\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/clock-demo-slide-1-4.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe Clock Demo shows an analog clock that animates while showing the time. It uses the shape API to draw the hands of the clock.\u003c/p\u003e\n\u003cp\u003eNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\u003cbr\u003e\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\u003c/p\u003e","title":"CLOCK DEMO"},{"content":" The first Codename One application you build in Eclipse should be intentionally small. Create the project with the initializr, import it into Eclipse as a Maven project, and aim for something that starts in the simulator, shows a form, and responds when you press a button. The video is out of date in one important way: it starts from the old Eclipse plugin workflow. The actual lesson is still valid, but the modern setup is Maven-based and does not depend on the legacy IDE plugins.\nOne of the first choices that matters is the package name. It is easy to treat that as temporary when you are just building a sample app, but package names become part of the app\u0026rsquo;s identity and eventually affect signing, store metadata, and native packaging. Pick a stable reverse-domain package from the beginning so you do not have to rename it later when the project is already in motion.\nOnce the project is open, spend a few minutes reading the generated application class. Codename One applications still revolve around init(), start(), stop(), and destroy(). init() is where one-time setup belongs. start() is where you build and show the first UI. stop() handles the app moving into the background, and destroy() is there for shutdown cleanup. Understanding those lifecycle methods is one of the most useful things a hello world app can teach.\nKeep the first screen simple. Create a Form, add a button, attach an action listener, and show a dialog when the button is pressed. That tiny exercise proves that the project imports correctly, the application starts, the UI appears, and events are firing. You do not need more than that to confirm that the environment is healthy.\nThe simulator should be your primary feedback loop at this stage. Run the app, switch device skins if you want to see how the layout behaves, and make sure the form survives the normal stop-and-start flow. Device builds matter, but they come after the simulator loop is already stable. In practice Android is usually the easiest first target. iOS generally comes later because certificates and provisioning need to be set up before the build becomes useful.\nStyling and localization are the other places where the old workflow needs translation. The video moves from the basic app into the theme designer and resource editor because that was a common path at the time. For new projects, CSS is the better default for styling and l10n property bundles are the better default for localization. The older tools still work, but they are no longer the path most new apps should start with.\nThat leaves a straightforward modern workflow: generate a Maven project, choose a good package name, understand the lifecycle, build one small interactive form, validate it in the simulator, and then send a device build. Once those basics are in place, you can keep building in normal Java code while using CSS for styling and property bundles for localization.\nFurther Reading Initializr Getting Started Hello World Development Environment Build Server Themeing Moving To Maven Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-create-a-basic-hello-world-application-send-it-to-my-device-using-eclipse/","summary":"\u003cp\u003e\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/fmNpMFLwABA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\nThe first Codename One application you build in Eclipse should be intentionally small. \u003ca href=\"/initializr/\"\u003eCreate the project with the initializr\u003c/a\u003e, import it into Eclipse as a Maven project, and aim for something that starts in the simulator, shows a form, and responds when you press a button. The video is out of date in one important way: it starts from the old Eclipse plugin workflow. The actual lesson is still valid, but the modern setup is Maven-based and does not depend on the legacy IDE plugins.\u003c/p\u003e","title":"CREATE A BASIC HELLO WORLD APPLICATION \u0026 SEND IT TO MY DEVICE USING ECLIPSE"},{"content":" The easiest way to get started in IntelliJ is to open a Maven-based Codename One project and keep the first version of the app very small. Create the project with the initializr, import it into IntelliJ, and aim for something that starts in the simulator without surprises and does one obvious thing when you press a button. The video demonstrates the same first milestone, but it gets there through the old IDE plugin flow, which is no longer the recommended setup. That small app is enough to prove that the environment is working and to give you a solid base for the next step.\nThe first decision worth making carefully is the package name. In Codename One it eventually shows up in builds, signing, store metadata, and native packaging, so it is worth choosing a stable reverse-domain package from the beginning. Renaming a package later is possible, but once a project has started to accumulate build configuration and native artifacts it becomes much more annoying than it looks.\nOnce the project is open, the generated application class is the most important thing to understand. Codename One applications still revolve around init(), start(), stop(), and destroy(). init() is where one-time application setup belongs. start() is where you create or show the first screen. stop() is called when the app is backgrounded, and destroy() is reserved for final cleanup when the application is really shutting down. If you understand those four methods early, the rest of the framework becomes much easier to reason about.\nFor a first app, create a single form and add one interactive component to it. A button that opens a dialog is enough. That tiny exercise proves several important things at once: the app started successfully, the form was shown from start(), components were added correctly, and events are firing as expected. In practice that is much more valuable than jumping immediately into themes, navigation frameworks, or platform integration.\nThe simulator is still the fastest place to do this first pass. Run the app, press the button, switch simulator skins if you want to see how the screen behaves on different devices, and make sure the application survives stop-and-start cycles. You do not need to solve device-specific issues before you even know that the application works locally. Once the simulator loop is stable, send a native build. Android is usually the easiest first target. iOS still requires signing and provisioning, so it is normal to validate Android first and then handle Apple certificates afterwards.\nOne part of the video is clearly dated. It moves from the generated app into the older theme designer and resource-editor workflow. For a new project, the better path is to style with CSS and handle localization with l10n property bundles. The designer and resource editor still work, but they are awkward enough that they should not be the default recommendation for new development.\nSo the practical workflow is straightforward: start with a Maven project, understand the lifecycle, build one small interactive form, validate it in the simulator, and then send a device build. After that, keep the app logic in code, move styling into CSS, and use property bundles when you add localization.\nFurther Reading Getting Started Development Environment Hello World Build Server Themeing Create an iOS Provisioning Profile Moving To Maven Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-create-a-basic-hello-world-application-send-it-to-my-device-using-intellij-idea/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/oR3KHYf5OrY?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe easiest way to get started in IntelliJ is to open a Maven-based Codename One project and keep the first version of the app very small. \u003ca href=\"/initializr/\"\u003eCreate the project with the initializr\u003c/a\u003e, import it into IntelliJ, and aim for something that starts in the simulator without surprises and does one obvious thing when you press a button. The video demonstrates the same first milestone, but it gets there through the old IDE plugin flow, which is no longer the recommended setup. That small app is enough to prove that the environment is working and to give you a solid base for the next step.\u003c/p\u003e","title":"CREATE A BASIC HELLO WORLD APPLICATION \u0026 SEND IT TO MY DEVICE USING INTELLIJ/IDEA"},{"content":" The first Codename One application you build in NetBeans should be deliberately simple. Create the project with the initializr, open it in NetBeans as a Maven project, and aim for an app that starts in the simulator, shows a form, and responds to one button press. The video uses the old NetBeans plugin flow, which is no longer the recommended way to start a project, but the underlying lesson is still the same: begin with a tiny app that teaches you the lifecycle and the development loop.\nThe package name is one of the first things worth deciding carefully. It may look unimportant in a hello world app, but later it becomes part of signing, native packaging, and store submission. A stable reverse-domain package name will save you from an annoying rename once the project begins to grow.\nAfter the project opens, look at the generated application class before making larger changes. init() is for one-time application setup, start() is where you create and show the first form, stop() handles the app moving to the background, and destroy() is there for shutdown cleanup. Those methods are the backbone of a Codename One app, and understanding them early makes the rest of the framework much easier to follow.\nFor the actual hello world UI, keep it boring on purpose. Create a form, add a button, and have the button show a dialog. That is enough to prove that the project opens correctly, the lifecycle is working, the UI renders, and action listeners are firing. You do not need complex navigation or custom components to learn the right first lessons.\nThe simulator is still the fastest place to validate this work. Run the app, switch device skins if needed, and make sure the form behaves the way you expect. Once that loop is stable, send a native build. Android is usually the easiest first target. iOS is still more demanding because of certificates and provisioning, so it is normal to get Android working first and then return to Apple signing later.\nOne part of the video does need an explicit update. It moves naturally from the generated app into the older theme designer and resource editor. For new projects, CSS is now the better default for styling and l10n property bundles are the better default for localization. The designer and resource editor are still supported, but they are not where most modern Codename One projects should start.\nSo the modern NetBeans version of this lesson is straightforward: start from the initializr, import the Maven project, understand the lifecycle, build a tiny interactive form, verify it in the simulator, then send a device build. From there, keep the app logic in code, style with CSS, and use property bundles when you localize.\nFurther Reading Initializr Getting Started Hello World Development Environment Build Server Themeing Moving To Maven Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-create-a-basic-hello-world-application-send-it-to-my-device-using-netbeans/","summary":"\u003cp\u003e\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/73d65cvyQv4?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\nThe first Codename One application you build in NetBeans should be deliberately simple. \u003ca href=\"/initializr/\"\u003eCreate the project with the initializr\u003c/a\u003e, open it in NetBeans as a Maven project, and aim for an app that starts in the simulator, shows a form, and responds to one button press. The video uses the old NetBeans plugin flow, which is no longer the recommended way to start a project, but the underlying lesson is still the same: begin with a tiny app that teaches you the lifecycle and the development loop.\u003c/p\u003e","title":"CREATE A BASIC HELLO WORLD APPLICATION \u0026 SEND IT TO MY DEVICE USING NETBEANS"},{"content":" A good side menu does two jobs at once. It gives the user a clear navigation structure, and it makes that structure feel intentional rather than bolted on. The old video builds this through the toolbar side-menu APIs and then styles the result in the theme designer. The basic navigation idea still works, but the modern styling path should usually be CSS rather than designer-driven theme editing.\nThe first step is structural rather than visual. Define the side-menu commands you actually need, give them clear labels, and choose icons that reinforce the meaning instead of decorating it. A side menu becomes cluttered quickly when it is used as a dumping ground for everything that does not fit elsewhere in the UI.\nOnce the commands exist, the real visual work is about hierarchy and spacing. The menu background, the command row style, the selected state, and the optional header area all need to feel like part of the same visual system. The video spends time on padding, alignment, color, and pressed-state styling, and those are still the right levers to care about. Touch targets need enough padding to feel comfortable, selected states need to be obvious, and typography needs to be readable before it tries to be clever.\nThe older workflow styles these pieces in the theme editor with UIIDs such as the side command and the side panel. In a new project, those same ideas should usually be expressed in CSS. That gives you a more maintainable styling workflow and makes it easier to keep the side menu aligned with the rest of the application theme.\nThe header area at the top of the menu is often what separates an ordinary side menu from one that feels designed. A logo, profile image, app title, or short tagline can make the menu feel anchored instead of generic. The video demonstrates this by building a top section from ordinary components and then adding it to the toolbar side menu. That is still the right way to think about it: the decorative header is just another piece of UI composition, not a special magic feature.\nThe main modern caution is not to over-invest in ornament if the menu is no longer the primary navigation pattern for the app. Some applications are now better served by bottom navigation, tabs, or a simpler toolbar structure. A side menu is still useful, but it should be chosen because it fits the navigation model, not because it was once the default mobile pattern.\nFurther Reading Themeing Developer Guide Layout Basics How Do I Create A Simple Theme Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-create-gorgeous-sidemenu/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/99DAeP9LG6c?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eA good side menu does two jobs at once. It gives the user a clear navigation structure, and it makes that structure feel intentional rather than bolted on. The old video builds this through the toolbar side-menu APIs and then styles the result in the theme designer. The basic navigation idea still works, but the modern styling path should usually be CSS rather than designer-driven theme editing.\u003c/p\u003e","title":"CREATE A GORGEOUS SIDEMENU"},{"content":" If you need to show a vertical list of items in Codename One, the first question is not \u0026ldquo;how do I use List?\u0026rdquo; It is \u0026ldquo;what kind of scrolling UI am I actually building?\u0026rdquo; The video makes a point that still matters: for many ordinary mobile screens, a vertically stacked container of components is easier to reason about than the older List API.\nA simple and effective pattern is to use a container with BoxLayout.y() and place it in a scrollable area. That gives you full control over each row. You can use MultiButton, your own custom components, or any other component structure that fits the design. For small and medium-sized data sets, this is often the cleanest way to build a list-like screen.\nThe point where this changes is scale. If the data set is large, you should not create hundreds or thousands of row components eagerly. That is where InfiniteContainer and related lazy-loading patterns become valuable. Instead of building the entire list at once, you fetch components in batches as the user scrolls. The video uses contacts as an example, and that is still a good way to think about it: load enough to keep the UI responsive, then fetch more as needed.\nScrolling behavior is part of the design, not an afterthought. A scrollable list container needs room to stretch properly, which is why placing it in the CENTER of a BorderLayout is such a common pattern. Nested scrolling should also be treated carefully, because touch interfaces are much harder to use when multiple scrollable areas compete for the same gesture.\nLazy-loading also changes how you think about per-row work. If an item depends on expensive data such as an image, do not block the row creation path longer than necessary. Show a placeholder, let the row appear quickly, and then fill in the heavier data when the application has time. The older example uses contact images and idle callbacks to illustrate this, and the underlying lesson is still sound: rows should become visible fast, then improve gracefully as more data arrives.\nSearch fits naturally into this model when you treat the visible data as a view over a larger data set. Change the filter, refresh the list, and let the fetch logic rebuild the visible subset instead of trying to mutate dozens of existing components manually. That keeps the mental model simple and scales better as the screen evolves.\nThe main thing that changed since the video is not the underlying idea but the broader UI workflow around it. In modern projects, the structure of the row still belongs in code and layout, but much of the visual styling should be pushed into CSS. That keeps complex list screens easier to maintain as they grow.\nFurther Reading Layout Basics Developer Guide How Do I Positioning Components Using Layout Managers How Do I Improve Application Performance Or Track Down Performance Issues Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-create-a-list-of-items-the-easy-way/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/0m7Bay4g93k?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eIf you need to show a vertical list of items in Codename One, the first question is not \u0026ldquo;how do I use \u003ccode\u003eList\u003c/code\u003e?\u0026rdquo; It is \u0026ldquo;what kind of scrolling UI am I actually building?\u0026rdquo; The video makes a point that still matters: for many ordinary mobile screens, a vertically stacked container of components is easier to reason about than the older \u003ccode\u003eList\u003c/code\u003e API.\u003c/p\u003e","title":"CREATE A LIST OF ITEMS"},{"content":" Styling in Codename One starts with a simple question: are you trying to change how components look, or are you trying to change how the UI behaves structurally? If the answer is visual styling, the modern default is CSS. The video uses the older designer-centered theme workflow, and that still helps explain the underlying concepts, but for a new project you should usually start with CSS and treat the older theme editor as a lower-level tool rather than the main path.\nThe concepts behind theming are still the same. Components get their appearance from a UIID. A UIID is effectively the name of the style a component uses. If you create a button and give it a custom UIID, that UIID becomes the hook for styling the button consistently. This is true whether the style is defined in CSS or in the older theme resource workflow.\nThe simplest useful example is a custom button. Give it a background color, a foreground color, some padding, and a readable font size. The point is not to make it beautiful on the first pass. The point is to understand which properties actually shape the component. Background and foreground colors control the obvious look, but spacing is just as important. Padding affects the space inside the component and therefore the touchable area. Margin affects the space outside the component and therefore the relationship between neighboring components. If a button feels cramped, that is often a spacing problem before it is a color problem.\nPortable sizing still matters here. The old advice to think in physical units rather than raw pixels is still sound. On touch devices, spacing and font sizes need to survive different densities and form factors. That is one reason the visual result can look fine on one platform and wrong on another if you only style the default state and ignore the rest.\nState-specific styling is one of the first places where theming becomes real. A button usually needs at least an unselected appearance and a pressed or selected appearance. If the normal state has one background and the pressed state has no explicit styling, the result can feel inconsistent or broken. The video demonstrates this with borders and selected styles, and the underlying lesson remains important: style all of the states that matter, not just the first one you see in the simulator.\nBorders are another common source of confusion. In the older theme editor, borders often take precedence over background settings, which is why a component can look correct on one platform but unexpectedly wrong on another. The same general rule applies conceptually even when you work in CSS: understand which visual property is actually winning. If a component is not rendering the way you expected, check the full style, not just the one value you most recently changed.\nThe other important concept from the video is inheritance. A custom style does not need to redefine everything from scratch. It is usually better to start from a base component style and override only what you actually want to change. That keeps your styles smaller and more maintainable. In practice this means defining a custom UIID that keeps the core behavior of a Button or TextField while changing color, spacing, fonts, or borders.\nOnce that pattern clicks, the rest of theming becomes much easier. You can create a second button style, apply the same UIID to a different component where appropriate, and reason about the result as a consistent design system instead of one-off tweaks. You can also change style values in code, but that is generally the exception rather than the default. For most visual work, CSS is cleaner and easier to maintain.\nTheme constants and other lower-level theme settings still matter, especially when you are controlling broader application behavior or integrating with older theme-based assets. But for a new project, the practical approach is simpler than the older lesson suggests: use layouts to define structure, use CSS to define appearance, and only drop to the older theme tooling when you genuinely need the lower-level control.\nFurther Reading Themeing Developer Guide Layout Basics Designer Hello World Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-create-a-simple-theme/","summary":"\u003cp\u003e\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/cxllJwt10VU?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\nStyling in Codename One starts with a simple question: are you trying to change how components look, or are you trying to change how the UI behaves structurally? If the answer is visual styling, the modern default is CSS. The video uses the older designer-centered theme workflow, and that still helps explain the underlying concepts, but for a new project you should usually start with CSS and treat the older theme editor as a lower-level tool rather than the main path.\u003c/p\u003e","title":"CREATE A SIMPLE THEME"},{"content":" Creating an iOS provisioning profile is really about assembling a matching set of Apple-side credentials and identifiers so that the app you build, the devices you test on, and the certificate you sign with all agree with each other. If any one of those pieces is misaligned, the build may still complete, but installation or submission will fail later.\nThe first step is to make sure the app identifier is correct. In Apple terms, the App ID needs to match the package identifier of your Codename One application. This is one reason package naming matters so much early in a project. Once provisioning, signing, and store submission are involved, renaming is much more annoying than it looks.\nFrom there, development and distribution provisioning split into two different jobs. Development provisioning is for testing on specific physical devices. That means the devices must be registered with the Apple developer account, and the development profile must explicitly include them. Distribution provisioning is for App Store delivery and does not include test devices in the same way.\nCertificates are the next piece. You need the right development and distribution signing certificates, and you need them exported in a form the build process can use. The old video explains this through Apple’s portal and the Keychain export flow, and that basic idea is still correct even though Apple’s UI changes over time. The stable rule is simple: the certificate, the provisioning profile, and the app identifier must all refer to the same app and account context.\nOnce those files exist, Codename One needs to know where they are and what passwords protect them. That is the bridge between the Apple-side account setup and the actual build. If the certificates import correctly and the provisioning profile matches the project, sending an iOS build becomes routine. If they do not, the error usually appears later in a frustrating way, which is why getting the identity chain right up front matters so much.\nThe video is useful as a picture of the overall flow, but the modern thing to remember is that Apple’s portal screens change while the underlying relationships do not. You always need the same core pieces: a matching app ID, development devices for local testing, development and distribution profiles, and exportable certificates that line up with them.\nFurther Reading Build Server Development Environment Hello World Developer Guide Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-create-an-ios-provisioning-profile/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/OWHizrNyizQ?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eCreating an iOS provisioning profile is really about assembling a matching set of Apple-side credentials and identifiers so that the app you build, the devices you test on, and the certificate you sign with all agree with each other. If any one of those pieces is misaligned, the build may still complete, but installation or submission will fail later.\u003c/p\u003e","title":"CREATE AN IOS PROVISIONING PROFILE"},{"content":" Backgrounds and borders in Codename One are easiest to understand once you stop treating them as a pile of theme options and start thinking in terms of rendering precedence. A component does not simply combine every visual setting you give it. Some background choices override others. Borders can override background images. Gradients can override plain background colors. If a component is not rendering the way you expected, the first question is often not \u0026ldquo;did my value save?\u0026rdquo; but \u0026ldquo;which style layer is actually winning?\u0026rdquo;\nThe older video explains this through the designer tool, but the concepts matter just as much when you style with CSS. In modern projects, CSS should usually be the main styling path, while the designer and resource editor are lower-level tools you use when you genuinely need them. The visual rules themselves are still the same: understand the border type, understand the background type, and understand how state-specific styles inherit from one another.\nThe most important image-border concept is still the 9-piece border. It exists because some shapes need to scale without looking stretched or blurry. Instead of treating a border as one image, you split it into corners, edges, and a center. The corners remain fixed, while the edge and center regions tile or expand as needed. That lets the component grow while preserving the look of the decorative frame.\nCutting a good 9-piece border is mostly about judgment. Keep the corners isolated so they are never tiled. Keep distinctive details such as speech-bubble arrows or ornamental edges out of the tiled regions, otherwise they will smear when the component grows. The old wizard-based workflow still illustrates this well, even if the everyday styling recommendation today is more CSS-first than designer-first.\nState handling matters just as much as the base border. A component rarely has only one appearance. Buttons, for example, usually need unselected, pressed, and selected variants. If you only style the default state, the component may suddenly pick up a strange native border or inconsistent highlight on another state. This is one reason the video spends time on empty borders and inherited styles: clearing or overriding the wrong inherited border can be the difference between a clean result and a confusing one.\n9-piece borders also interact with device density. If you are using raster imagery, you need to think about how the pieces scale across different densities. Multi-images are still relevant in that sense, but in a modern project the first question should be whether the effect really needs raster artwork at all. If a clean CSS border or a round border can achieve the same visual result, that is often easier to maintain and easier to adapt.\nThe broader lesson is that visual styling should be deliberate. Use the right border type for the job, style all of the component states that matter, and prefer simpler modern styling mechanisms when they can produce the same effect. 9-piece borders are still useful, but they are no longer the default answer to every styling problem.\nFurther Reading Themeing Developer Guide How Do I Create A Simple Theme Work With Multi Images And Device Densities Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-create-a-9-piece-image-border/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/ACsZ8qiwR8Q?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eBackgrounds and borders in Codename One are easiest to understand once you stop treating them as a pile of theme options and start thinking in terms of rendering precedence. A component does not simply combine every visual setting you give it. Some background choices override others. Borders can override background images. Gradients can override plain background colors. If a component is not rendering the way you expected, the first question is often not \u0026ldquo;did my value save?\u0026rdquo; but \u0026ldquo;which style layer is actually winning?\u0026rdquo;\u003c/p\u003e","title":"CUSTOMIZE COMPONENT BORDERS AND BACKGROUNDS"},{"content":" Debugging on an Android device is the right move when the simulator is no longer telling you enough. If the problem only happens on Android hardware, only appears after a native build, involves Android permissions or activities, or touches native integration code, then you need visibility into the generated Android project and the device runtime.\nThe video shows the older version of this process: enable source inclusion, send an Android build, download the generated sources, create an Android Studio project, copy the generated code into it, and debug from there. The important idea is that when you need to understand what the Android side is doing, the generated native sources are valuable. What has changed is how often you should do this. It is no longer something you should think of as part of normal day-to-day development.\nIn a modern Codename One project, the application source in your main project is still the source of truth. Start there first. If the problem reproduces in the simulator, stay in the regular Codename One codebase and debug it there. If the bug only appears on Android, then generate the Android sources with source inclusion enabled and use Android Studio to inspect what the native output is doing.\nThe useful workflow is to treat the generated Android project as a debugging artifact. Open it in Android Studio, connect a device, run under the debugger, inspect logcat, and place breakpoints in the generated sources or any native bridge code that is relevant to the problem. This is especially useful for permission issues, manifest problems, native interface behavior, packaging problems, and crashes that only occur on device. Once you understand the failure, move the real fix back into your Codename One application, native interface implementation, or build configuration.\nThat last step is the important one. You should not maintain fixes directly in the generated Android sources because those files are regenerated on the next build. The generated project is there so you can observe and diagnose. The durable fix belongs in the actual project that produced it.\nThe video is also a bit out of date in how manual the Android Studio setup is. Today the surrounding toolchain is cleaner and more Maven-centric, but the same principle applies: include sources when you need deeper visibility, inspect the generated Android project only for Android-specific failures, and then carry the solution back to the real codebase. If you approach it that way, Android Studio becomes a precise debugging tool instead of a second development environment you have to keep in sync.\nFurther Reading Introduction for Android Developers Build Server Build Tools Development Environment Moving To Maven Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-debug-on-an-android-device/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/008AK1GfHA8?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eDebugging on an Android device is the right move when the simulator is no longer telling you enough. If the problem only happens on Android hardware, only appears after a native build, involves Android permissions or activities, or touches native integration code, then you need visibility into the generated Android project and the device runtime.\u003c/p\u003e","title":"DEBUG A CODENAME ONE APPLICATION ON AN ANDROID DEVICE"},{"content":" Debugging into Codename One source is one of the most useful ways to understand why a framework-level behavior is happening. It lets you answer questions that are hard to resolve from application code alone: is the issue in your usage, in the framework, in a specific port, or in a recent Codename One change?\nThe basic workflow is to work against the actual Codename One source tree instead of only depending on prebuilt jars. Once the relevant projects are checked out and wired into your IDE, stepping into a framework class takes you to real source that you can read, debug, modify, and test immediately. That turns Codename One from a black box into an ordinary codebase you can inspect like any other dependency under development.\nThe old video is IDE-specific and reflects an older project setup, but the important lesson is unchanged: if you want to debug framework behavior seriously, you need the source projects in your workspace and you need your application to resolve against them instead of the packaged binaries.\nThis is valuable even if you never plan to contribute a patch. Walking into framework code while the debugger is live is often the fastest way to understand why a UI behaves the way it does, why a property is ignored, or why a specific port diverges from another. Reading the code is useful; reading it while stopped at the relevant call site is better.\nOnce you are set up this way, local experimentation becomes much easier. You can make a framework change, rerun the app, and immediately verify whether the change solves the problem. That is often faster than trying to infer the right fix abstractly. The video demonstrates this by adding a small utility method and pushing it through a fork, but the broader point is that Codename One can be debugged and modified with the same workflows you would use for any normal open source Java project.\nIf you do decide to contribute a fix, keep the standard open source rules in mind. Make sure you own the code you are submitting, preserve the project\u0026rsquo;s legal and coding conventions, and keep the change focused. Small, clear contributions are easier to review and easier to merge than wide changes that mix refactoring, cleanup, and new behavior all at once.\nIt is also smart to discuss non-trivial changes before investing heavily in them. If a proposed fix changes behavior or introduces a new API, a short discussion first can save a lot of time and reduce the chance that the patch heads in the wrong direction.\nThe real educational value here is that the framework source is not off-limits. If something in Codename One is confusing, stepping into it is often the right move. Even if the final outcome is not a pull request, understanding the code path usually improves how you structure your own application and how you diagnose similar issues later.\nFurther Reading Developer Guide How Do I Find Problems In My Application Using The Codename One Tools And The Standard IDE Tools? How Do I Debug On An Android Device How Do I Use The Include Sources Feature To Debug The Native Code On iOS/Android Etc. Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-debug-into-codename-one-source-modify-it-contribute-it-back/","summary":"\u003cp\u003e\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/2nD75pODPWk?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\nDebugging into Codename One source is one of the most useful ways to understand why a framework-level behavior is happening. It lets you answer questions that are hard to resolve from application code alone: is the issue in your usage, in the framework, in a specific port, or in a recent Codename One change?\u003c/p\u003e","title":"DEBUG INTO CODENAME ONE SOURCE, MODIFY IT \u0026 CONTRIBUTE IT BACK"},{"content":"Browse real Codename One applications, UI kits, and sample projects.\n","permalink":"https://www.codenameone.com/demos/","summary":"\u003cp\u003eBrowse real Codename One applications, UI kits, and sample projects.\u003c/p\u003e","title":"Demos"},{"content":"","permalink":"https://www.codenameone.com/developer-guide/","summary":"Codename One developer guide","title":"Developer Guide"},{"content":"A virtual therapist that uses bubble chat conversation and text to speech\nScreenshots DR. SBAITSO A virtual therapist that uses bubble chat conversation and text to speech\nHome DR. SBAITSO Dr. Sbaitso is based on a classic SoundBlaster demo, the virtual therapist holds a conversation with you offering help. In this case it uses an iChat like bubble chat UI with picture previews of the participant (from the camera). Chat history can be searched and on iOS and Android Text To Speech is used thru native interfaces.\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\nBlog Post: link\nTutorial: link\nSource: link\nJS Port: link\nWindows Desktop: link\nMac App: link\nAndroid App: link\nios: link\n","permalink":"https://www.codenameone.com/dr-sbaitso/","summary":"\u003cp\u003eA virtual therapist that uses bubble chat conversation and text to speech\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"DR. SBAITSO\" loading=\"lazy\" src=\"/demos/dr-sbaitso-slide-2-2-1.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"dr-sbaitso\"\u003eDR. SBAITSO\u003c/h2\u003e\n\u003cp\u003eA virtual therapist that uses bubble chat conversation and text to speech\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eDR. SBAITSO\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/dr-sbaitso-slide-2-2-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eDr. Sbaitso is based on a classic SoundBlaster demo, the virtual therapist holds a conversation with you offering help. In this case it uses an iChat like bubble chat UI with picture previews of the participant (from the camera). Chat history can be searched and on iOS and Android Text To Speech is used thru native interfaces.\u003c/p\u003e","title":"DR. SBAITSO"},{"content":" When a Codename One application feels wrong, the first job is to identify what kind of problem you actually have. Is the UI frozen? Is the event dispatch thread blocked? Is a network request slow? Is a component repainting too often? Is memory pressure coming from images? Codename One gives you tools for each of those questions, but they work best when you use them alongside the normal debugger in your IDE.\nThe standard Java debugger is still the first tool to reach for. If the simulator is stuck, pause the process and inspect the stack. If a specific interaction misbehaves, put a breakpoint on the action path that matters. Many bugs are still just ordinary logic bugs, and the debugger remains the fastest way to see what the code is actually doing.\nCodename One adds another layer of diagnostics inside the simulator. The EDT tools are especially important because so much UI behavior depends on the event dispatch thread. If you do heavy work on the EDT, the app becomes slow or unresponsive. If you touch UI state from the wrong thread, the behavior becomes unpredictable. The EDT diagnostics can help expose both kinds of mistakes, even though they are not perfect and can occasionally produce noisy warnings.\nThe network monitor is the next high-value tool. If your app talks to a server, inspect the requests and responses directly instead of guessing. Look at URLs, headers, payload sizes, response bodies, and timing. That is often enough to separate a client-side bug from a server-side bug or a simple latency problem.\nThe performance monitor becomes useful once the issue is more visual than logical. It helps show which components render frequently and which ones are expensive. That is a much better starting point than trying to optimize random code paths. If one screen feels slow, find the component or rendering pattern that is consuming the time before you start rewriting UI code.\nMemory problems also become much easier once you inspect images explicitly. In Codename One, images are often the first place to investigate when memory usage grows unexpectedly. The tooling can help show which images are being created and how large they are in memory. That matters because the runtime memory cost of an image is often very different from the compressed file size you started with.\nThe practical lesson is to debug with evidence. Use the debugger for logic, the EDT tools for threading mistakes, the network monitor for IO, the performance monitor for rendering cost, and the logging APIs for information that needs to survive beyond the simulator.\nFurther Reading Developer Guide Performance Network Monitors How Do I Improve Application Performance Or Track Down Performance Issues How Do I Use Crash Protection? Get Device Logs? Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-find-problems-in-my-application-using-the-codename-one-tools-and-the-standard-ide-tools/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/1wHGnmO-vtE?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eWhen a Codename One application feels wrong, the first job is to identify what kind of problem you actually have. Is the UI frozen? Is the event dispatch thread blocked? Is a network request slow? Is a component repainting too often? Is memory pressure coming from images? Codename One gives you tools for each of those questions, but they work best when you use them alongside the normal debugger in your IDE.\u003c/p\u003e","title":"FIND PROBLEMS IN MY APPLICATION, USING THE CODENAME ONE TOOLS AND THE STANDARD IDE TOOLS"},{"content":"Demonstrate geographic visualization of census data\nScreenshots GEOVIZ DEMO Demonstrate geographic visualization of census data\nHome GEOVIZ DEMO Demonstrates analysis of US census data thru charts for mapping and a line chart.\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\nBlog Post: link\nSource: link\nJS Port: link\nWindows Desktop: link\nMac App: link\nAndroid App: link\nios: link\n","permalink":"https://www.codenameone.com/geoviz-demo/","summary":"\u003cp\u003eDemonstrate geographic visualization of census data\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"GEOVIZ DEMO\" loading=\"lazy\" src=\"/demos/geoviz-demo-slide-1-5-1.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"geoviz-demo\"\u003eGEOVIZ DEMO\u003c/h2\u003e\n\u003cp\u003eDemonstrate geographic visualization of census data\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eGEOVIZ DEMO\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/geoviz-demo-slide-1-5-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eDemonstrates analysis of US census data thru charts for mapping and a line chart.\u003c/p\u003e\n\u003cp\u003eNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\u003cbr\u003e\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\u003c/p\u003e","title":"GEOVIZ DEMO"},{"content":" Repeatable builds matter when you are trying to stabilize a release, investigate a regression, or keep a production app on a known-good Codename One version instead of automatically moving with the latest server-side changes. Versioned builds are the feature designed for that job.\nThe core idea is simple. Instead of always building against the current Codename One server release, you tell the build system to target a specific Codename One version. That means the native build is performed against the exact server logic and framework state associated with that release. If your application built and ran correctly against that version before, you now have a way to stay there while you validate later updates on your own schedule.\nThis is especially useful when a build suddenly starts failing or when behavior changes unexpectedly after a platform update. If you can rebuild against an older known-good Codename One version and the problem disappears, you have learned something important: the regression is probably tied to the framework or build-server changes rather than to a recent change in your own app. That turns versioned builds into both a stability feature and a debugging tool.\nThe original video frames this as a Pro feature with longer retention in the Enterprise tier, and that is still the right way to think about availability. The exact retention window depends on the subscription tier, but the practical lesson is the same: if stable historical build targets matter to your team, versioned builds should be part of your release strategy.\nWhen you use a versioned build, it is usually a good idea to keep your local simulator environment aligned with that same framework version as well. Otherwise you can end up testing one version locally and shipping another remotely. The older settings UI exposed this through the version selection and client library update flow. In current Maven-based projects, the broader goal is still consistency: keep the project, simulator, and native build path aligned so that local testing reflects what the build server is actually producing.\nThis is not something you need for every build during active day-to-day development. It becomes valuable when predictability matters more than immediately consuming the latest changes. Teams that ship production apps, support older releases, or operate in tightly controlled release windows tend to benefit the most from this feature.\nIn practice, the healthiest workflow is to use the current Codename One version during normal development, then pin to a specific version when you need a reproducible release train or when you are isolating a regression. Once the newer version is validated, you can move forward deliberately instead of being surprised by it in the middle of a release.\nFurther Reading Build Server Moving To Maven Developer Guide How Do I Use Offline Build Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-get-repeatable-builds-build-against-a-consistent-version-of-codename-one-use-the-versioning-feature/","summary":"\u003cp\u003e\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/w7xvlw3rI6Y?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\nRepeatable builds matter when you are trying to stabilize a release, investigate a regression, or keep a production app on a known-good Codename One version instead of automatically moving with the latest server-side changes. Versioned builds are the feature designed for that job.\u003c/p\u003e\n\u003cp\u003eThe core idea is simple. Instead of always building against the current Codename One server release, you tell the build system to target a specific Codename One version. That means the native build is performed against the exact server logic and framework state associated with that release. If your application built and ran correctly against that version before, you now have a way to stay there while you validate later updates on your own schedule.\u003c/p\u003e","title":"GET REPEATABLE BUILDS? BUILD AGAINST A CONSISTENT VERSION OF CODENAME ONE? USE THE VERSIONING FEATURE?"},{"content":"A Basic Demonstration Using the Google Maps Library\nScreenshots GOOGLE MAPS DEMO A Basic Demonstration Using the Google Maps Library\nHome GOOGLE MAPS DEMO This app demonstrates the use of The Google Maps library to embed a native map into a Codename One app. The app itself is basic. It contains buttons to add markers and paths to the map, as well as reposition the camera. One subtle feature that this app demonstrates, is the ability to render Codename One UI components over top of a native component.\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\nBlog Post: link\nSource: link\nJS Port: link\nAndroid App: link\nios: link\n","permalink":"https://www.codenameone.com/google-maps-demo/","summary":"\u003cp\u003eA Basic Demonstration Using the Google Maps Library\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"GOOGLE MAPS DEMO\" loading=\"lazy\" src=\"/demos/google-maps-demo-slide-1-2-1.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"google-maps-demo\"\u003eGOOGLE MAPS DEMO\u003c/h2\u003e\n\u003cp\u003eA Basic Demonstration Using the Google Maps Library\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eGOOGLE MAPS DEMO\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/google-maps-demo-slide-1-2-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThis app demonstrates the use of The Google Maps library to embed a native map into a Codename One app. The app itself is basic. It contains buttons to add markers and paths to the map, as well as reposition the camera. One subtle feature that this app demonstrates, is the ability to render Codename One UI components over top of a native component.\u003c/p\u003e","title":"GOOGLE MAPS DEMO"},{"content":" The GUI builder workflow in Codename One is based on generated forms and generated state-machine code, which means events and screen population work a little differently from the desktop UI builders many Java developers are used to. The old video focuses on that generated workflow directly, and that is still the right mental model if you are maintaining a GUI-builder based project.\nNavigation is easiest when you use the builder’s command and form-linking features instead of trying to wire everything manually. If a button simply needs to open another form, the generated navigation model is often the cleanest route because it keeps the relationship visible in the builder and preserves the expected back-navigation behavior automatically.\nEvent handling becomes more interesting when a component needs custom logic. In the builder-driven approach, you attach the event in the UI resource and then implement the generated handler in code. That part is easy to trip over if you forget that the generated base classes are updated when the resource file is saved. The video calls this out indirectly through the save cycle, and it is still one of the main stumbling points when working in this style.\nPopulating a form from code is really about timing. A generated form is not a permanently alive singleton sitting in memory waiting for you to reach into it. It is created when needed and discarded when it is no longer active. That is why screen-specific initialization belongs in the lifecycle hooks that run just before the form is shown, not in some random place that assumes the components already exist.\nThis is the part of the video that still matters most conceptually. If you want to change a label, fill a field, or update a screen-specific component, you do it at the point where that form is being prepared to appear. That way the components actually exist and the change is applied to the live form instance rather than to a screen that has already been discarded.\nThe modern caveat is that new Codename One projects are usually less GUI-builder centric than the old workflow assumes. Many teams now prefer code-based UI plus CSS for styling. But if you are working in the builder, the generated-form lifecycle is still the rule you need to understand: navigation is configured declaratively where possible, event handlers live in the generated override points, and screen population happens at form-show time.\nFurther Reading Developer Guide Layout Basics How Do I Create A Gorgeous Sidemenu How Do I Create A List Of Items Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-handle-eventsnavigation-in-the-gui-builder-populate-the-form-from-code/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/3IC2qZ3wUO4?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe GUI builder workflow in Codename One is based on generated forms and generated state-machine code, which means events and screen population work a little differently from the desktop UI builders many Java developers are used to. The old video focuses on that generated workflow directly, and that is still the right mental model if you are maintaining a GUI-builder based project.\u003c/p\u003e","title":"HANDLE EVENTS/NAVIGATION IN THE GUI BUILDER \u0026 POPULATE THE FORM FROM CODE"},{"content":" Performance work gets easier once you stop thinking in terms of vague slowness and start looking for specific expensive patterns. In Codename One, the same categories of mistakes show up repeatedly: too much work on the EDT, heavy list renderers, unnecessary image churn, overly dynamic text measurement, and drawing strategies that look harmless in code but cost a lot at runtime.\nLists are one of the first places to inspect. If you are using a list model, avoid changing it one item at a time when what you really mean is \u0026ldquo;replace a lot of data\u0026rdquo;. Repeated add/remove events trigger repeated notification and repaint work. If you need to make a large change, replacing the model or batching the change is usually much cheaper than firing a long stream of individual updates.\nCustom list models and renderers need even more discipline. Methods such as getItemAt() must be fast. They should not block on network access or heavy computation. If a list depends on remote data, return quickly and update later when the data arrives. The same principle applies to renderers: do not construct a fresh component tree every time the renderer is asked for output. Reuse renderer components and update their state. Creating components repeatedly inside the renderer is one of the easiest ways to destroy scrolling performance.\nText measurement is another hidden cost. Automatic line breaking and repeated calls that depend on string width can be expensive, especially when they happen frequently during rendering. If a screen is performance-sensitive, prefer simpler label usage and avoid forcing the UI to re-measure large amounts of text over and over when a more stable layout would do.\nImages deserve just as much attention. A few sensible image draws are often cheaper than a huge number of tiny draw operations. That is one reason very small tiled images, overly fragmented borders, and repeated low-level drawing primitives can become surprisingly expensive. The old note about gradients is also still worth keeping: decorative gradients are a surprisingly common source of avoidable cost, and in many cases a simple image or cleaner styling choice is the better tradeoff.\nImage scaling is another common trap. If you call scaling methods casually, you may be creating larger in-memory images than you realize. The source asset might be small on disk, but the scaled runtime image can cost a lot more RAM. That means scaling should be deliberate, cached where appropriate, and revisited if memory pressure starts to climb.\nThe right workflow is to measure first, then optimize. Use the performance tools, identify the component or pattern that is actually expensive, and fix that specific thing. Do not rewrite major pieces of a screen just because it feels slow. In Codename One, a small renderer mistake or image decision can dominate the cost of an otherwise reasonable UI.\nFurther Reading Performance Network Monitors Developer Guide How Do I Find Problems In My Application, Using The Codename One Tools And The Standard IDE Tools In A Pinch Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-improve-application-performance-or-track-down-performance-issues/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/set12jVQl_A?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003ePerformance work gets easier once you stop thinking in terms of vague slowness and start looking for specific expensive patterns. In Codename One, the same categories of mistakes show up repeatedly: too much work on the EDT, heavy list renderers, unnecessary image churn, overly dynamic text measurement, and drawing strategies that look harmless in code but cost a lot at runtime.\u003c/p\u003e","title":"IMPROVE APPLICATION PERFORMANCE OR TRACK DOWN PERFORMANCE ISSUES"},{"content":"","permalink":"https://www.codenameone.com/initializr/","summary":"","title":"Initializr"},{"content":"Codename One’s first demo, a mesh of supported features to highlight capabilities.\nKITCHEN SINK Codename One’s first demo, a mesh of supported features to highlight capabilities.\nHome KITCHEN SINK The Kitchen Sink demo is the first Codename One demo ever made. It recently went thru a complete rewrite to modernize it and improve it’s UX/UI and functionality.\nThe demo displays icons/cards with various categories to show off various features of Codename One such as layouts, theming, animations/effects etc. Notice that the demo adapts itself to the form factor and acts differently when running on a Tablet than it would on a phone.\nSource: link\nJS Port: link\niOS iTunes: link\nUniversal Windows (UWP): link\nGoogle Play link\nWindows Desktop: link\nMac App: link\n","permalink":"https://www.codenameone.com/kitchen-sink/","summary":"\u003cp\u003eCodename One’s first demo, a mesh of supported features to highlight capabilities.\u003c/p\u003e\n\u003ch2 id=\"kitchen-sink\"\u003eKITCHEN SINK\u003c/h2\u003e\n\u003cp\u003eCodename One’s first demo, a mesh of supported features to highlight capabilities.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eKITCHEN SINK\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe Kitchen Sink demo is the first Codename One demo ever made. It recently went thru a complete rewrite to modernize it and improve it’s UX/UI and functionality.\u003cbr\u003e\nThe demo displays icons/cards with various categories to show off various features of Codename One such as layouts, theming, animations/effects etc. Notice that the demo adapts itself to the form factor and acts differently when running on a Tablet than it would on a phone.\u003c/p\u003e","title":"KITCHEN SINK"},{"content":" Layouts are the reason a Codename One UI can survive different screen sizes, orientations, pixel densities, and languages. Components do not live at fixed coordinates. They live inside Container objects, and those containers use layout managers to decide how much space each child gets and where it should appear.\nThe core problem layouts solve is portability. A button position that looks fine on one phone may be wrong on another. A label that fits in English may overflow in German. A design that works in portrait may fall apart in landscape. Absolute positioning looks tempting when a screen is simple, but it stops being practical as soon as the UI has to adapt. Layout managers let you describe intent instead of hard-coding coordinates: this component should stay on the left, this field should take the remaining width, this section should stack vertically, these buttons should all be the same size.\nThat is why the classic “label on the left, field on the right” example is still such a useful starting point. In Codename One you usually express that with a BorderLayout, putting the label in BorderLayout.WEST and the field in BorderLayout.CENTER. The layout then handles the resizing rules for you. The label keeps the width it needs, while the center component expands into the remaining space. Once that pattern clicks, you can start seeing a screen as a composition of small layout problems instead of one big manual positioning job.\nThe standard layouts each have a natural role. FlowLayout is still the simplest layout and is fine for small inline groups of components, but it is easy to outgrow. BorderLayout is one of the most useful outer layouts because it gives you strong structure: top, bottom, left, right, and a center area that consumes the remaining space. BoxLayout.y() is a great default for stacked content because it reads like the screen itself. BoxLayout.x() is good for small horizontal rows. GridLayout is useful when you genuinely want equal-sized components, such as button bars or icon grids. TableLayout is especially helpful for forms and data entry because it gives you more control over rows, columns, and spanning. LayeredLayout is the one to reach for when components need to sit on top of each other, such as floating actions, overlays, or decorative layers.\nOne detail that matters early is constraints. Some layouts need them and some do not. BorderLayout depends on explicit positions such as CENTER and WEST, while BoxLayout generally does not need extra constraints at all. Understanding that difference helps make the APIs feel much less arbitrary. A layout manager is not just “where children go”; it also defines what information you need to provide when you add those children.\nThe most effective way to build a real screen is usually to nest a few simple containers rather than hunting for one magical layout that does everything. A form might use BorderLayout at the top level, a BoxLayout.y() in the content area, and then small BorderLayout or GridLayout sections inside it. That is normal. Good layout code tends to mirror the visual structure of the screen. If a screen has a header, a scrolling body, and a floating action button, the container hierarchy should make that obvious.\nInspecting a real screen is often more useful than memorizing layout APIs in the abstract. If you open a working UI in the component inspector and look at the nesting, you quickly see why a LayeredLayout was used at the root, why a BoxLayout.y() holds a scrolling list, or why a GridLayout makes the swipe actions line up evenly. That is how layouts become intuitive.\nThe modern adjustment is not in the layout system itself so much as in how you split responsibilities. Layout code should mostly define structure and resizing behavior. CSS should do much more of the styling work: spacing, fonts, colors, borders, and visual states. If you find yourself using extra containers only to fake visual styling, that is often a sign that the visual concern belongs in CSS instead.\nFurther Reading Layout Basics Developer Guide Themeing Getting Started Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-positioning-components-using-layout-managers/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/4D_KUa2qv2o?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eLayouts are the reason a Codename One UI can survive different screen sizes, orientations, pixel densities, and languages. Components do not live at fixed coordinates. They live inside \u003ccode\u003eContainer\u003c/code\u003e objects, and those containers use layout managers to decide how much space each child gets and where it should appear.\u003c/p\u003e","title":"LAYOUT BASICS"},{"content":" Internationalization and localization are broader than translation. Internationalization means structuring the app so it can adapt to different locales. Localization is the work of adapting the app to a specific locale. Language is part of that, but so are dates, numbers, currency, right-to-left behavior, phrasing, and the cultural meaning of visual choices.\nThe first practical rule is to stop hard-coding user-facing text directly into the UI wherever possible. Codename One is designed to work with key/value bundles so that the text shown to the user can change with the current locale. The older video demonstrates this through the resource editor. For new projects, the better default is l10n property bundles, but the core idea remains the same: components should reference localizable keys, not baked-in strings that force you to revisit the code for every translation.\nThis matters because translation is only the first layer. Locale-specific behavior also affects the way you display dates, numbers, and currency. If you use locale-aware formatting utilities, the app can present those values in a way that feels natural to the user instead of forcing one fixed representation on every market. In Codename One, L10NManager and the framework\u0026rsquo;s localization utilities are the right place to start for this kind of formatting.\nTesting localization also needs to be part of the normal development loop. It is much easier to catch problems early if you force the simulator into a different language and inspect the UI there. A localized build should not only show translated strings. It should still fit properly, align correctly, and feel intentional when labels grow longer or date and number formatting changes.\nRight-to-left support is one of the most important areas to get right. Languages such as Hebrew and Arabic do not just translate the text. They change the expected flow of the interface. Text aligns differently, component order often reverses, and icons or directional affordances may need to be mirrored. Codename One helps a lot here because layouts react to RTL mode by flipping positions and alignment where appropriate. A BorderLayout.EAST relationship, for example, is interpreted relative to the active writing direction.\nThat said, RTL is not automatic magic. Mixed-direction content still needs attention. Numbers are still read left-to-right even inside right-to-left languages, so bidirectional text can produce cursor movement and layout behavior that surprises developers who only test in English. Icons such as play arrows, chevrons, and back buttons also need review because a mirrored UI with unmirrored directional icons still feels wrong.\nThe video uses the older designer workflow to define bundles and RTL markers. That part is outdated for new projects, but the localization concepts themselves are still the right ones to learn. In current Codename One development, the better default is property-bundle based localization plus locale-aware formatting in code, with the layout system doing most of the heavy lifting for RTL-aware component ordering.\nThe practical goal is not just \u0026ldquo;translated text\u0026rdquo;. It is an application that feels like it belongs in the user\u0026rsquo;s locale. That means translated labels, correctly formatted values, sensible spacing for longer phrases, mirrored layout where appropriate, and deliberate review of the edge cases that do not flip automatically.\nFurther Reading Developer Guide Themeing Layout Basics Hello World Properties Are Amazing Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-localizetranslate-my-application-apply-i18nl10n-internationalizationlocalization-to-my-app/","summary":"\u003cp\u003e\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/32mkZymqa6E?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\nInternationalization and localization are broader than translation. Internationalization means structuring the app so it can adapt to different locales. Localization is the work of adapting the app to a specific locale. Language is part of that, but so are dates, numbers, currency, right-to-left behavior, phrasing, and the cultural meaning of visual choices.\u003c/p\u003e","title":"LOCALIZE/TRANSLATE MY APPLICATION? APPLY I18N/L10N (INTERNATIONALIZATION/LOCALIZATION) TO MY APP?"},{"content":"Gorgeous design as the designer intended\nScreenshots MSUIKIT – PSD TEMPLATE PORT TO CROSS PLATFORM PIXEL PERFECT CODENAME ONE APP FOR ANDROID, IPHONE (IOS) ETC. Gorgeous design as the designer intended\nHome MSUIKIT – PSD TEMPLATE PORT TO CROSS PLATFORM PIXEL PERFECT CODENAME ONE APP FOR ANDROID, IPHONE (IOS) ETC. This demo ports a set of PSD designs to a fully functional cross platform Codename One app, it also takes those designs for a high resolution Android device and makes them useable in any resolution device.\nSince this isn’t a \u0026ldquo;real application\u0026rdquo; with functionality it can’t be distributed thru the stores so we can’t provide an iOS version or even upload it to Google Play. We provide the ability to download the APK for Android and full source code. Notice that the images are all actual device screenshots from an Android One Plus One device.\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nBlog Post: link\nSource: link\nJS Port: link\nAndroid App: link\n","permalink":"https://www.codenameone.com/msuikit-psd-template-port-to-cross-platform-pixel-perfect-codename-one-app-for-android-iphone-ios-etc/","summary":"\u003cp\u003eGorgeous design as the designer intended\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"MSUIKIT – PSD TEMPLATE PORT TO CROSS PLATFORM PIXEL PERFECT CODENAME ONE APP FOR ANDROID, IPHONE (IOS) ETC.\" loading=\"lazy\" src=\"/demos/msuikit-psd-template-port-to-cross-platform-pixel-perfect-codename-one-app-for-android-iphone-ios-etc-slide-2-3.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"MSUIKIT – PSD TEMPLATE PORT TO CROSS PLATFORM PIXEL PERFECT CODENAME ONE APP FOR ANDROID, IPHONE (IOS) ETC.\" loading=\"lazy\" src=\"/demos/msuikit-psd-template-port-to-cross-platform-pixel-perfect-codename-one-app-for-android-iphone-ios-etc-slide-3-3.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"MSUIKIT – PSD TEMPLATE PORT TO CROSS PLATFORM PIXEL PERFECT CODENAME ONE APP FOR ANDROID, IPHONE (IOS) ETC.\" loading=\"lazy\" src=\"/demos/msuikit-psd-template-port-to-cross-platform-pixel-perfect-codename-one-app-for-android-iphone-ios-etc-slide-4-3.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"MSUIKIT – PSD TEMPLATE PORT TO CROSS PLATFORM PIXEL PERFECT CODENAME ONE APP FOR ANDROID, IPHONE (IOS) ETC.\" loading=\"lazy\" src=\"/demos/msuikit-psd-template-port-to-cross-platform-pixel-perfect-codename-one-app-for-android-iphone-ios-etc-slide-5-2.png\"\u003e\u003c/p\u003e","title":"MSUIKIT – PSD TEMPLATE PORT TO CROSS PLATFORM PIXEL PERFECT CODENAME ONE APP FOR ANDROID, IPHONE (IOS) ETC."},{"content":"Gorgeous design as the designer intended\nScreenshots PHEONIX UI – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP Gorgeous design as the designer intended\nHome PHEONIX UI – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP This demo ports a set of PSD designs to a fully functional cross platform Codename One app, it also takes those designs for a high resolution Android device and makes them useable in any resolution device.\nSince this isn’t a \u0026ldquo;real application\u0026rdquo; with functionality it can’t be distributed thru the stores so we can’t provide an iOS version or even upload it to Google Play. We provide the ability to download the APK for Android and full source code. Notice that the images are all actual device screenshots from an Android One Plus One device.\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nBlog Post: link\nSource: link\nJS Port: link\nAndroid App: link\n","permalink":"https://www.codenameone.com/pheonix-ui-port-of-psd-design-to-cross-platform-native-mobile-app/","summary":"\u003cp\u003eGorgeous design as the designer intended\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"PHEONIX UI – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP\" loading=\"lazy\" src=\"/demos/pheonix-ui-port-of-psd-design-to-cross-platform-native-mobile-app-slide-5-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"PHEONIX UI – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP\" loading=\"lazy\" src=\"/demos/pheonix-ui-port-of-psd-design-to-cross-platform-native-mobile-app-slide-6.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"PHEONIX UI – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP\" loading=\"lazy\" src=\"/demos/pheonix-ui-port-of-psd-design-to-cross-platform-native-mobile-app-slide-8.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"PHEONIX UI – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP\" loading=\"lazy\" src=\"/demos/pheonix-ui-port-of-psd-design-to-cross-platform-native-mobile-app-slide-9.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"pheonix-ui--port-of-psd-design-to-cross-platform-native-mobile-app\"\u003ePHEONIX UI – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP\u003c/h2\u003e\n\u003cp\u003eGorgeous design as the designer intended\u003c/p\u003e","title":"PHEONIX UI – PORT OF PSD DESIGN TO CROSS PLATFORM NATIVE MOBILE APP"},{"content":"","permalink":"https://www.codenameone.com/playground/","summary":"","title":"Playground"},{"content":"A simple Poker mockup showing off complex animations/layouts with cards\nScreenshots POKER DEMO A simple Poker mockup showing off complex animations/layouts with cards\nHome POKER DEMO The Poker demo was written as part of an article covering game development with Codename One, it shows how even elaborate game like animations/layouts can be achieved using the Codename One layout animations.\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\nSource: link\nJS Port: link\nWindows Desktop: link\nMac App: link\nAndroid App: link\nios: link\n","permalink":"https://www.codenameone.com/poker-demo/","summary":"\u003cp\u003eA simple Poker mockup showing off complex animations/layouts with cards\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"POKER DEMO\" loading=\"lazy\" src=\"/demos/poker-demo-slide-3-1.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"poker-demo\"\u003ePOKER DEMO\u003c/h2\u003e\n\u003cp\u003eA simple Poker mockup showing off complex animations/layouts with cards\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003ePOKER DEMO\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/poker-demo-slide-3-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe Poker demo was written as part of an article covering game development with Codename One, it shows how even elaborate game like animations/layouts can be achieved using the Codename One layout animations.\u003c/p\u003e\n\u003cp\u003eNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\u003cbr\u003e\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\u003c/p\u003e","title":"POKER DEMO"},{"content":"Browse houses for sale in the UK using a JSON webservice\nScreenshots PROPERTYCROSS DEMO Browse houses for sale in the UK using a JSON webservice\nHome PROPERTYCROSS DEMO PropertyCross demonstrates a simple handcoded UI that connects to a JSON webservice. It shows local caching of images using URLImage and general caching of network operations. It allows you to browse thru content with infinite scrolling containers and mark favorites.\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\nBlog Post: link\nTutorial: link\nSource: link\nJS Port: link\nWindows Desktop: link\nMac App: link\nAndroid App: link\nios: link\n","permalink":"https://www.codenameone.com/propertycross-demo/","summary":"\u003cp\u003eBrowse houses for sale in the UK using a JSON webservice\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"PROPERTYCROSS DEMO\" loading=\"lazy\" src=\"/demos/propertycross-demo-slide-3-5.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"PROPERTYCROSS DEMO\" loading=\"lazy\" src=\"/demos/propertycross-demo-slide-1-5.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"PROPERTYCROSS DEMO\" loading=\"lazy\" src=\"/demos/propertycross-demo-slide-2-5.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"propertycross-demo\"\u003ePROPERTYCROSS DEMO\u003c/h2\u003e\n\u003cp\u003eBrowse houses for sale in the UK using a JSON webservice\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003ePROPERTYCROSS DEMO\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/propertycross-demo-slide-3-5.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/propertycross-demo-slide-1-5.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/propertycross-demo-slide-2-5.png\"\u003e\u003c/p\u003e\n\u003cp\u003ePropertyCross demonstrates a simple handcoded UI that connects to a JSON webservice. It shows local caching of images using URLImage and general caching of network operations. It allows you to browse thru content with infinite scrolling containers and mark favorites.\u003c/p\u003e","title":"PROPERTYCROSS DEMO"},{"content":"Demo showing off a restaurant with map, navigation and a menu\nScreenshots RATATOUILLE’S RESTAURANT Demo showing off a restaurant with map, navigation and a menu\nHome RATATOUILLE’S RESTAURANT This is a quick and dirty demo showing how to create a clean and simple UI using some well placed images and animations.\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\nBlog Post: link\nSource: link\nJS Port: link\nAndroid App: link\nios: link\n","permalink":"https://www.codenameone.com/ratatouilles-restaurant/","summary":"\u003cp\u003eDemo showing off a restaurant with map, navigation and a menu\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"RATATOUILLE’S RESTAURANT\" loading=\"lazy\" src=\"/demos/ratatouilles-restaurant-slide-3-6.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"RATATOUILLE’S RESTAURANT\" loading=\"lazy\" src=\"/demos/ratatouilles-restaurant-slide-1-6.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"RATATOUILLE’S RESTAURANT\" loading=\"lazy\" src=\"/demos/ratatouilles-restaurant-slide-2-1-1.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"ratatouilles-restaurant\"\u003eRATATOUILLE’S RESTAURANT\u003c/h2\u003e\n\u003cp\u003eDemo showing off a restaurant with map, navigation and a menu\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eRATATOUILLE’S RESTAURANT\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/ratatouilles-restaurant-slide-3-6.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/ratatouilles-restaurant-slide-1-6.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/ratatouilles-restaurant-slide-2-1-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThis is a quick and dirty demo showing how to create a clean and simple UI using some well placed images and animations.\u003c/p\u003e\n\u003cp\u003eNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\u003cbr\u003e\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\u003c/p\u003e","title":"RATATOUILLE’S RESTAURANT"},{"content":"A fully featured Solitaire Klondike game with multiple levels of undo\nScreenshots SOLITAIRE KLONDIKE A fully featured Solitaire Klondike game with multiple levels of undo\nHome SOLITAIRE KLONDIKE The Solitaire Klondike app was adapted from the old Poker demo resources so we will be able to submit the app to the stores and provide a fully installable demo that will more accurately represent the way things look when you build the native app.\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nSince Apple doesn’t allow demos on itunes and doesn’t allow installing apps without itunes we can’t distribute the native app demos, you would need to build from source with an itunes demo account.\nSource: link\nJS Port: link\nMac App: link\nAndroid App: link\nios: link\n","permalink":"https://www.codenameone.com/solitaire-klondike/","summary":"\u003cp\u003eA fully featured Solitaire Klondike game with multiple levels of undo\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"SOLITAIRE KLONDIKE\" loading=\"lazy\" src=\"/demos/solitaire-klondike-slide-1-3.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"SOLITAIRE KLONDIKE\" loading=\"lazy\" src=\"/demos/solitaire-klondike-slide-2-3-1.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"solitaire-klondike\"\u003eSOLITAIRE KLONDIKE\u003c/h2\u003e\n\u003cp\u003eA fully featured Solitaire Klondike game with multiple levels of undo\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eSOLITAIRE KLONDIKE\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/solitaire-klondike-slide-1-3.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/solitaire-klondike-slide-2-3-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003eThe Solitaire Klondike app was adapted from the old Poker demo resources so we will be able to submit the app to the stores and provide a fully installable demo that will more accurately represent the way things look when you build the native app.\u003c/p\u003e","title":"SOLITAIRE KLONDIKE"},{"content":"Full power of relational DB everywhere\nScreenshots SQL PLAYGROUND – SQL TUTORIAL IN THE BROWSER, IPHONE (IOS), ANDROID, WINDOWS… Full power of relational DB everywhere\nHome SQL PLAYGROUND – SQL TUTORIAL IN THE BROWSER, IPHONE (IOS), ANDROID, WINDOWS… The SQL Playground app shows off some of the SQL capabilities of Codename One and sqlite. It provides the ability to issue arbitrary SQL queries and view the results. It also provides a tutorial mode with some sample queries.\nImportant: JavaScript SQL support is problematic at best and thus this demo only works on Chrome and has some bugs even there… We are working on resolving the issues from our side but since there is apparently no W3C standard for SQL it’s unclear how we will support this moving forward…\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nBlog Post: link\nSource: link\nJS Port: link\nUniversal Windows (UWP): link\nGoogle Play link\nios: link\n","permalink":"https://www.codenameone.com/sql-playground-sql-tutorial-in-the-browser-iphone-ios-android-windows/","summary":"\u003cp\u003eFull power of relational DB everywhere\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"SQL PLAYGROUND – SQL TUTORIAL IN THE BROWSER, IPHONE (IOS), ANDROID, WINDOWS…\" loading=\"lazy\" src=\"/demos/sql-playground-sql-tutorial-in-the-browser-iphone-ios-android-windows-slide-4-6.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"SQL PLAYGROUND – SQL TUTORIAL IN THE BROWSER, IPHONE (IOS), ANDROID, WINDOWS…\" loading=\"lazy\" src=\"/demos/sql-playground-sql-tutorial-in-the-browser-iphone-ios-android-windows-picture-11.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"SQL PLAYGROUND – SQL TUTORIAL IN THE BROWSER, IPHONE (IOS), ANDROID, WINDOWS…\" loading=\"lazy\" src=\"/demos/sql-playground-sql-tutorial-in-the-browser-iphone-ios-android-windows-slide-3-8.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"SQL PLAYGROUND – SQL TUTORIAL IN THE BROWSER, IPHONE (IOS), ANDROID, WINDOWS…\" loading=\"lazy\" src=\"/demos/sql-playground-sql-tutorial-in-the-browser-iphone-ios-android-windows-slide-1-8.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"sql-playground--sql-tutorial-in-the-browser-iphone-ios-android-windows\"\u003eSQL PLAYGROUND – SQL TUTORIAL IN THE BROWSER, IPHONE (IOS), ANDROID, WINDOWS…\u003c/h2\u003e\n\u003cp\u003eFull power of relational DB everywhere\u003c/p\u003e","title":"SQL PLAYGROUND – SQL TUTORIAL IN THE BROWSER, IPHONE (IOS), ANDROID, WINDOWS…"},{"content":"Write once run anywhere with very little effort\nScreenshots SWIFTNOTES – PORT OF NATIVE ANDROID APP TO CODENAME ONE IPHONE (IOS), WINDOWS AND JAVASCRIPT TARGETS Write once run anywhere with very little effort\nHome SWIFTNOTES – PORT OF NATIVE ANDROID APP TO CODENAME ONE IPHONE (IOS), WINDOWS AND JAVASCRIPT TARGETS This demo is a part of a tutorial on converting Android native apps to Codename One apps thus allowing them to run on iOS, Windows \u0026amp; even the web.\nThe UI and UX of this demo is derived from the native Android app, we tried to keep it as close as reasonably possible to the original to avoid confusion. You can check out the original native Swiftnotes app here and its source code here. Our versions and sources are listed below.\nNotice that the JavaScript HTML5 demo is not what we have on the device where applications are translated to native code!\nSource: link\nJS Port: link\nUniversal Windows (UWP): link\nGoogle Play link\nios: link\n","permalink":"https://www.codenameone.com/swiftnotes-port-of-native-android-app-to-codename-one-iphone-ios-windows-and-javascript-targets/","summary":"\u003cp\u003eWrite once run anywhere with very little effort\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"SWIFTNOTES – PORT OF NATIVE ANDROID APP TO CODENAME ONE IPHONE (IOS), WINDOWS AND JAVASCRIPT TARGETS\" loading=\"lazy\" src=\"/demos/swiftnotes-port-of-native-android-app-to-codename-one-iphone-ios-windows-and-javascript-targets-slide-4-2.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"SWIFTNOTES – PORT OF NATIVE ANDROID APP TO CODENAME ONE IPHONE (IOS), WINDOWS AND JAVASCRIPT TARGETS\" loading=\"lazy\" src=\"/demos/swiftnotes-port-of-native-android-app-to-codename-one-iphone-ios-windows-and-javascript-targets-slide-1-2.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"SWIFTNOTES – PORT OF NATIVE ANDROID APP TO CODENAME ONE IPHONE (IOS), WINDOWS AND JAVASCRIPT TARGETS\" loading=\"lazy\" src=\"/demos/swiftnotes-port-of-native-android-app-to-codename-one-iphone-ios-windows-and-javascript-targets-slide-2-2.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"SWIFTNOTES – PORT OF NATIVE ANDROID APP TO CODENAME ONE IPHONE (IOS), WINDOWS AND JAVASCRIPT TARGETS\" loading=\"lazy\" src=\"/demos/swiftnotes-port-of-native-android-app-to-codename-one-iphone-ios-windows-and-javascript-targets-slide-3-2.png\"\u003e\u003c/p\u003e","title":"SWIFTNOTES – PORT OF NATIVE ANDROID APP TO CODENAME ONE IPHONE (IOS), WINDOWS AND JAVASCRIPT TARGETS"},{"content":" Taking a picture in Codename One is conceptually simple: ask the platform to capture an image, get back a file, load the image you actually want to display, and then update the UI. The details matter because camera images can be much larger than the UI really needs.\nThe Capture API supports several capture workflows, including direct image capture and variants that return later through a callback. The most practical lesson from the video is still the most important one: do not casually load the full original camera image if all you need is something that fits on screen. High-resolution camera output can consume a lot of memory, and many apps only need a resized version for preview or upload.\nThat is why scaling at capture time is often the right default. If the goal is to show a preview inside the app, scaling the image to something close to the display width is usually much safer than loading the raw camera file and hoping memory usage stays reasonable. The video demonstrates this with a width-based capture and aspect-ratio preservation, and that is still a sensible pattern.\nThe next practical detail is that the UI needs to react to the new image. If you replace the icon on a label or another display component, the form may need to revalidate or repaint so the layout can account for the new content. This is especially noticeable when the placeholder and the captured image have very different sizes.\nThe simulator behavior is also worth understanding. On the simulator, capture usually behaves more like a file chooser than a real camera. On a device, it invokes the actual camera flow. That means simulator testing is good for the code path, but device testing is still necessary for the real user experience, permissions, and camera integration behavior.\nThe modern advice here is mostly about restraint. Capture the image you need, not the largest image the device can produce. Resize early when appropriate, keep memory in mind, and treat image loading as a UI and performance concern, not just a feature checkbox.\nFurther Reading Developer Guide How Do I Improve Application Performance Or Track Down Performance Issues How Do I Use Storage, File System And SQL Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-take-a-picture-with-the-camera/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/nF4eqzVcsic?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eTaking a picture in Codename One is conceptually simple: ask the platform to capture an image, get back a file, load the image you actually want to display, and then update the UI. The details matter because camera images can be much larger than the UI really needs.\u003c/p\u003e","title":"TAKE A PICTURE WITH THE CAMERA"},{"content":"A clone of the native Uber Application\nScreenshots UberClone A clone of the native Uber Application\nHome UberClone Uber Clone The Uber Clone application is available as part of the online course Build Real World Full Stack Mobile Apps in Java. The course includes almost 5 hours of videos explaining the project and its architecture coupled with the full source code of the client and sever code.\nThe application makes use of Codename One’s builtin native maps and includes most of the big ticket items required for building a taxi hailing application.\nDue to the nature of the application we can’t redistribute it in precompiled demo form.\nBlog Post: link\n","permalink":"https://www.codenameone.com/uberclone/","summary":"\u003cp\u003eA clone of the native Uber Application\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"UberClone\" loading=\"lazy\" src=\"/demos/uberclone-1uc.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"UberClone\" loading=\"lazy\" src=\"/demos/uberclone-2uc.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"UberClone\" loading=\"lazy\" src=\"/demos/uberclone-3uc.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"UberClone\" loading=\"lazy\" src=\"/demos/uberclone-4uc.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"UberClone\" loading=\"lazy\" src=\"/demos/uberclone-5uc.jpg\"\u003e\u003c/p\u003e\n\u003ch2 id=\"uberclone\"\u003eUberClone\u003c/h2\u003e\n\u003cp\u003eA clone of the native Uber Application\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eUberClone\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/uberclone-1uc.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/uberclone-2uc.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/uberclone-3uc.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/uberclone-4uc.jpg\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/uberclone-5uc.jpg\"\u003e\u003c/p\u003e\n\u003ch4 id=\"uber-clone\"\u003eUber Clone\u003c/h4\u003e\n\u003cp\u003eThe Uber Clone application is available as part of the online course \u003ca href=\"https://codenameone.teachable.com/p/build-real-world-full-stack-mobile-apps-in-java\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eBuild Real World Full Stack Mobile Apps in Java\u003c/a\u003e. The course includes almost 5 hours of videos explaining the project and its architecture coupled with the full source code of the client and sever code.\u003c/p\u003e","title":"UberClone"},{"content":"A full-featured UberEats clone app template for Codename One.\nScreenshots UberEats Clone A full-featured UberEats clone app template for Codename One.\nHome UberEats Clone UberEats UI Clone Grub is a full-featured food delivery app UI template. It helps to build an elaborate cross-platform food delivery app such as UberEats, Foodpanda, GrubHub etc.\nThis app is designed as a proof of concept for the CodeRAD library, which facilitates the development of rich, reusable UI components for Codename One. It contains everything you should need to build a rich and reusable app with the Rapid application development principles.\nFeatures – Light/Dark mode – Onboarding screens – Register \u0026amp; Sign In – Location – Search – Filters – Restaurant Categories – Cart – Add to Cart – Promo Code – Payments – Credit Cards Management – Favourites – Order Tracking – Profile – Optimized for both iOS and Android – Fully customizable codebase – Highly-modularized code Tutorial: link\nSource: link\nAndroid App: link\n","permalink":"https://www.codenameone.com/ubereats-clone/","summary":"\u003cp\u003eA full-featured UberEats clone app template for Codename One.\u003c/p\u003e\n\u003ch2 id=\"screenshots\"\u003eScreenshots\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"UberEats Clone\" loading=\"lazy\" src=\"/demos/ubereats-clone-1-Sign-Up.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"UberEats Clone\" loading=\"lazy\" src=\"/demos/ubereats-clone-3-Onboard-2.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"UberEats Clone\" loading=\"lazy\" src=\"/demos/ubereats-clone-5-Home.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"UberEats Clone\" loading=\"lazy\" src=\"/demos/ubereats-clone-4-Location.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"UberEats Clone\" loading=\"lazy\" src=\"/demos/ubereats-clone-5-Add-Card.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"ubereats-clone\"\u003eUberEats Clone\u003c/h2\u003e\n\u003cp\u003eA full-featured UberEats clone app template for Codename One.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.codenameone.com\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eHome\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eUberEats Clone\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/ubereats-clone-1-Sign-Up.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/ubereats-clone-3-Onboard-2.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/ubereats-clone-5-Home.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/ubereats-clone-4-Location.png\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/demos/ubereats-clone-5-Add-Card.png\"\u003e\u003c/p\u003e\n\u003ch4 id=\"ubereats-ui-clone\"\u003eUberEats UI Clone\u003c/h4\u003e\n\u003cp\u003eGrub is a full-featured food delivery app UI template. It helps to build an elaborate cross-platform food delivery app such as UberEats, Foodpanda, GrubHub etc.\u003c/p\u003e\n\u003cp\u003eThis app is designed as a proof of concept for the \u003ca href=\"https://github.com/shannah/CodeRAD\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eCodeRAD library\u003c/a\u003e, which facilitates the development of rich, reusable UI components for Codename One. It contains everything you should need to build a rich and reusable app with the Rapid application development principles.\u003c/p\u003e","title":"UberEats Clone"},{"content":" Cloud Connect was designed to solve a very specific problem: seeing UI changes on real devices immediately while working in the GUI builder. It synchronized the builder\u0026rsquo;s saved UI state to connected devices so that you could feel the screen on hardware instead of relying only on the desktop preview.\nThat idea still makes sense as a workflow lesson even though the exact builder-centered flow is much less central to modern Codename One development. The value is in shortening the feedback loop between design changes and device reality. The more quickly you can see spacing, text length, transparency, and interaction feel on real hardware, the better your UI decisions tend to be.\nThe old feature accomplished that by pushing builder XML and resources through the cloud to a preview app on device. The practical takeaway today is broader: fast on-device iteration is valuable, but the current direction of most projects is much less GUI-builder centric than the video assumes. In a modern CSS-and-code workflow, the exact tools may differ, but the goal is the same: do not trust only the desktop preview for visual decisions that need to survive on real devices.\nSo while the original Cloud Connect workflow is mostly historical now, the reason it existed is still worth remembering. A UI that looks fine in a builder or simulator can feel very different in the hand. Real device preview is where touch target size, keyboard overlap, spacing, and overall feel become obvious.\nFurther Reading Developer Guide Themeing Hello World Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-use-cloud-connect/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/NVPIXnkoxv0?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eCloud Connect was designed to solve a very specific problem: seeing UI changes on real devices immediately while working in the GUI builder. It synchronized the builder\u0026rsquo;s saved UI state to connected devices so that you could feel the screen on hardware instead of relying only on the desktop preview.\u003c/p\u003e","title":"USE CLOUD CONNECT"},{"content":" Crash protection is about getting useful failure information out of production devices instead of trying to reproduce every rare crash locally. In a framework that targets a wide range of devices and operating systems, that is not optional for serious apps. Some failures only show up in the field.\nThe underlying tool is the Codename One Log API. Use Log.p() for ordinary diagnostic messages and Log.e() for exceptions. That matters because ordinary Java console habits such as System.out.println() and printStackTrace() are not the right production tools across all Codename One targets. If you want logs that are portable and useful, go through the framework logging APIs.\nCrash protection builds on top of that logging infrastructure. The usual pattern is to bind crash protection early in application startup so uncaught runtime exceptions are captured automatically. That gives you a fallback path even when the user cannot explain what happened or when the device is nowhere near your development environment.\nManual log sending is useful too. Not every failure is an uncaught crash. Sometimes the app reaches a bad state, detects a server-side inconsistency, or encounters a condition you know should be reported even though the application continues running. In those cases, sending the log explicitly can be more valuable than waiting for an unhandled exception.\nOne detail the video explains well is the tradeoff around swallowing user-visible error dialogs. During development, an obvious error popup can be useful. In production, that same behavior can create a poor user experience. Whether you suppress the default dialog or not should be an intentional product decision, not an accident.\nEDT error handling is part of this story as well. A lot of visible Codename One failures show up on the event dispatch thread. If you need custom behavior, you can listen for EDT errors yourself, log them, and decide how much of the default user-facing handling should still happen. The built-in crash protection binding is still the best default for most applications because it covers the common cases with less custom code.\nThe key point is that crash reporting works best when it is part of a broader logging discipline. If the log already contains meaningful context leading up to the failure, the crash report becomes much more useful. If the only thing in the log is the final exception, you will still know that the app failed, but you may not know why.\nFurther Reading Developer Guide How Do I Find Problems In My Application, Using The Codename One Tools And The Standard IDE Tools How Do I Debug On An Android Device Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-use-crash-protection-get-device-logs/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/C3PLjAWQ-XA?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eCrash protection is about getting useful failure information out of production devices instead of trying to reproduce every rare crash locally. In a framework that targets a wide range of devices and operating systems, that is not optional for serious apps. Some failures only show up in the field.\u003c/p\u003e","title":"USE CRASH PROTECTION? GET DEVICE LOGS?"},{"content":" Networking on mobile is not the same as networking on the desktop or server. Connections disappear, latency changes abruptly, background execution is limited, and platform security rules can reject traffic that would look perfectly normal elsewhere. If you start with that assumption, the rest of the networking choices in Codename One make much more sense.\nThe default tool for most network work in Codename One is ConnectionRequest together with NetworkManager. That combination exists because mobile code benefits from a higher-level, portability-aware request pipeline. It handles threading better, integrates cleanly with the UI lifecycle, and is the right place to start for normal HTTP and REST communication.\nHTTPS should also be the default expectation. The video is correct that plain HTTP is increasingly restricted, especially in the Apple ecosystem. Treat unsecured HTTP as the exception that must be justified, not as the baseline.\nWhen you send a request with ConnectionRequest, the next question is how you want to process the response. Reading the response directly on the network thread is often the most efficient option when you want full control and do not need to touch the UI immediately. Response listeners are simpler when UI updates are the next step, because they run in a friendlier context for UI work. Blocking requests can still be useful in limited cases, but they should be used carefully because the convenience comes with responsiveness tradeoffs.\nThe older URL-style APIs exist mostly for portability of existing Java code, but they are not the best default for new Codename One networking. Once you drop to lower-level APIs, you inherit more threading and platform-behavior differences yourself. For new code, ConnectionRequest or the higher-level REST utilities are usually the better choice.\nSockets are a different category entirely. They are lower level, harder to support across mobile environments, and more sensitive to NAT, connectivity shifts, and platform behavior. They can be the right answer for specialized protocols, but they are not the place most mobile applications should begin.\nWebSockets sit in the middle. They are a good fit when the server needs to push events to the client continuously, as in chat, live dashboards, or presence-style features. They are usually much more appropriate than crude polling loops when you need ongoing server-to-client communication. Even then, they should be chosen because the problem really needs that shape of communication, not because they sound more modern than HTTP.\nThe modern decision tree is fairly simple. If you are calling a normal backend API, use HTTP with ConnectionRequest or the higher-level REST helpers. If you need real-time bidirectional messaging, consider WebSockets. If you need a special low-level protocol and understand the operational costs, use sockets deliberately. Do not pick the lowest-level tool first and then try to rebuild mobile-friendly behavior on top of it.\nFurther Reading Developer Guide Terse REST API How Do I Access Remote Webservices? Perform Operations On The Server? Performance Network Monitors Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-use-http-sockets-webservices-websockets/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/-M957AAi-vk?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eNetworking on mobile is not the same as networking on the desktop or server. Connections disappear, latency changes abruptly, background execution is limited, and platform security rules can reject traffic that would look perfectly normal elsewhere. If you start with that assumption, the rest of the networking choices in Codename One make much more sense.\u003c/p\u003e","title":"USE HTTP, SOCKETS, WEBSERVICES AND WEBSOCKETS"},{"content":" Offline build exists for the cases where the Codename One cloud build servers are not an option. That usually means regulated environments, restricted networks, or institutions that cannot send source or build assets to external services. If you are not in that situation, the normal build server is still the simpler and more heavily traveled path.\nThe important mental model is that offline build is not a full replacement for your local native toolchain. It reproduces the translation and project-generation parts of the Codename One build process on your own machine, then hands you native projects that you continue with in Xcode or Android Studio. In other words, offline build gets you from a Codename One project to platform-native project output without using the cloud.\nThat means the toolchain requirements matter a lot. You need the native tools installed and working, and you need versions that are compatible with the builder snapshot you are using. The exact list changes over time, so the current Developer Guide should be treated as the source of truth instead of the version numbers mentioned in the old video.\nThe video is also a product of an older setup era, so the specific versions it names for Gradle, Xcode, and related tools should be treated as historical. The durable lessons are different. First, offline build is operationally heavier than cloud build. Second, it depends on more moving parts on your own machine. Third, once you do generate the native projects, you debug and compile them with the platform-native tools exactly as you would expect.\nA useful way to think about offline builders is as locally installed snapshots of Codename One build logic. You choose which builder version to use, and that choice affects the generated native output. That makes offline build closely related to repeatable build concerns: if one builder version works and a newer one regresses, you can stay on the working snapshot while you investigate.\nFor Android, the flow is generally: generate the offline Android build, open the resulting native project in Android Studio, make sure the local Gradle/toolchain configuration is correct, and then run or debug it there. For iOS, the flow is similar but more sensitive to the Apple toolchain. You generate the iOS offline build, open the resulting xcworkspace in Xcode rather than the bare project file, and continue from there.\nThe generated directories should be treated as build artifacts, not hand-maintained source trees. If you need to preserve a particular generated native project for investigation, copy it somewhere safe before generating another one. The video calls this out, and it is still an important practical point because regeneration can replace previous output.\nThe main reason to choose offline build is policy, not convenience. It is usually more complex than the cloud build system, more dependent on local toolchain setup, and more prone to environment-specific problems. But if you are in an environment where cloud builds are not possible, it gives you a workable path to native project generation while keeping the rest of the Codename One development model intact.\nFurther Reading Build Server Developer Guide How Do I Use The Include Sources Feature To Debug The Native Code On iOS/Android Etc. How Do I Get Repeatable Builds? Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-use-offline-build/","summary":"\u003cp\u003e\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/IqsUSCgSVTo?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\nOffline build exists for the cases where the Codename One cloud build servers are not an option. That usually means regulated environments, restricted networks, or institutions that cannot send source or build assets to external services. If you are not in that situation, the normal build server is still the simpler and more heavily traveled path.\u003c/p\u003e","title":"USE OFFLINE BUILD"},{"content":" Codename One properties are useful when you want one model class to do more than simply hold data. A plain old Java object can represent state just fine, but it does not automatically know how to bind to UI, serialize itself, parse structured input, or describe its own fields at runtime. The properties API exists to make those jobs easier.\nThe core idea is that a property-backed object carries metadata about its fields through the property index. That means the framework can introspect the object safely even after obfuscation. Once that metadata exists, a lot of repetitive plumbing becomes easier: JSON and XML mapping, serialization, SQL helpers, UI binding, and generated forms.\nThis is what makes properties more than just a different syntax for getters and setters. You still keep a clear data model, but you also gain a structured description of that model that the framework can reuse. That is why the video moves quickly from basic property access into parsing, storage, CRUD helpers, and binding. Those features all depend on the same underlying introspection capability.\nTwo uses are especially practical. The first is data mapping. If your app receives structured data from a service and you want a cleaner route from raw JSON or XML into an object model, properties can reduce a lot of manual parsing code. The second is UI binding. If a field in the model changes and a component should reflect that change, or vice versa, the properties API gives you a much cleaner starting point than manually wiring every update yourself.\nThe video also highlights Instant UI, which can generate forms from property objects. That is still conceptually useful, but it should be applied with judgment. Generated UI can be a strong accelerator for internal tools, simple data-entry screens, or prototypes. It is not automatically the best fit for polished product UI where custom layout and styling matter more. In modern projects, CSS and hand-authored layout code still remain the better choice for most high-touch product screens.\nSo the best way to think about properties is as a productivity tool for model-driven parts of an application. If the same object needs to be bound to UI, serialized, parsed, and perhaps stored, properties can eliminate a lot of repetitive glue code. If the object is simple and none of those benefits matter, a normal POJO may still be the simpler choice.\nFurther Reading Developer Guide Properties Are Amazing How Do I Use Storage, File System And SQL Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-use-properties-to-speed-development/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/77N2t2n8rbQ?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eCodename One properties are useful when you want one model class to do more than simply hold data. A plain old Java object can represent state just fine, but it does not automatically know how to bind to UI, serialize itself, parse structured input, or describe its own fields at runtime. The properties API exists to make those jobs easier.\u003c/p\u003e","title":"USE PROPERTIES TO SPEED DEVELOPMENT"},{"content":" Push notification is best understood as a user-notification channel, not as a general-purpose networking layer. It is good for telling a device that something happened and, depending on platform and app state, optionally carrying some payload with that message. It is not something you should design your core application protocol around.\nThat distinction matters because push is inherently unreliable as a transport. Users can disable it. Some devices or services may not support it the same way. Different platforms treat background delivery differently. The video makes this point clearly in older terms, and it is still true now: build your app so that push signals something important, but do not assume it is always available or always delivered in the same way everywhere.\nCodename One smooths over a lot of the platform differences by providing a unified push API and server-side push entry point. You still need platform credentials for the vendor services, but you do not have to design a completely separate push implementation for every target OS. The high-level workflow is: configure the provider credentials, register the app for push, collect the push token on the device, send that token to your server, and then use your server to send push messages through the Codename One push infrastructure.\nOn the client side, one of the most important details is that push callbacks belong in the main application class. The PushCallback implementation must live in the class that represents the app lifecycle. That is where Codename One wires push delivery into the application. The key callbacks are the message callback itself, the registration callback, and the registration error callback.\nThe registration callback is especially important because that is where you usually obtain the push key and send it to your own backend. A common mistake is to treat the device identifier argument as if it were the push token. It is not. The push key is what your server needs in order to target that device later.\nServer-side push is just as important as the client setup. Sending the request is not enough; you also need to parse the response and log the outcome. The old video calls this out, and it is still correct. A lot of push debugging time is wasted by code that fires off a request and never looks closely at the response body. If delivery fails because of a credential mismatch, certificate problem, provider rejection, or malformed request, that response is often your only useful clue.\nPush types also need to be chosen deliberately. Visible notification types are usually the safest default because they match what users and platforms expect. Hidden push and payload-heavy push are more nuanced and behave differently across operating systems, especially on iOS. The video is out of date in its references to older Google push naming and setup steps, but the design lesson is still current: treat push as signaling, not as the backbone of app synchronization.\nApple and Google credentials are the other major source of friction. iOS push configuration is tightly tied to certificates, provisioning, and environment separation. Android push configuration depends on the current Google push provider setup and project credentials. The names and consoles have changed over time, so the exact setup screens in the video should be treated as historical. The durable guidance is to keep your package identifiers, signing, and provider credentials aligned and to verify the full chain from registration to delivery.\nTesting needs a layered approach. First make sure registration succeeds and the device receives a push token. Then verify that your server stores the token correctly. Then send a push and inspect the full server response. Finally test how the app behaves in foreground, background, and terminated states. If you only test one state, you can miss the most important platform-specific behavior differences.\nFurther Reading Developer Guide Build Hints Build Server How Do I Use Crash Protection? Get Device Logs? Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-use-push-notification-send-server-push-messages/","summary":"\u003cp\u003e\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/8wzBpEp81Kc?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\nPush notification is best understood as a user-notification channel, not as a general-purpose networking layer. It is good for telling a device that something happened and, depending on platform and app state, optionally carrying some payload with that message. It is not something you should design your core application protocol around.\u003c/p\u003e","title":"USE PUSH NOTIFICATION SEND SERVER PUSH MESSAGES?"},{"content":" Persistent data in Codename One usually starts with a choice between three levels of storage: Preferences for very small settings, Storage for simple app-private persisted objects or blobs, and SQL for data that needs real querying, sorting, or filtering. The file system sits beside those as a lower-level tool rather than the default answer to every persistence question.\nStorage is the place to start for many apps because it is portable and application-oriented. It is not a general shared file hierarchy. It is a higher-level persistence API tied to the app itself. That makes it a much better default than reaching immediately for raw files just because you are used to desktop development.\nThe file system becomes useful when you actually need file paths, larger assets, or interoperability with APIs that naturally work in terms of files. But mobile app isolation still matters. Devices do not expose the same shared-file assumptions developers are used to on the desktop. Even when some platforms allow more shared file access than others, that behavior is not the best foundation for portable application design.\nSQL is the right tool when your data is large enough or dynamic enough that you need real query capability. If you need filtering, sorting, lookups, or structured updates over a meaningful amount of data, SQLite is usually a better fit than trying to serialize everything into a single stored object. If you just need to save app state or a few structured objects, SQL is often unnecessary complexity.\nThe video also makes an important operational point about cleanup. Database cursors and related resources should be closed explicitly. You should not rely on the garbage collector to clean up database resources whenever it happens to run. That becomes especially important when portability differences between platforms affect database behavior and thread safety.\nShipping an initial database is another valid pattern. If the app needs seed data, you can package a database resource and copy it into the correct writable location on first run. That is often easier than trying to generate the full initial data set programmatically every time.\nThe modern recommendation is mostly about choosing the simplest layer that fits the problem. Use Preferences for settings, Storage for straightforward app-private persistence, SQL when you genuinely need query power, and filesystem APIs when the problem is really file-oriented. Starting at the highest appropriate level tends to produce the most portable and maintainable code.\nFurther Reading Developer Guide How Do I Use Properties To Speed Development How Do I Improve Application Performance Or Track Down Performance Issues Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-use-storage-file-system-sql/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/_EXEN52wQvs?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003ePersistent data in Codename One usually starts with a choice between three levels of storage: \u003ccode\u003ePreferences\u003c/code\u003e for very small settings, \u003ccode\u003eStorage\u003c/code\u003e for simple app-private persisted objects or blobs, and SQL for data that needs real querying, sorting, or filtering. The file system sits beside those as a lower-level tool rather than the default answer to every persistence question.\u003c/p\u003e","title":"USE STORAGE, FILE SYSTEM AND SQL"},{"content":" The desktop and JavaScript ports answer different questions, even though both let you run a Codename One application outside a phone. The desktop port is about packaging the application as a desktop-style app. The JavaScript port is about running the application in the browser as a Codename One app experience rendered on the web platform.\nThe desktop port is usually the easier one to reason about conceptually. You are still running a Codename One application, but the result is packaged for desktop operating systems. The app still feels like a Codename One UI, often closer to a tablet-style experience than to a native desktop app built around each platform\u0026rsquo;s widget toolkit. That is fine for some use cases and awkward for others, so it should be chosen intentionally.\nThe JavaScript port is different. It does not turn your app into a normal hand-authored website. It translates the app into a browser-executed Codename One application using the web platform as the runtime. That means the result behaves more like an app rendered in the browser than like a typical server-rendered or frontend-framework website.\nThat distinction matters because browser rules apply. Same-origin restrictions, browser capabilities, and web-platform limitations still shape what the JavaScript port can do. The video explains this through the older proxy-servlet workaround, and the underlying point remains valid: browser deployment has a different networking and integration model than native or desktop targets.\nDesktop and JavaScript also differ sharply in distribution. Desktop builds are distributed like installers or packaged desktop applications. JavaScript builds are deployed through a web server. Those are not interchangeable decisions; they affect installation, updates, integration, and how users experience the app.\nNative extension story is another major difference. Desktop can lean on JavaSE APIs directly. JavaScript can reach into browser-side JavaScript functionality, but it remains constrained by the browser sandbox. If a project depends heavily on platform capabilities outside the browser model, that often influences the choice immediately.\nThe best way to choose between these ports is not to ask which one is more powerful in the abstract. Ask what environment you actually want the app to live in, what distribution model you need, and what platform limitations your feature set can tolerate.\nFurther Reading Developer Guide Introduction For Android Developers Hello World Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-use-desktop-javascript-ports/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/hCjmHoktlrU?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eThe desktop and JavaScript ports answer different questions, even though both let you run a Codename One application outside a phone. The desktop port is about packaging the application as a desktop-style app. The JavaScript port is about running the application in the browser as a Codename One app experience rendered on the web platform.\u003c/p\u003e","title":"USE THE DESKTOP AND JAVASCRIPT PORTS"},{"content":" The include-sources feature is for the moments when you need to see the native project Codename One generated for a build. That makes it useful for native debugging, profiling, investigating platform-specific behavior, and understanding how a portable Codename One class is represented on the native side.\nIt is not the primary way to write platform-specific code. If you need durable custom native functionality, native interfaces are the right abstraction. Include-sources is the tool you reach for when you need visibility into the generated native output or when you need to debug what the platform-specific side is actually doing.\nWhen the feature is enabled, the build produces an additional source archive alongside the native build result. That archive contains the generated native project for the target platform. Because the build has to package more output, it takes longer, which is one reason this is not the default path for ordinary builds.\nFor iOS, the important practical detail is that you open the generated xcworkspace, not just the bare project file. The workspace includes the full project structure Xcode expects to run and debug correctly. Once it is open, you can run on the simulator or on a real device and use the normal native debugging tools there. Device testing is still essential for features that Apple does not support in the simulator, such as push.\nFor Android, the generated project opens in Android Studio. The exact Gradle and Android tooling details in the old video are outdated, but the workflow is still valid: open the generated project, point it at your local Android toolchain if needed, then run or debug on a device or emulator. In practice, a real device is often the faster and more useful target for this kind of debugging.\nThe strongest use of include-sources is when you want to set breakpoints inside generated native code and walk the full stack. That lets you see how a high-level Codename One operation ends up behaving on the native side. If you are diagnosing a rendering problem, a lifecycle issue, a native crash, or a problem in a native interface bridge, this can be far more revealing than debugging only from the portable Java side.\nThe video shows this with breakpoints inside Dialog handling, and that lesson generalizes well. Once you can stop inside the generated native implementation, inspect variables, and walk back up the stack, you have a much clearer picture of whether the problem is in your app code, in the Codename One framework layer, or in the native platform behavior underneath it.\nOne subtle but important point is that the source coverage differs by platform. On Android, much of your application logic may still be represented as packaged binaries in the generated project. On iOS, more of the translated output is available as native source because of how the pipeline works. That affects what you can step into and how directly you can inspect it.\nThe modern takeaway is simple: use include-sources when the normal simulator or application-level debugger stops being enough. It is a debugging and inspection feature, not a day-to-day coding model. Once you understand the native-side issue, the lasting fix should still go back into the real Codename One project, build configuration, or native interface code.\nFurther Reading Developer Guide Build Server How Do I Debug On An Android Device How Do I Access Native Device Functionality? Invoke Native Interfaces? Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-use-the-include-sources-feature-to-debug-the-native-code-on-iosandroid-etc/","summary":"\u003cp\u003e\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/6oTy-LcTm0s?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\nThe include-sources feature is for the moments when you need to see the native project Codename One generated for a build. That makes it useful for native debugging, profiling, investigating platform-specific behavior, and understanding how a portable Codename One class is represented on the native side.\u003c/p\u003e","title":"USE THE INCLUDE SOURCES FEATURE TO DEBUG THE NATIVE CODE ON IOS/ANDROID ETC."},{"content":" Image handling on mobile starts with density, not just resolution. Two devices can have very different physical sizes and very different pixel densities, which means the same raster image can feel too small, too large, or too soft depending on where it is shown. That is why Codename One introduced multi-images and why density still matters even in a modern CSS-first project.\nThe important distinction is between raster and vector assets. Raster formats such as PNG and JPEG are fixed collections of pixels. If you scale them too aggressively, quality drops. Vector assets can be redrawn cleanly at different sizes. That is why FontImage and icon-font based workflows are so valuable: when an icon can be expressed as a vector, you avoid many of the density problems that ordinary raster assets create.\nMulti-images exist for the cases where you really do need raster artwork. Instead of shipping one image and scaling it poorly on-device, you prepare density-appropriate variants so the runtime can choose the asset that best matches the device. The older designer workflow made this explicit through multi-image tooling. The idea is still valid today, even though many modern projects will rely more heavily on vector icons and CSS styling than older designer-heavy apps did.\nThis also means that not every screen should just \u0026ldquo;scale up\u0026rdquo; for tablets. The video makes an important point here: higher-resolution devices should often show more content, not just bigger versions of the same phone UI. A tablet layout that merely enlarges every icon and spacing value can feel wasteful. Density-aware images are part of adaptation, but layout choices are just as important.\nIn practical terms, use vectors where you can, multi-images where you must, and on-device scaling carefully. If you do need to generate or manipulate scaled rasters, remember that the memory cost at runtime can be much higher than the compressed file size suggests. This is one of the reasons image-heavy screens often need explicit memory discipline.\nThe older page talks about fetching images from the resource file through the resource APIs. That is still correct for apps that keep assets in resource bundles. In a more modern setup, the broader principle matters more than the exact tool: keep image handling density-aware, prefer vectors for icons, and avoid assuming one raster size will feel correct everywhere.\nFurther Reading Themeing Developer Guide How Do I Create A 9 Piece Image Border How Do I Improve Application Performance Or Track Down Performance Issues Discussion Join the conversation via GitHub Discussions.\n","permalink":"https://www.codenameone.com/how-do-i/how-do-i-fetch-an-image-from-the-resource-file-add-a-multiimage/","summary":"\u003cdiv style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\"\u003e\n      \u003ciframe allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen\" loading=\"eager\" referrerpolicy=\"strict-origin-when-cross-origin\" src=\"https://www.youtube.com/embed/sK-u1TBWFX8?autoplay=0\u0026amp;controls=1\u0026amp;end=0\u0026amp;loop=0\u0026amp;mute=0\u0026amp;start=0\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;\" title=\"YouTube video\"\u003e\u003c/iframe\u003e\n    \u003c/div\u003e\n\n\u003cp\u003eImage handling on mobile starts with density, not just resolution. Two devices can have very different physical sizes and very different pixel densities, which means the same raster image can feel too small, too large, or too soft depending on where it is shown. That is why Codename One introduced multi-images and why density still matters even in a modern CSS-first project.\u003c/p\u003e","title":"WORK WITH MULTI IMAGES AND DEVICE DENSITIES"}]